一.前言
实静默安装的原理就是调用Android系统的pm install命令就可以了,但关键的问题就在于,pm命令系统是不授予我们权限调用的,因此只能在拥有ROOT权限的手机上去申请权限才行。
二.流程
1.ROOT
手机要先root,可以在代码中判断下有无ROOT
public static boolean is_root() {
boolean res = false;
try {
if ((!new File("/system/bin/su").exists()) && (!new File("/system/xbin/su").exists())) {
res = false;
} else {
res = true;
}
} catch (Exception e) {
}
return res;
}
2.静默安装
如果有root的话,在下载完apk后可执行静默安装
public static boolean install(String apkPath) {
boolean result = false;
DataOutputStream dataOutputStream = null;
BufferedReader errorStream = null;
try {
// 申请su权限
Process process = Runtime.getRuntime().exec("su");
dataOutputStream = new DataOutputStream(process.getOutputStream());
// 执行pm install命令
String command = "pm install -r " + apkPath + "\n";
dataOutputStream.write(command.getBytes(Charset.forName("utf-8")));
dataOutputStream.flush();
dataOutputStream.writeBytes("exit\n");
dataOutputStream.flush();
process.waitFor();
errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String msg = "";
String line;
// 读取命令的执行结果
while ((line = errorStream.readLine()) != null) {
msg += line;
}
Log.d("TAG", "install msg is " + msg);
// 如果执行结果中包含Failure字样就认为是安装失败,否则就认为安装成功
if (!msg.contains("Failure")) {
result = true;
}
} catch (Exception e) {
Log.e("TAG", e.getMessage(), e);
} finally {
try {
if (dataOutputStream != null) {
dataOutputStream.close();
}
if (errorStream != null) {
errorStream.close();
}
} catch (IOException e) {
Log.e("TAG", e.getMessage(), e);
}
}
return result;
}
3.自启动
在安装完app后,对其进行自启动
(1) 在AndroidManifest.xml注册广播监听
<receiver android:name="com.example.demo.receiver.SilenceInstallReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
(2)在安装
public class SilenceInstallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.PACKAGE_REPLACED")){
startApp(context);
}
}
/**
* 监测到升级后执行app的启动
*/
public void startApp(Context context){
Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}