美文网首页
安卓静默安装与自启动

安卓静默安装与自启动

作者: DDstar | 来源:发表于2019-12-24 17:16 被阅读0次
    写在前面

    静默安装如果在正常的用户手机上除非是残疾用户使用,不然都是耍流氓

    本次是因为做一个硬件功能,不带操作的硬件在版本更新的时候只能使用静默安装

    不想听瞎逼逼可以直接看总结

    说一下大概流程

    静默安装需要操作的应用包括需要安装的app(最后安装的app)和被静默安装的app(要被替换掉的)

    首先是最后要安装的app需要的操作

    • 写app(废话)

    • 设置安装监听权限

    • 做安装与卸载的广播监听

    • 接收到广播就调用打开应用方法

    • 打包应用

    • 搞定

    代码撸起来

    1 首先写个app(省略一万行代码)
    2 添加监听安装和卸载权限

      <uses-permission android:name="android.permission.DELETE_PACKAGES" />
        <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    

    3 做安装与卸载的广播监听,接收到广播就调用打开应用方法

    自定义一个receiver继承BroadcastReceiver

    public class BootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            //接收安装广播 
            if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
                String packageName = intent.getDataString();
                // TODO:   ActivityHome为启动页
                Intent intent2 = new Intent(context, ActivityHome.class);
                intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent2);
                Log.e("onReceive", "安装了:" + packageName + "包名的程序");
            }
            //接收重新安装广播
            if (intent.getAction().equals("android.intent.action.PACKAGE_REPLACED")) {
                Toast.makeText(context, "升级了一个安装包,重新启动此程序", Toast.LENGTH_SHORT).show();
                // TODO:   ActivityHome为启动页
                Intent intent2 = new Intent(context, ActivityHome.class);
                intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent2);
    
            }
            //接收卸载广播
            if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {
                String packageName = intent.getDataString();
                System.out.println("卸载了:" + packageName + "包名的程序");
    
            }
        }
    } 
    

    4 打包应用@@%#$&%*&%&%&^%

    之后就可以将此app放到服务器上面等待下载安装了
    以上,此app就具有被唤醒的功能,也就是我们静默安装的目标app 可以 被唤醒了

    然后是最后具备静默安装的App需要的操作

    • 添加安装app权限和超级用户权限

    • 静默安装逻辑

    • 打包

    • 系统签名

    • 搞定

    代码接着撸起来

    1 添加安装app权限和超级用户权限

    //有root的设备声明超级用户权限
     <uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    添加了这个权限还是啊会提示错误,能编译通过就不要管他

    2 静默安装需要反射系统的方法来实现

     public void installPackage(String apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException, NoSuchMethodException {
            Class<?> pmClz = pm.getClass();
            if (Build.VERSION.SDK_INT >= 21) {
                Class<?> aClass = Class.forName("android.app.PackageInstallObserver");
                Constructor<?> constructor = aClass.getDeclaredConstructor();
                constructor.setAccessible(true);
                Object installObserver = constructor.newInstance();
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class,
                        aClass, int.class, String.class);
                method.setAccessible(true);
                method.invoke(pm, Uri.fromFile(new File(apkFile)),
                        installObserver, 2, null);
            } else {
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class,
                        Class.forName("android.content.pm.IPackageInstallObserver"), int.class,
                        String.class);
                method.setAccessible(true);
                method.invoke(pm, Uri.fromFile(new File(apkFile)), null, 2,
                        null);
            }
        }
    
    

    3 在下载安装包完成后调用安装逻辑

    4 做应用系统签名 <---重点
    普通签名的应用在调用静默安装的时候会抛没有此方法的异常,需要对它进行系统应用签名才能做到
    所以
    |
    |
    首先 将我们的app打包
    然后使用签名工具---链接---
    下载此工具包 将apk安装包放到工具包目录下,使用命令工具

    java -jar signapk.jar platform.x509.pem platform.pk8 unsign.apk signed.apk
    

    签名完成的安装包就是具备静默安装功能的安装包了,将此安装包安装到设备上,就可以测试静默安装了

    总结

    静默安装的app当然是需要每次升级安装的版本具备静默安装下一个应用的功能,所以一般来说,一个要做静默安装的应用必须具备静默安装其他app和被其他app静默安装的时候可以唤醒,所以以上的两个功能在同一个apk里面都必须具备

    所以总结下步骤(其实看这个就可以了)

    • 设置下载和监听安装、重新安装、卸载的权限
     <uses-permission android:name="android.permission.DELETE_PACKAGES" />
        <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    //有root的设备声明超级用户权限
     <uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
    • 自定义receiver 继承BroadcastReceiver 在收到安装或重新安装的action时打开app操作
    public class BootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            //接收安装广播 
            if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
                String packageName = intent.getDataString();
                // TODO:   ActivityHome为启动页
                Intent intent2 = new Intent(context, ActivityHome.class);
                intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent2);
                Log.e("onReceive", "安装了:" + packageName + "包名的程序");
            }
            //接收重新安装广播
            if (intent.getAction().equals("android.intent.action.PACKAGE_REPLACED")) {
                Toast.makeText(context, "升级了一个安装包,重新启动此程序", Toast.LENGTH_SHORT).show();
                // TODO:   ActivityHome为启动页
                Intent intent2 = new Intent(context, ActivityHome.class);
                intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent2);
    
            }
            //接收卸载广播
            if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {
                String packageName = intent.getDataString();
                System.out.println("卸载了:" + packageName + "包名的程序");
    
            }
        }
    } 
    
    • 在清单文件注册以上receiver
    <receiver
                android:name=".silenceInstall.BootReceiver"
                android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.PACKAGE_ADDED" />
                    <action android:name="android.intent.action.PACKAGE_REPLACED" />
                    <action android:name="android.intent.action.PACKAGE_REMOVED" />
    
                    <data android:scheme="package" />
                </intent-filter>
    
    • 做静默安装逻辑,在安装包下载完成后调用安装方法
     public void installPackage(String apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException, NoSuchMethodException {
            Class<?> pmClz = pm.getClass();
            if (Build.VERSION.SDK_INT >= 21) {
                Class<?> aClass = Class.forName("android.app.PackageInstallObserver");
                Constructor<?> constructor = aClass.getDeclaredConstructor();
                constructor.setAccessible(true);
                Object installObserver = constructor.newInstance();
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class,
                        aClass, int.class, String.class);
                method.setAccessible(true);
                method.invoke(pm, Uri.fromFile(new File(apkFile)),
                        installObserver, 2, null);
            } else {
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class,
                        Class.forName("android.content.pm.IPackageInstallObserver"), int.class,
                        String.class);
                method.setAccessible(true);
                method.invoke(pm, Uri.fromFile(new File(apkFile)), null, 2,
                        null);
            }
        }
    
    • 打包app
    $%#$^$&^%*^*^&
    

    使用系统签名工具---》
    使用命令

    java -jar signapk.jar platform.x509.pem platform.pk8 unsign.apk signed.apk
    
    • 搞定

    相关文章

      网友评论

          本文标题:安卓静默安装与自启动

          本文链接:https://www.haomeiwen.com/subject/wbdfoctx.html