静默安装 And 静默卸载 (更新5.0-9.0)

本文适用于 系统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 **********************************************************

你可能感兴趣的:(静默安装 And 静默卸载 (更新5.0-9.0))