Android PackageInstaller:安装应用的应用

PackageInstaller作为安装应用的应用,在Android中的地位有些特殊。

看看在AndroidManifest.xml中的声明:

        <activity android:name=".PackageInstallerActivity"
                android:configChanges="orientation|keyboardHidden|screenSize"
                android:excludeFromRecents="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.INSTALL_PACKAGE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="content" />
                <data android:scheme="file" />
                <data android:mimeType="application/vnd.android.package-archive" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.INSTALL_PACKAGE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="file" />
                <data android:scheme="package" />
            </intent-filter>
        </activity>

可以看到对application/vnd.android.package-archive这个mime的处理,还有android.intent.action.INSTALL_PACKAGE这个action的处理。

在文件管理器中点击apk文件,或者发送以上intent-filter中对应的action,就会调用PackageInstaller。


1.只安装指定前缀包名的应用

我们可以在initiateInstall()这个函数中,通过包名对将要安装的应用进行管控,参考代码如下:

    private void initiateInstall() {
        String pkgName = mPkgInfo.packageName;
		Log.v("AZ","[initiateInstall]pkgName:" + pkgName);
		if(pkgName.startsWith("com.zms")){
			// Check if there is already a package on the device with this name
			// but it has been renamed to something else.
			String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
			if (oldName != null && oldName.length > 0 && oldName[0] != null) {
				pkgName = oldName[0];
				mPkgInfo.packageName = pkgName;
				mPkgInfo.applicationInfo.packageName = pkgName;
			}
			// Check if package is already installed. display confirmation dialog if replacing pkg
			try {
				// This is a little convoluted because we want to get all uninstalled
				// apps, but this may include apps with just data, and if it is just
				// data we still want to count it as "installed".
				mAppInfo = mPm.getApplicationInfo(pkgName,
						PackageManager.GET_UNINSTALLED_PACKAGES);
				if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
					mAppInfo = null;
				}
			} catch (NameNotFoundException e) {
				mAppInfo = null;
			}

			mInstallFlowAnalytics.setReplace(mAppInfo != null);
			mInstallFlowAnalytics.setSystemApp(
					(mAppInfo != null) && ((mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0));

			startInstallConfirm();
		}else{
			finish();
		}
    }

以上代码的效果就是,只安装包名以“com.zms”开头的应用。其他的不会出现安装界面,直接finish()。



2.PackageInstaller安装完某个应用,自动打开:

packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallAppProgress.java

    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case INSTALL_COMPLETE:
                    mInstallFlowAnalytics.setFlowFinishedWithPackageManagerResult(msg.arg1);
                    if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
                        Intent result = new Intent();
                        result.putExtra(Intent.EXTRA_INSTALL_RESULT, msg.arg1);
                        setResult(msg.arg1 == PackageManager.INSTALL_SUCCEEDED
                                ? Activity.RESULT_OK : Activity.RESULT_FIRST_USER,
                                        result);
                        finish();
                        return;
                    }
                    // Update the status text
                    mProgressBar.setVisibility(View.INVISIBLE);
                    // Show the ok button
                    int centerTextLabel;
                    int centerExplanationLabel = -1;
                    LevelListDrawable centerTextDrawable = (LevelListDrawable) getResources()
                            .getDrawable(R.drawable.ic_result_status);
                    if (msg.arg1 == PackageManager.INSTALL_SUCCEEDED) {
                        mLaunchButton.setVisibility(View.VISIBLE);
                        centerTextDrawable.setLevel(0);
                        centerTextLabel = R.string.install_done;
                        // Enable or disable launch button
                        mLaunchIntent = getPackageManager().getLaunchIntentForPackage(
                                mAppInfo.packageName);
                        boolean enabled = false;
                        if(mLaunchIntent != null) {
                            List<ResolveInfo> list = getPackageManager().
                                    queryIntentActivities(mLaunchIntent, 0);
                            if (list != null && list.size() > 0) {
                                enabled = true;
                                                   }
                        if (enabled) {
                            // ZMS:Add for opening app automatically START
                            if(mAppInfo.packageName.equals("com.zms.demo")){
                               startActivity(mLaunchIntent);
                            }
                            // ZMS:END
                            mLaunchButton.setOnClickListener(InstallAppProgress.this);
                        } else {
                            mLaunchButton.setEnabled(false);
                        }
                    } else if (msg.arg1 == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
                        /// M: [ALPS00269830][ICS-TDD][Symbio][Free test] Assertion while playing music when downloading apks @{
                        if (!isFinishing()) {
                            Log.d(TAG, "!isFinishing()");   // Check to see whether this activity is in the process of finishing
                        showDialogInner(DLG_OUT_OF_SPACE);
                        }
                        /// @}
                        return;
                    } else {
                        // Generic error handling for all other error codes.
                        centerTextDrawable.setLevel(1);
                        centerExplanationLabel = getExplanationFromErrorCode(msg.arg1);
                        centerTextLabel = R.string.install_failed;
                        mLaunchButton.setVisibility(View.INVISIBLE);
                    }
                    if (centerTextDrawable != null) {
                    centerTextDrawable.setBounds(0, 0,
                            centerTextDrawable.getIntrinsicWidth(),
                            centerTextDrawable.getIntrinsicHeight());
                        mStatusTextView.setCompoundDrawablesRelative(centerTextDrawable, null,
                                null, null);
                    }
                    mStatusTextView.setText(centerTextLabel);
                    if (centerExplanationLabel != -1) {
                        mExplanationTextView.setText(centerExplanationLabel);
                        mExplanationTextView.setVisibility(View.VISIBLE);
                    } else {
                        mExplanationTextView.setVisibility(View.GONE);
                    }
                    mDoneButton.setOnClickListener(InstallAppProgress.this);
                    mOkPanel.setVisibility(View.VISIBLE);
                    break;
                default:
                    break;
            }
        }
    };


    原文作者:周木水
    原文地址: https://blog.csdn.net/zhoumushui/article/details/51088165
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞