网上有很多相关的资料,也有很多不同的方法去实现,本文是我选取的一个方法,已实现静默安装和卸载功能,本文主要目的记录一下关键点。
主要是用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文件上面权限要加上
设置为系统app:android:sharedUserId=“android.uid.system”
添加系统签名,具体的步骤可以问度哥。
参考博客:https://blog.csdn.net/qq_26787115/article/details/52347146