Android 静默安装和自启动

  1. 需求:更新APP时,需要更新完自动启动APP的MainActivity(主页面)。注意:静默安装需要Root权限。
  2. 自定义一个类 AutoInstallRestartManager
 //静默安装
    public static void installSilent(String apkPath, Context context) {
        LogUtil.i(TAG, "开始静默安装");
        String cmd = "pm install -r " + apkPath + "\n";

        Process process = null;
        DataOutputStream os = null;
//        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = null;
        StringBuilder errorMsg = null;
        try {
            //静默安装需要root权限
            process = Runtime.getRuntime().exec("su");
            os = new DataOutputStream((OutputStream) process.getOutputStream());
            // 部分手机Root之后Library path 丢失,导入library path可解决该问题
//            os.writeBytes((String) "export LD_LIBRARY_PATH=/vendor/lib:/system/lib\n");
//            byte[] bytes = cmd.getBytes();
//            os.write(bytes);
//            os.flush();
            os.writeBytes(cmd);
            os.writeBytes("exit\n");
            os.flush();
            //执行命令
            process.waitFor();
            //获取返回结果
            successMsg = new StringBuilder();
            errorMsg = new StringBuilder();
//            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String s;
            while ((s = errorResult.readLine()) != null) {
                successMsg.append(s);
                LogUtil.i(TAG, "installSilent success");
            }
            LogUtil.i(TAG, "installSilent fail:" + errorMsg.toString());
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.i(TAG, "installSilent fail,Exception:" + e.getLocalizedMessage());
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (process != null) {
                    process.destroy();
                }

                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
  1. 写入bytes数组后,更新完成后,当前APP可能直接挂掉,而且没有崩溃日志,正常现象。去设置中---->应用,查看versionName等信息,检查是否更新完成
  2. 定义广播,监听apk被替换
	public class CommonReceiver extends BroadcastReceiver {


    @Override
    public void onReceive(final Context context, Intent intent) {
        //监听应用被替换的广播
        String action = intent.getAction();
        if (DirConfig.SILENCE_INSTALL_ACTION.equals(action)) {//静默安装
            LogUtil.i("CommonReceiver", "接收到SILENCE_INSTALL_ACTION,静默安装");
            final String versionUpdatePath = intent.getStringExtra("path");
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    AutoInstallRestartManager.checkAndInstallApkByPath(context, "", versionUpdatePath);
                }
            }.start();
        } else {
            LogUtil.i("CommonReceiver", "接收到PACKAGE_REPLACED,启动应用");
            try {
                File file = new File(DirConfig.VERSIONUPDATEPATH);
//            版本更新成功后,把下载的apk删除掉
                if (file.exists()) {
                    boolean delete = file.delete();
                }
            } catch (Exception e) {
                LogUtil.i("CommonReceiver", "删除安装包失败!请检查安装包路径");
            }

            intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        }
    }
}
  1. 重点是广播的注册。本人操作是静默安装发送一个广播,替换完成后捕捉到PACKAGE_REPLACED广播,开始自启动。也可以不使用SILENCE_INSTALL_ACTION这个action,直接点击静默安装,只监听被替换的广播
<receiver android:name="包名.CommonReceiver">
            <intent-filter>
                <!--apk被替换-->
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <data android:scheme="package" />
            </intent-filter>
            <intent-filter>
                <!--静默安装,可酌情舍弃-->
                <action android:name="android.intent.action.SILENCE_INSTALL_ACTION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

猜你喜欢

转载自blog.csdn.net/guojiayuan002/article/details/83861874