浅谈Android中静默安装&&卸载流程的使用

1.静默安装:一般需要该应用是系统级别的应用,经过了平台下发的对应签名apk。

即: 1.内置到ROM,即APK包的安装位置是/system/app下。

        2.使用APK的目标安装系统同样的签名。

         当然不同平台的签名是不一样的,这个需要根据平台业务来具体确认,第三方Rom这样做也是处于保护系统安全的角度来考虑的。

个人在这只是针对上述分享下静默安装的具体实现方式:

针对 Android 6.0 and up. 静默安装示例如下:

public static boolean installPackage(Context context, InputStream in, String packageName) throws IOException {
    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
    PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
    params.setAppPackageName(packageName);
    // set params
    int sessionId = packageInstaller.createSession(params);
    PackageInstaller.Session session = packageInstaller.openSession(sessionId);
    OutputStream out = session.openWrite(packageName, 0, -1);
    byte[] buffer = new byte[65536];
    int c;
    while ((c = in.read(buffer)) != -1) {
       out.write(buffer, 0, c);
   }
    session.fsync(out);
    in.close();
    out.close();
    session.commit(createIntentSender(context, sessionId));
    return true;
}

    private static IntentSender createIntentSender(Context context, int sessionId) {
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,sessionId,new Intent(Intent.ACTION_PACKAGE_ADDED),PendingIntent.FLAG_UPDATE_CURRENT);
        return pendingIntent.getIntentSender();
}

针对 Android 6.0 and up. 静默卸载示例如下:

String appPackage = "com.your.app.package";
Intent intent = new Intent(getActivity(), getActivity().getClass());
PendingIntent sender = PendingIntent.getActivity(getActivity(), 0, intent, 0);
PackageInstaller mPackageInstaller = getActivity().getPackageManager().getPackageInstaller();
mPackageInstaller.uninstall(appPackage, sender.getIntentSender());

低版本Android 6.0以下,大部分app的静默安装都是通过 移植系统源码中的相关AIDL 文件,进行调用pm里面的android方法:

普通情况下肯定是调用不到的。在源码\frameworks\base\core\java\android\content\pm目录下PackageManager.java,应该发现

在注释行里有加上@hide声明。调用的安装下载接口如下:

public abstract void installPackage(Uri packageURI,IPackageInstallObserver observer, int flags,String installerPackageName);
public abstract void deletePackage(String packageName,IPackageDeleteObserver observer, int flags);

最简单的就是直接拷贝4个文件即可:

PackageManager.java

IPackageDeleteObserver.aidl

IPackagerInstallObserver.aidl

IPackageMoveObserver.aidl

然后把PackageManager.java中报的异常的接口都注释掉即可,然后直接调用pm里面的方法。

静默安装示例如下:

/*** 静默安装* */
public static void autoInstallApk(Context context, String fileName,String packageName, String APPName) {
       Log.d(TAG, “jing mo an zhuang:” + packageName + “,fileName:” + fileName);File file = new File(fileName);
       int installFlags = 0;
       if (!file.exists())
                return;
           installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
       if (hasSdcard()) {
           installFlags |= PackageManager.INSTALL_EXTERNAL;
       }
       PackageManager pm = context.getPackageManager();
       try {
            IPackageInstallObserver observer = new MyPakcageInstallObserver(context, APPName, appId, fileName,packageName,type_name);
            Log.i(TAG, “########installFlags:” + installFlags+”packagename:”+packageName);
            pm.installPackage(Uri.fromFile(file), observer, installFlags,packageName);
           } catch (Exception e) {
                

          }
}

实现静默安装的回调接口如下:

class MyPakcageInstallObserver extends IPackageInstallObserver.Stub {
Context cxt;
String appName;
String filename;
String pkname;

 public MyPakcageInstallObserver(Context c, String appName, String filename, String packagename) {
  this.cxt = c;
  this.appName = appName;
  this.filename = filename;
  this.pkname = packagename;
}

    @Override
    public void packageInstalled(String packageName, int returnCode) {
        Log.i(TAG, “returnCode = ” + returnCode);// 返回1代表安装成功
        if (returnCode == 1) {
             //TODO
        }
        Intent it = new Intent();
        it.setAction(CustomAction.INSTALL_ACTION);
        it.putExtra(“install_returnCode”, returnCode);
        it.putExtra(“install_packageName”, packageName);
        it.putExtra(“install_appName”, appName); cxt.sendBroadcast(it);
    }
}

下面来看看apk的卸载流程。

[/frameworks/base/core/java/android/app/ApplicationPackageManager.java]

@Override
public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
    try {
        mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
    } catch (RemoteException e) {
    // Should never happen!
  }
}

Client端调用PackageManager的deletePackage方法删除对应包名的apk,其中通过注册IPackageDeleteObserver监听卸载结果。实际上通过binder调用pms的deletePackageAsUser方法,在服务中执行卸载动作。

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值