本文适用于 系统app 第三方apk 无法实现
***************************** 用于5.0 *************************************************************
一、准备工作
要实现静默安装、卸载,首先你要有root权限,能把你的静默安装、卸载程序移动到system/app目录下。
1、用RE浏览器将你的应用(一般在/data/app目录下)移动到/system/app目录下,如果你的程序有.so文件,那么请将相应的.so文件从/data/data/程序包名/lib目录下移动到/system/lib目录下
2、重启你的手机,你就会发现你的应用已经是系统级应用了,不能被卸载,也就是说你的应用现在已经八门全开,活力无限了。
二 .权限
三 :管理类
public class ApkManager {
15
16 private static final String TAG = "ApkManager";
17 private static final String INSTALL_CMD = "install";
18 private static final String UNINSTALL_CMD = "uninstall";
19
20 /**
21 * APK静默安装
22 *
23 * @param apkPath
24 * APK安装包路径
25 * @return true 静默安装成功 false 静默安装失败
26 */
27 public static boolean install(String apkPath) {
28 String[] args = { "pm", INSTALL_CMD, "-r", apkPath };
29 String result = apkProcess(args);
30 Log.e(TAG, "install log:"+result);
31 if (result != null
32 && (result.endsWith("Success") || result.endsWith("Success\n"))) {
33 return true;
34 }
35 return false;
36 }
37
38 /**
39 * APK静默安装
40 *
41 * @param packageName
42 * 需要卸载应用的包名
43 * @return true 静默卸载成功 false 静默卸载失败
44 */
45 public static boolean uninstall(String packageName) {
46 String[] args = { "pm", UNINSTALL_CMD, packageName };
47 String result = apkProcess(args);
48 Log.e(TAG, "uninstall log:"+result);
49 if (result != null
50 && (result.endsWith("Success") || result.endsWith("Success\n"))) {
51 return true;
52 }
53 return false;
54 }
55
56 /**
57 * 应用安装、卸载处理
58 *
59 * @param args
60 * 安装、卸载参数
61 * @return Apk安装、卸载结果
62 */
63 public static String apkProcess(String[] args) {
64 String result = null;
65 ProcessBuilder processBuilder = new ProcessBuilder(args);
66 Process process = null;
67 InputStream errIs = null;
68 InputStream inIs = null;
69 try {
70 ByteArrayOutputStream baos = new ByteArrayOutputStream();
71 int read = -1;
72 process = processBuilder.start();
73 errIs = process.getErrorStream();
74 while ((read = errIs.read()) != -1) {
75 baos.write(read);
76 }
77 baos.write('\n');
78 inIs = process.getInputStream();
79 while ((read = inIs.read()) != -1) {
80 baos.write(read);
81 }
82 byte[] data = baos.toByteArray();
83 result = new String(data);
84 } catch (Exception e) {
85 e.printStackTrace();
86 } finally {
87 try {
88 if (errIs != null) {
89 errIs.close();
90 }
91 if (inIs != null) {
92 inIs.close();
93 }
94 } catch (Exception e) {
95 e.printStackTrace();
96 }
97 if (process != null) {
98 process.destroy();
99 }
100 }
101 return result;
102 }
103 }
***************************** 用于5.0 end *************************************************************
***************************** 用于5.0 - 8.0 *************************************************************
import java.io.IOException;
import java.io.InputStream;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.PackageManager;
import java.io.File;
import android.os.Environment;
import android.net.Uri;
public class Installer {
private Context mContext;
private static Installer mInstaller=null;
private Installer() {}
public static Installer getInstance(){
if(mInstaller==null){
mInstaller = new Installer();
}
return mInstaller;
}
public void silentInstall(Context context, String fileName) {
try {
Log.d("lrs","fileName=" + fileName);
File file = new File(fileName);
int installFlags = 0;
if (!file.exists())
return;
installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
PackageManager pm = context.getPackageManager();
IPackageInstallObserver observer = new MyPakcageInstallObserver(context);
pm.installPackage(Uri.fromFile(file), observer, installFlags, null);
} catch (Exception e) {
e.printStackTrace();
}
}
class MyPakcageInstallObserver extends IPackageInstallObserver.Stub {
public MyPakcageInstallObserver(Context context) {
mContext = context;
}
@Override
public void packageInstalled(String packageName, int returnCode) {
if (returnCode == 1) { // Success
Log.e("lrs","install success...");
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_INSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_INSTALLE_RRESULT_INTERFACE_SET_STATE", 1);
mIntent.putExtra("com.rich.extra_INSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", packageName);
mContext.sendBroadcast(mIntent);
} else{ // Failure
Log.e("lrs","install fail code:"+returnCode);
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_INSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_INSTALLE_RRESULT_INTERFACE_SET_STATE", 0);
mIntent.putExtra("com.rich.extra_INSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", packageName);
mContext.sendBroadcast(mIntent);
}
}
}
public void silentUninstall(String packageName, Context context) {
PackageManager pm = context.getPackageManager();
IPackageDeleteObserver observer = new MyPackageDeleteObserver(context);
pm.deletePackage(packageName, observer, 0);
}
class MyPackageDeleteObserver extends IPackageDeleteObserver.Stub {
public MyPackageDeleteObserver(Context context) {
mContext = context;
}
@Override
public void packageDeleted(String packageName, int returnCode) {
if (returnCode == 1) {
Log.e("lrs","uninstall success...");
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_UNINSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_STATE", 1);
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", packageName);
mContext.sendBroadcast(mIntent);
}else{
Log.e("lrs","uninstall fail code:"+returnCode);
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_UNINSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_STATE", 0);
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", packageName);
mContext.sendBroadcast(mIntent);
}
}
}
***************************** 用于5.0 - 8.0 end **********************************************************
***************************** 用于9.0 start **********************************************************
import java.io.IOException;
import java.io.InputStream;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageInstallerCallback;
import android.content.pm.PackageManager;
import java.io.File;
import android.os.Environment;
import android.net.Uri;
import android.os.RemoteException;
import android.os.AsyncTask;
import java.io.FileInputStream;
import java.io.OutputStream;
import android.app.PendingIntent;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageParser;
import static android.content.pm.PackageInstaller.SessionParams.UID_UNKNOWN;
import android.support.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.pm.VersionedPackage;
import android.os.UserHandle;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.os.ServiceManager;
import android.app.ActivityThread;
public class Installer {
private Context mContext;
private static Installer mInstaller=null;
private static String TAG="rich_install";
private String mInstall_PackageName="rich_test";
private int mSessionId = -1;
static final int GENERATE_NEW_ID = Integer.MIN_VALUE;
private int mInstallId = Integer.MIN_VALUE;
private int nUnInstallId = Integer.MIN_VALUE;
private static Uri mPackageURI;
private static final String BROADCAST_ACTION = "com.android.packageinstaller.ACTION_INSTALL_COMMIT";
private static final String BROADCAST_ACTION_UN = "com.android.packageinstaller.ACTION_UNINSTALL_COMMIT";
private static final String UNINSTALL_ID = "com.android.packageinstaller.UNINSTALL_ID";
static final String EXTRA_ID = "EventResultPersister.EXTRA_ID";
private int mCounter;
private final Object mLock = new Object();
public UserHandle user;
public ApplicationInfo mAppInfo;
private Installer() {}
public static Installer getInstance(){
if(mInstaller==null){
mInstaller = new Installer();
}
return mInstaller;
}
/***************************** install start **************************************/
private boolean createSeesionId(){
boolean result = true;
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
params.originatingUid = 10045;
File file = new File(mPackageURI.getPath());
try {
PackageParser.PackageLite pkg = PackageParser.parsePackageLite(file, 0);
mInstall_PackageName = pkg.packageName;
params.setAppPackageName(pkg.packageName);
params.setInstallLocation(pkg.installLocation);
params.setSize(file.length());
//params.setSize( PackageHelper.calculateInstalledSize(pkg, false, params.abiOverride));
} catch (PackageParser.PackageParserException e) {
Log.e(TAG, "Cannot parse package " + file + ". Assuming defaults.");
Log.e(TAG, "Cannot calculate installed size " + file + ". Try only apk size.");
params.setSize(file.length());
}
try {
mInstallId = getNewId();
} catch (OutOfIdsException e) {
result=false;
}
try {
mSessionId = mContext.getPackageManager().getPackageInstaller().createSession(params); //get PackageInstaller
} catch (IOException e) {
result= false;
}
return result;
}
public int getNewId() throws OutOfIdsException {
synchronized (mLock) {
mCounter= GENERATE_NEW_ID + 1;
if (mCounter == Integer.MAX_VALUE) {
throw new OutOfIdsException();
}
mCounter++;
return mCounter - 1;
}
}
class OutOfIdsException extends Exception {}
class InstallingAsyncTask extends AsyncTask {
volatile boolean isDone;
@Override
protected PackageInstaller.Session doInBackground(Void... params) {
PackageInstaller.Session session;
try {
session = mContext.getPackageManager().getPackageInstaller().openSession(mSessionId);
} catch (IOException e) {
return null;
}
session.setStagingProgress(0);
try {
File file = new File(mPackageURI.getPath());
try (InputStream in = new FileInputStream(file)) {
long sizeBytes = file.length();
try (OutputStream out = session
.openWrite("PackageInstaller", 0, sizeBytes)) {
byte[] buffer = new byte[1024 * 1024];
while (true) {
int numRead = in.read(buffer);
if (numRead == -1) {
session.fsync(out);
break;
}
out.write(buffer, 0, numRead);
if (sizeBytes > 0) {
float fraction = ((float) numRead / (float) sizeBytes);
session.addProgress(fraction);
}
}
}
}
return session;
} catch (IOException | SecurityException e) {
Log.e(TAG, "Could not write package", e);
session.close();
return null;
} finally {
}
}
@Override
protected void onPostExecute(PackageInstaller.Session session) {
if (session != null) {
Intent broadcastIntent = new Intent(BROADCAST_ACTION);
broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
broadcastIntent.setPackage(
mContext.getPackageManager().getPermissionControllerPackageName());
//broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mInstallId);
broadcastIntent.putExtra(EXTRA_ID, mInstallId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
mContext,
mInstallId,
broadcastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());
}
}
}
public SessionCallbackDelegate MySessionCallbackDelegate ;
public void silentInstall(Context context, String fileName) {
Log.d(TAG,"fileName=" + fileName);
mContext = context;
user = android.os.Process.myUserHandle();
File file = new File(fileName);
if (!file.exists())
return;
MySessionCallbackDelegate =new SessionCallbackDelegate();
try {
ActivityThread.getPackageManager().getPackageInstaller().registerCallback(MySessionCallbackDelegate,user.getIdentifier()); //get IPackageInstaller
} catch (RemoteException e) {
Log.d(TAG,"registerCallback filed");
}
mPackageURI=Uri.fromFile(file);
if(!createSeesionId()){
return;
}
Log.d(TAG,"silentInstall start");
new InstallingAsyncTask().execute();
}
class SessionCallbackDelegate extends IPackageInstallerCallback.Stub{
private static final int MSG_SESSION_CREATED = 1;
private static final int MSG_SESSION_BADGING_CHANGED = 2;
private static final int MSG_SESSION_ACTIVE_CHANGED = 3;
private static final int MSG_SESSION_PROGRESS_CHANGED = 4;
private static final int MSG_SESSION_FINISHED = 5;
public SessionCallbackDelegate() {
}
@Override
public void onSessionCreated(int sessionId) {
}
@Override
public void onSessionBadgingChanged(int sessionId) {
}
@Override
public void onSessionActiveChanged(int sessionId, boolean active) {
}
@Override
public void onSessionProgressChanged(int sessionId, float progress) {
}
@Override
public void onSessionFinished(int sessionId, boolean success) {
Log.d(TAG,"onSessionFinished="+success);
if(success){
onPackageInstalled(mInstall_PackageName,1);
}else{
onPackageInstalled(mInstall_PackageName,-1);
}
try {
ActivityThread.getPackageManager().getPackageInstaller().unregisterCallback(MySessionCallbackDelegate);
} catch (RemoteException e) {
Log.d(TAG,"registerCallback filed");
}
}
}
/*****************************install end**************************************/
/*****************************uninstall start**************************************/
/*public void silentUninstall(String packageName, Context context) { //deletePackage Success no CallBack
user = android.os.Process.myUserHandle();
try {
nUnInstallId = getNewId();
} catch (OutOfIdsException e) {
Log.e(TAG, "Unable to get packageName. nUnInstallId OutOfIdsException");
}
IPackageManager pm = IPackageManager.Stub.asInterface(
ServiceManager.getService("package"));
if(pm==null){
return;
}
try {
mAppInfo= pm.getApplicationInfo(packageName, PackageManager.MATCH_ANY_USER, user.getIdentifier());
} catch (RemoteException e) {
Log.e(TAG, "Unable to get packageName. Package manager is dead?");
}
Log.d(TAG,"mAppInfo="+mAppInfo);
if(mAppInfo == null ){
return;
}
Intent broadcastIntent = new Intent(BROADCAST_ACTION_UN);
broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
broadcastIntent.putExtra(EXTRA_ID, nUnInstallId);
broadcastIntent.setPackage(mContext.getPackageName());
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, nUnInstallId,
broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
try {
ActivityThread.getPackageManager().getPackageInstaller().uninstall(
new VersionedPackage(mAppInfo.packageName, PackageManager.VERSION_CODE_HIGHEST),
mContext.getPackageName(),
0,
pendingIntent.getIntentSender(),
user.getIdentifier());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
public void packageDeleted(String packageName, int returnCode) {
if (returnCode == 1) {
Log.e(TAG,"uninstall success...");
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_UNINSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_STATE", 1);
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", packageName);
mContext.sendBroadcast(mIntent);
}else{
Log.e(TAG,"uninstall fail code:"+returnCode);
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_UNINSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_STATE", 0);
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", packageName);
mContext.sendBroadcast(mIntent);
}
}
*****************************uninstall end**************************************/
/*****************************Uninstall start 2**************************************/
public void silentUninstall(String packageName, Context context) {
user = android.os.Process.myUserHandle();
IPackageManager ipm = IPackageManager.Stub.asInterface(
ServiceManager.getService("package"));
if(ipm==null){
return;
}
try {
mAppInfo= ipm.getApplicationInfo(packageName, PackageManager.MATCH_ANY_USER, user.getIdentifier());
} catch (RemoteException e) {
Log.e(TAG, "Unable to get packageName. Package manager is dead?");
}
if(mAppInfo==null){
return;
}
IPackageDeleteObserver observer = new MyPackageDeleteObserver(context);
Log.d(TAG,"silentUninstall start");
context.getPackageManager().deletePackageAsUser(mAppInfo.packageName, observer, 0, user.getIdentifier());
}
class MyPackageDeleteObserver extends IPackageDeleteObserver.Stub {
public MyPackageDeleteObserver(Context context) {
mContext = context;
}
@Override
public void packageDeleted(String packageName, int returnCode) {
if (returnCode == 1) {
Log.e(TAG,"uninstall success...");
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_UNINSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_STATE", 1);
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", packageName);
mContext.sendBroadcast(mIntent);
}else{
Log.e(TAG,"uninstall fail code:"+returnCode);
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_UNINSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_STATE", 0);
mIntent.putExtra("com.rich.extra_UNINSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", packageName);
mContext.sendBroadcast(mIntent);
}
}
}
/*****************************Uninstall end 2**************************************/
public void onPackageInstalled(String basePackageName, int returnCode){
if (returnCode == 1) { // Success
Log.e(TAG,"install success... basePackageName="+basePackageName);
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_INSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_INSTALLE_RRESULT_INTERFACE_SET_STATE", 1);
mIntent.putExtra("com.rich.extra_INSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", basePackageName);
mContext.sendBroadcast(mIntent);
} else{ // Failure
Log.e(TAG,"install fail code:"+returnCode);
Intent mIntent =new Intent();
mIntent.setAction("com.rich.action_INSTALLER_APK_RESULT_INTERFACE_SET");
mIntent.putExtra("com.rich.extra_INSTALLE_RRESULT_INTERFACE_SET_STATE", 0);
mIntent.putExtra("com.rich.extra_INSTALLE_RRESULT_INTERFACE_SET_PACKAGE_NAME", basePackageName);
mContext.sendBroadcast(mIntent);
}
}
}
***************************** 用于9.0end **********************************************************