- 需求:更新APP时,需要更新完自动启动APP的MainActivity(主页面)。注意:静默安装需要Root权限。
- 自定义一个类 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();
}
}
}
- 写入bytes数组后,更新完成后,当前APP可能直接挂掉,而且没有崩溃日志,正常现象。去设置中---->应用,查看versionName等信息,检查是否更新完成
- 定义广播,监听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);
}
}
}
- 重点是广播的注册。本人操作是静默安装发送一个广播,替换完成后捕捉到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>