在一些特殊用途的时候,我们需要为APP设计自动安装升级包,并能在自动静默安装后自动打开应用。一般这种用途大都在android工控机上,因为这样的机器大都是具备root权限的,不然的话,如果没有root权限,自动静默安装及自动打开都是不能实现的。
首先,我写了一个工具类用于处理静默安装:
public class UpdateUtil {
public static boolean install(String path, Context context) {
// 判断root权限
if (isRoot()) {
// 有root权限,静默安装
return apkInstall(path);
} else {
// 无root权限,用意图安装,无法自动,没有意义
File file = new File(path);
if (!file.exists())
return false;
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
context.startActivity(intent);
return true;
}
}
/** 静默安装 */
private static boolean apkInstall(String path) {
PrintWriter PrintWriter = null;
Process process = null;
try {
process = Runtime.getRuntime().exec("su");
PrintWriter = new PrintWriter(process.getOutputStream());
PrintWriter.println("chmod 777 " + path);
PrintWriter
.println("export LD_LIBRARY_PATH=/vendor/lib:/system/lib");
PrintWriter.println("pm install -r " + path);
PrintWriter.flush();
PrintWriter.close();
int value = process.waitFor();
return value == 0;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
}
return false;
}
/** 判断当前设备是否已经获取到root权限 */
private static boolean isRoot() {
PrintWriter PrintWriter = null;
Process process = null;
try {
process = Runtime.getRuntime().exec("su");
PrintWriter = new PrintWriter(process.getOutputStream());
PrintWriter.flush();
PrintWriter.close();
int value = process.waitFor();
return value == 0;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
}
return false;
}
}
另外需要在新版本中,注册广播,在androidManifest.xml中添加权限并注册:
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name="com.example.updatetest.utils.TestReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
TestReceiver中注意处理<pre name="code" class="html">android.intent.action.PACKAGE_REPLACED
从而实现自动启动该应用
if (intent.getAction().equalsIgnoreCase("android.intent.action.PACKAGE_REPLACED")) {
Intent intent2 = new Intent(context, MainActivity.class);
intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent2);
}