应用安装和卸载的几种方式

本文基于Android6.0

1. 使用ADB指令

1.1. 安装

    /**
     * 安装
     *
     * @param apkFile apk文件
     */
    public static void installByAdb(File apkFile) {
        try {
            // adb shell pm install -r /sdcard/test.apk
            Runtime.getRuntime().exec("pm install " + apkFile.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

1.2. 卸载

    /**
     * 卸载
     *
     * @param pkgName 需要卸载的应用包名
     */
    public static void uninstallByAdb(String pkgName) {
        try {
            //  adb shell pm uninstall com.example.test
            Runtime.getRuntime().exec("pm uninstall " + pkgName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

1.3. 注意事项

  1. 需要申请安装权限
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
  1. 需要系统签名

2. 使用Intent

2.1. 安装

    /**
     * 安装
     *
     * @param context
     * @param apkFile apk文件
     */
    public static void installByIntent(Context context, File apkFile) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
        context.startActivity(intent);
    }

2.2. 卸载

    /**
     * 卸载
     *
     * @param context
     * @param pkgName 需要卸载的包名
     */
    public static void uninstallByIntent(Context context, String pkgName) {
        Intent intent = new Intent(Intent.ACTION_DELETE);
        intent.setData(Uri.parse("package:" + pkgName));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

2.3. 注意事项

  1. 需要安装权限
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />

3. 使用PackageManager

3.1. 安装

    /**
     * 安装
     *
     * @param context
     * @param apkFile apk文件
     * @param pkgName 需要安装的apk包名
     */
    public static void installByPackageManager(Context context, File apkFile, String pkgName) {
        try {
            // android.app.ApplicationPackageManager
            // public void installPackage (Uri packageURI, IPackageInstallObserver observer,int flags, String installerPackageName)
            // android.content.pm.IPackageInstallObserver
            // 获取方法安装方法
            Method installPackageMethod = Class.forName("android.app.ApplicationPackageManager")
                    .getMethod("installPackage",
                            Uri.class,
                            Class.forName("android.content.pm.IPackageInstallObserver"),
                            int.class,
                            String.class);

            Uri uri = Uri.fromFile(apkFile);
            // 动态代理创建监听
            Object proxy = Proxy.newProxyInstance(context.getClassLoader(),
                    new Class[]{Class.forName("android.content.pm.IPackageInstallObserver")},
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            // public static final int INSTALL_SUCCEEDED = 1;
                            // public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
                            return null;
                        }
                    });
            // public static final int INSTALL_REPLACE_EXISTING = 0x00000002;
            installPackageMethod.invoke(context.getPackageManager(), uri, proxy, 2, pkgName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3.2. 卸载

    /**
     * 卸载
     *
     * @param context
     * @param pkgName 需要卸载的应用包名
     */
    public static void uninstallByPackageManager(Context context, String pkgName) {
        try {
            // android.app.ApplicationPackageManager
            // public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags)
            // public static final int DELETE_ALL_USERS = 0x00000002;
            // android.content.pm.IPackageDeleteObserver

            Class[] args = new Class[3];
            args[0] = String.class;
            args[1] = Class.forName("android.content.pm.IPackageDeleteObserver");
            args[2] = int.class;
            Method deletePackageMethod = Class.forName("android.app.ApplicationPackageManager").getMethod("deletePackage", args);
            Object proxy = Proxy.newProxyInstance(context.getClassLoader(),
                    new Class[]{Class.forName("android.content.pm.IPackageDeleteObserver")},
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            return null;
                        }
                    });

            Object[] params = new Object[3];
            // String packageName
            params[0] = pkgName;
            // IPackageDeleteObserver observer
            params[1] = proxy;
            // int flags
            // public static final int DELETE_ALL_USERS = 0x00000002;
            params[2] = 2;

            deletePackageMethod.invoke(context.getPackageManager(), params);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3.3. 注意事项

  1. 需要申请安装权限
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
  1. 需要系统签名

4. 监听apk的安装和卸载

4.1. 注册广播

4.1.1. 动态广播方式

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addDataScheme("package");
        registerReceiver(mReceiver, filter);

注意:需要设置data信息filter.addDataScheme("package");,否则无法接收广播信息

4.1.2. 静态广播注册

清单文件注册

        <receiver android:name=".PkgReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />

                <data android:scheme="package" />
            </intent-filter>
        </receiver>

注意:需要添加data标签<data android:scheme="package" />,否则无法接收到广播信息

4.2. 接收广播消息

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "onReceive: " + intent.getAction());
            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
                // String pkgName = intent.getData().getSchemeSpecificPart();
                Log.d(TAG, "ACTION_PACKAGE_ADDED: " + intent.getData());
            } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
                String pkgName = intent.getData().getSchemeSpecificPart();
                boolean remove = intent.getBooleanExtra(Intent.EXTRA_DATA_REMOVED, false);
                Log.d(TAG, "ACTION_PACKAGE_REMOVED: pkgName = " + pkgName + ", remove = " + remove);
            }
        }
    };
上一篇:鸿蒙跳转到图库或者文件选择图片并显示到Image控件中


下一篇:androidstudio简单页面设计