1. 程式人生 > >Android 安裝應用的兩種方式--外部應用安裝器安裝和靜默安裝(系統應用)

Android 安裝應用的兩種方式--外部應用安裝器安裝和靜默安裝(系統應用)

1.呼叫外部安裝器安裝

/**
     * 外部應用安裝器安裝apk(原生介面)
     * @param context
     * @param path apk的路徑
     * @return
     */
    public static boolean installApkByPath(Context context, String path) {
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

2.靜默安裝(系統應用才有許可權)

這裡使用反射的方式呼叫  

public class PackageManager_R {
    private static final String TAG = "PackageManager_R";
    private static final String ERROR_TAG = "ReflectError " + TAG;

    private static Method sMethod_installPackage;

    /**
     * 靜默安裝(原生介面)
     *
     * @param path
     * @return
     */
    public static boolean installPackage(String path, final SystemAppInstall.InstalledCallBack callBack) {
        if (sMethod_installPackage == null) {
            try {
                sMethod_installPackage = PackageManager.class.getMethod("installPackage", Uri.class, IPackageInstallObserver.class, int.class, String.class);
            } catch (Exception e) {
                LogUtils.w(ERROR_TAG, "", e);
                e.printStackTrace();
            }
        }

        IPackageInstallObserver observer = new IPackageInstallObserver.Stub() {
            public void packageInstalled(String packageName, int returnCode) {
                if (returnCode != 1) {
                    callBack.onResult(packageName, false);
                } else {
                    callBack.onResult(packageName, true);
                }
            }
        };

        PackageManager pm = AppContextUtils.getAppContext().getPackageManager();
        try {
            sMethod_installPackage.invoke(pm, Uri.parse("file://" + path), observer, 0, null);
            return true;
        } catch (Exception e) {
            LogUtils.w(ERROR_TAG, "", e);
            e.printStackTrace();
        }
        return false;
    }
}
對應的原始碼的介面
/**
     * @hide Install a package. Since this may take a little while, the result
     *       will be posted back to the given observer. An installation will
     *       fail if the calling context lacks the
     *       {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if
     *       the package named in the package file's manifest is already
     *       installed, or if there's no space available on the device.
     * @param packageURI The location of the package file to install. This can
     *            be a 'file:' or a 'content:' URI.
     * @param observer An observer callback to get notified when the package
     *            installation is complete.
     *            {@link IPackageInstallObserver#packageInstalled(String, int)}
     *            will be called when that happens. This parameter must not be
     *            null.
     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
     *            {@link #INSTALL_REPLACE_EXISTING},
     *            {@link #INSTALL_ALLOW_TEST}.
     * @param installerPackageName Optional package name of the application that
     *            is performing the installation. This identifies which market
     *            the package came from.
     * @deprecated Use {@link #installPackage(Uri, PackageInstallObserver, int,
     *             String)} instead. This method will continue to be supported
     *             but the older observer interface will not get additional
     *             failure details.
     */
    // @SystemApi
    public abstract void installPackage(
            Uri packageURI, IPackageInstallObserver observer, int flags,
            String installerPackageName);

3.監聽應用的安裝與解除安裝

//註冊監聽

IntentFilter installFilter = new IntentFilter();
        installFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        installFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
        installFilter.addDataScheme("package");
        mContext.registerReceiver(mAppReceiver, installFilter);
//移除監聽
mContext.unregisterReceiver(mAppReceiver);

//廣播接收回調

private BroadcastReceiver mAppReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            LogUtils.d(TAG, "onReceive = " + action);
            String pkgName = intent.getData().getSchemeSpecificPart();
            if(action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
                //解除安裝
            }else if(action.equals(Intent.ACTION_PACKAGE_ADDED)) {
                //安裝
            }
        }
    };