android如何在定制系统上实现静默安装
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android如何在定制系统上实现静默安装相关的知识,希望对你有一定的参考价值。
目前的要求是在ACER-Z120手机上(该手机应该是基于android 4.1.1的定制系统)实现软件的静默安装。就是我要写一个控制软件来下载被控制软件,下载完了静默安装被控制软件。我的控制软件要执行 pm install 命令是不是要先得到该操作系统的platform..pk8 platform.x509.pem signapk.jar三个文件,用命令来对我的控制软件进行签名,在安装进入该手机?整个过程这样对吗?我现在把签名好的apk文件放到与adb.exe同一目录下,在cmd下执行adb install signed.apk(我要装到真机里)会报错,Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES],能包我分析下吗?
电脑通过usb调试模式控制静默安装是可以的。手机自己控制静默安装需要获得ROOT权限。追问
感谢您的回答,我问一下,只能root吗?目前的要求是手机不能root。有办法实现吗?
追答只能ROOT了。
追问那先不管静默安装,我的控制软件用厂商提供的platform.pk8 platform.x509.pem signapk.jar三个文件签好名,为什么无法安装进手机?
参考技术A 不懂啊,不好意思啊Android 如何静默安装app
Android 要想静默安装app,必须是系统应用或者具有Root权限,否则根本不可能实现静默安装。
本文假设你的app是系统应用(有系统签名,或者放在系统/system/app 或 /system/priv-app分区),则可以进行以下安装:
注意:静默安装还需要在你的AndroidManifest.xml中添加权限声明。该权限默认赋予系统应用,第三方应用即使声明了,也拿不到该权限! [html] view plain copy- <!-- 静默安装 -->
- <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
1. 有提示的安装(所有第三方应用都可以)
[java] view plain copy- 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
[java] view plain copy- /**
- * install slient
- *
- * @param filePath
- * @return 0 means normal, 1 means file not exist, 2 means other exception error
- */
- 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();
- // TODO should add memory is not enough here
- if (successMsg.toString().contains("Success") || successMsg.toString().contains("success"))
- result = 0;
- else
- result = 2;
- Log.d("test-test", "successMsg:" + successMsg + ", ErrorMsg:" + errorMsg);
- return result;
- 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);
- // Handle a requested timeout, or just use waitFor() otherwise.
- 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");
- // Note: 'finally' will call destroy(), but you might still see zombies.
- return true;
- else
- process.waitFor();
- // In order to consider this a success, we require to things: a) a proper exit value, and ...
- 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
- // Yes, this really is the way to check if the process is still running.
- 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;
- /**
- * Check whether a process is still alive. We use this as a naive way to implement timeouts.
- */
- private static boolean isProcessAlive(Process p)
- try
- p.exitValue();
- return false;
- catch (IllegalThreadStateException e)
- return true;
- /** Get the SU file path if it exist */
- private static String getSuPath()
- for (String p : SH_PATH)
- File sh = new File(p);
- if (sh.exists())
- return p;
- return "su";
[java] view plain copy
- 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");
- //PackageManager.INSTALL_REPLACE_EXISTING = 2;
- catch (NoSuchMethodException e)
- e.printStackTrace();
- catch (Exception e)
- e.printStackTrace();
以上是关于android如何在定制系统上实现静默安装的主要内容,如果未能解决你的问题,请参考以下文章