Android 8.1实现静默安装、卸载功能

网上有很多相关的资料,也有很多不同的方法去实现,本文是我选取的一个方法,已实现静默安装和卸载功能,本文主要目的记录一下关键点。
主要是用PackageManagerService.java里面的
installPackageAsUser
deletePackageAsUser
的方法去实现静默安装和卸载
通过method.invoke去调用这些方法,话不多说,上代码:

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.File;
import java.lang.reflect.Method;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    public static final int INSTALL_APK = 1;
    public static final int UNINSTALL_APK = 2;
    int versioncode;
    String path = "/sdcard/UC.apk";
    //String path = Environment.getDataDirectory().getParentFile() + "/UC.apk";
    Button myButton;
    Button myButton2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myButton = findViewById(R.id.button);
        myButton.setOnClickListener(new mybuttonListener());
        myButton2 = findViewById(R.id.button2);
        myButton2.setOnClickListener(new mybutton2Listener());
    }
    class mybuttonListener implements View

            .OnClickListener{
        @Override
        public void onClick(View v){
            Log.e("KaicomWangxp",path);
            if (new File(path).exists()) {
                ApkInSilence(path, getApkPackageName(path), INSTALL_APK);
                Log.e("KaicomWangxp","onClick");
            }
            else {
                //Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
                Log.e("KaicomWangxp","文件不存在");
            }

        }
    }
    class mybutton2Listener implements View


            .OnClickListener{
        @Override
        public void onClick(View v){
            if (new File(path).exists()) {
                ApkInSilence(path, getApkPackageName(path), UNINSTALL_APK);
            }
            else {
                //Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
                Log.e("KaicomWangxp","文件不存在");
            }

        }
    }

    public String getApkPackageName(String path) {
        String packageName = "";
        PackageManager pm = getPackageManager();
        PackageInfo info = pm.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
        if (info != null) {
            ApplicationInfo appInfo = info.applicationInfo;
            String appName = pm.getApplicationLabel(appInfo).toString();
            packageName = appInfo.packageName;  //获取安装包名称
           // versioncode=pm.get(packageName, 0);
            versioncode = info.versionCode;
        }
        return packageName;
    }


    private void ApkInSilence(String installPath, String packageName,int type) {
        Class<?> pmService;
        Class<?> activityTherad;
        Method method;
        Log.e("KaicomWangxp","ApkInSilence");
        try {
            activityTherad = Class.forName("android.app.ActivityThread");
            Class<?> paramTypes[] = getParamTypes(activityTherad, "getPackageManager");
            method = activityTherad.getMethod("getPackageManager", paramTypes);
            Object PackageManagerService = method.invoke(activityTherad);
            pmService = PackageManagerService.getClass();
            if(type == INSTALL_APK) {
                Log.e("KaicomWangxp","installPath="+ installPath +"packageName="+packageName);
                Class<?> paramTypes1[] = getParamTypes(pmService, "installPackageAsUser");
                method = pmService.getMethod("installPackageAsUser", paramTypes1);
                method.invoke(PackageManagerService, installPath, null, 0x00000040, packageName, getUserId(Binder.getCallingUid()));//getUserId
                Log.e("KaicomWangxp","pmService");

            }
            else {
                Class<?> paramTypes1[] = getParamTypes(pmService, "deletePackageAsUser");
                method = pmService.getMethod("deletePackageAsUser", paramTypes1);
                method.invoke(PackageManagerService, packageName ,versioncode, null, getUserId(Binder.getCallingUid()),0x00000040);//getUserId
            }
            Toast.makeText(this, "成功", Toast.LENGTH_SHORT).show();
            Log.e("KaicomWangxp","成功");
        } catch (Exception e) {
            Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
            Log.e("KaicomWangxp","失败");
        }
    }

    private Class<?>[] getParamTypes(Class<?> cls, String mName) {
        Class<?> cs[] = null;
        Method[] mtd = cls.getMethods();
        for (int i = 0; i < mtd.length; i++) {
            if (!mtd[i].getName().equals(mName)) {
                continue;
            }

            cs = mtd[i].getParameterTypes();
        }
        return cs;
    }
    public static final int PER_USER_RANGE = 100000;
    public static int getUserId(int uid) {
        return uid / PER_USER_RANGE;
    }
}

主要的功能和方法都在上面了,也比较简单易懂。
需要注意的是AndroidManifest.xml文件上面权限要加上

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication"
    android:sharedUserId="android.uid.system">
    <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

设置为系统app:android:sharedUserId=“android.uid.system”
添加系统签名,具体的步骤可以问度哥。

参考博客:https://blog.csdn.net/qq_26787115/article/details/52347146

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值