【Android】應用安裝和卸載的幾種方式


本文基於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);
            }
        }
    };


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM