本文主要介绍程序如何安装apk,包括普通模式安装和系统权限静默安装。
如果是非系统应用请直接查看:Android常用代码之APK root权限静默安装,查看更完美的解决方案。
1、普通模式安装,调用系统Intent,代码如下:
1 2 3 4 5 6 |
public static void install(Context context, String filePath) { Intent i = new Intent(Intent.ACTION_VIEW); i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive"); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } |
2、静默安装
如果是非系统应用请移步:Android常用代码之APK root权限静默安装,查看更完美的解决方案。
分为如下三步
(1)、静默安装需要系统应用安装权限,需要在AndroidManifest.xml中添加
1 |
<uses-permission android:name="android.permission.INSTALL_PACKAGES" /> |
(2)、实现代码
静默安装代码如下,实际是通过pm install -r 命令安装。
注意:该函数最好在新建的线程中运行并通过handler发送安装结果给主线程,否则安装时间较长会导致ANR。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
/** * install slient * * @param context * @param filePath * @return 0 means normal, 1 means file not exist, 2 means other exception error */ public static int installSlient(Context context, String filePath) { File file = new File(filePath); if (filePath == null || filePath.length() == 0 || (file = new File(filePath)) == 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(); result = 2; } catch (Exception e) { e.printStackTrace(); result = 2; } 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("installSlient", "successMsg:" + successMsg + ", ErrorMsg:" + errorMsg); return result; } |
返回值0表示安装成功,1表示文件不存在,2表示其他错误。需要更丰富的安装失败信息(内存不足、解析包出错)可直接使用PackageUtils.installSlient。
(3) 、获取系统权限
完成了上面两步后,普通方式安装我们的应用仍然无法静默安装。需要我们的应用获得系统权限,编译应用并通过
adb push <your_apk_path> /system/app/
命令实现安装,即可拥有系统权限。
android P 有没有试过
第三步什么意思,没有读懂,有人指点一下嘛
你这个还是需要系统签名授权的,还没有pm的方便
apk静默安装完后,安装的路径是在data/app下吗?那怎么样实现系统应用自己静默升级,升级完了还在system/app下呢?
cp 到 system/app 下,看 http://www.trinea.cn/android/android-java-execute-shell-commands/ 最后
您的意思是不需要执行pm install命令,而是直接将新版本apk cp到/system/app/下面?
嗯
可是我在执行命令“mount -o rw,remount /system”或“ cp /mnt/sdcard/xx.apk /system/app/”时会抛IOException: No such file or directory异常,apk的路径是对的,没有源码,不知道ProcessManager.exec(Native Method)的错误原因
确定你的 /mnt/sdcard/xx.apk 存在
apk是存在的,在adb shell中可以正确执行cp命令,但是写在系统应用中就会报错java.io.IOException: Error running exec(). Command: [mount -o remount,rw /system/app cp /storage/emulated/legacy/autoupgradedemo.apk /system/app/] Working Directory: null Environment: [ANDROID_ROOT=/system, 。。。不知道是不是因为我的测试机权限问题,但是模拟器也同样测不过
先自己在 adb 中测试, adb 中都通不过,就不用用代码测试了
successMsg:, ErrorMsg:Segmentation fault ,我的提示这个,获得root之后也安装不了。
换个一般的apk,比如 微信、微博
ddd
successMsg:, ErrorMsg:Segmentation fault ,我的提示也是这个,你怎么解决的能告知一下吗。谢谢,急
调用静默安装接口后 运行提示:ErrorMsg:su: uid not allowed to su
需要 root 权限
03-13 14:08:44.120: E/Trace(16372): error opening trace file: No such file or directory (2)03-13 14:08:45.620: E/PackageUtils(16372): installSilent successMsg:, ErrorMsg:Segmentation fault 这是什么错误,返回的是-1000000其他
您好,我有个问题想请教您,就是我在做一个程序,就是要实现静默安装,我使用了您写的代码,但是我总会碰到一个不可解决的问题,这个问题困扰我好久了,就是在shellUtils里execCommand这个函数,用了Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);可是我的程序经常会卡死在Runtime.getRuntime().exec(‘su’)这句话里,这个问题该怎么解决呢?
应该是手机问题,正常情况下这时候系统会弹出”是否允许xx程序获得root权限”的询问框
你好,我测试的平台已经是root了,系统不会弹出这个询问框,请问,我还需要用Runtime.getRuntime().exec(‘su’)么?
需要的,你是什么手机,什么系统?或者换台手机试试
不好意思啊,我找到毛病了,原来是我同一个程序开了几个task,没有销毁,所以老卡死,后来解决了这个问题就不卡住了。
(3)中,“系统权限”指root权限吗?”完成了上面两步后,普通方式安装我们的应用仍然无法静默安装“是什么意思?我的手机已经root过了,前两步静默安装时,应用申请root权限,我点击确定后,完成了静默安装。使用“adb push /system/app/“命令就可以不申请root权限吗?那是先执行push命令呢?还是先执行installSlient方法呢?
不是说的很清楚了吗,不是系统应用,你直接看http://www.trinea.cn/android/android%e5%b8%b8%e7%94%a8%e4%bb%a3%e7%a0%81%e4%b9%8bapk-root%e6%9d%83%e9%99%90%e9%9d%99%e9%bb%98%e5%ae%89%e8%a3%85/
楼主,系统应用跟非系统应用什么区别啊?
安装在/system/app的就是系统应用,其他的都是一般应用
/system/app下的应用跟其他应用有什么区别吗?一般开发的应用不是都在data/data/下吗?应用要怎么才能装到/system/app下?
你用一般应用方式就可以了,我们是自己做rom的