@写在前面的话 Android 要想静默安装app,必须是系统应用或者具有Root权限,否则根本不可能实现静默安装 转载自@苍痕
1.系统API 。不是静默安装
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setDataAndType(Uri.parse("file://" + apkFilePath), "application/vnd.android.package-archive");
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(intent);
2. 静默安装:利用ProcessBuilder
-
-
-
-
-
-
- public static int installSilent(String filePath) {
- File file = new File(filePath);
- if (filePath == null || filePath.length() == 0 || file == null || file.length() <= 0 || !file.exists() || !file.isFile()) {
- return 1;
- }
-
- String[] args = { "pm", "install", "-r", filePath };
- ProcessBuilder processBuilder = new ProcessBuilder(args);
- Process process = null;
- BufferedReader successResult = null;
- BufferedReader errorResult = null;
- StringBuilder successMsg = new StringBuilder();
- StringBuilder errorMsg = new StringBuilder();
- int result;
- try {
- process = processBuilder.start();
- successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
- errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
- String s;
- while ((s = successResult.readLine()) != null) {
- successMsg.append(s);
- }
- while ((s = errorResult.readLine()) != null) {
- errorMsg.append(s);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (successResult != null) {
- successResult.close();
- }
- if (errorResult != null) {
- errorResult.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (process != null) {
- process.destroy();
- }
- }
-
-
- if (successMsg.toString().contains("Success") || successMsg.toString().contains("success")) {
- result = 0;
- } else {
- result = 2;
- }
- Log.d("test-test", "successMsg:" + successMsg + ", ErrorMsg:" + errorMsg);
- return result;
- }
3. 静默安装:利用Runtime.getRuntime().exec()
- private static final String TAG = "test-test";
-
- private static final int TIME_OUT = 60 * 1000;
-
- private static String[] SH_PATH = {
- "/system/bin/sh",
- "/system/xbin/sh",
- "/system/sbin/sh"
- };
-
- public static boolean executeInstallCommand(String filePath) {
- String command = “pm install -r ” + filePath;
- Process process = null;
- DataOutputStream os = null;
- StringBuilder successMsg = new StringBuilder();
- StringBuilder errorMsg = new StringBuilder();
- BufferedReader successResult = null;
- BufferedReader errorResult = null;
- try {
- process = runWithEnv(getSuPath(), null);
- if (process == null) {
- return false;
- }
-
- successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
- errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
-
- os = new DataOutputStream(process.getOutputStream());
- os.writeBytes(command + "\n");
- os.writeBytes("echo \"rc:\" $?\n");
- os.writeBytes("exit\n");
- os.flush();
-
- String s;
- while ((s = successResult.readLine()) != null) {
- successMsg.append(s);
- }
- while ((s = errorResult.readLine()) != null) {
- errorMsg.append(s);
- }
-
-
- if (TIME_OUT > 0) {
- long finish = System.currentTimeMillis() + TIME_OUT;
- while (true) {
- Thread.sleep(300);
- if (!isProcessAlive(process)) {
- break;
- }
-
- if (System.currentTimeMillis() > finish) {
- Log.w(TAG, "Process doesn't seem to stop on it's own, assuming it's hanging");
-
- return true;
- }
- }
- } else {
- process.waitFor();
- }
-
-
- if (process.exitValue() != 0) {
- return false;
- }
-
- return true;
-
- } catch (FileNotFoundException e) {
- Log.w(TAG, "Failed to run command, " + e.getMessage());
- return false;
- } catch (IOException e) {
- Log.w(TAG, "Failed to run command, " + e.getMessage());
- return false;
- } catch (InterruptedException e) {
- Log.w(TAG, "Failed to run command, " + e.getMessage());
- return false;
- } finally {
- if (os != null) {
- try {
- os.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- try {
- if (successResult != null) {
- successResult.close();
- }
- if (errorResult != null) {
- errorResult.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- if (process != null) {
- try {
-
- process.exitValue();
- } catch (IllegalThreadStateException e) {
- process.destroy();
- }
- }
- }
- }
-
- private static Process runWithEnv(String command, String[] customEnv) throws IOException {
- List<String> envList = new ArrayList<String>();
- Map<String, String> environment = System.getenv();
- if (environment != null) {
- for (Map.Entry<String, String> entry : environment.entrySet()) {
- envList.add(entry.getKey() + "=" + entry.getValue());
- }
- }
-
- if (customEnv != null) {
- for (String value : customEnv) {
- envList.add(value);
- }
- }
-
- String[] arrayEnv = null;
- if (envList.size() > 0) {
- arrayEnv = new String[envList.size()];
- for (int i = 0; i < envList.size(); i++) {
- arrayEnv[i] = envList.get(i);
- }
- }
-
- Process process = Runtime.getRuntime().exec(command, arrayEnv);
- return process;
- }
-
-
-
-
- private static boolean isProcessAlive(Process p) {
- try {
- p.exitValue();
- return false;
- } catch (IllegalThreadStateException e) {
- return true;
- }
- }
-
-
- private static String getSuPath() {
- for (String p : SH_PATH) {
- File sh = new File(p);
- if (sh.exists()) {
- return p;
- }
- }
- return "su";
- }
4. 静默安装:利用反射调用API-PackageManager.installPackage()
- public static void installSilentWithReflection(Context context, String filePath) {
- try {
- PackageManager packageManager = context.getPackageManager();
- Method method = packageManager.getClass().getDeclaredMethod("installPackage",
- new Class[] {Uri.class, IPackageInstallObserver.class, int.class, String.class} );
- method.setAccessible(true);
- File apkFile = new File(filePath);
- Uri apkUri = Uri.fromFile(apkFile);
-
- method.invoke(packageManager, new Object[] {apkUri, new IPackageInstallObserver.Stub() {
- @Override
- public void packageInstalled(String pkgName, int resultCode) throws RemoteException {
- Log.d(TAG, "packageInstalled = " + pkgName + "; resultCode = " + resultCode) ;
- }
- }, Integer.valueOf(2), "com.ali.babasecurity.yunos"});
-
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
上面用到了反射调用,IPackageInstallObserver.class这个类在android sdk里面是没有的,您需要下载
android_dependency.jar
放到你工程的libs目录,这个jar提供了与PackageManager反射调用相关的类的定义。
注意:静默安装还需要在你的AndroidManifest.xml中添加权限声明。该权限默认赋予系统应用,第三方应用即使声明了,也拿不到该权限!
-
- <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
/**
* 执行具体的静默安装逻辑,需要手机ROOT。
* @param apkPath
* 要安装的apk文件的路径
* @return 安装成功返回true,安装失败返回false。
*/
public 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;
}