android 预装第三方apk的方法
16lz
2021-01-26
预装第三方apk,并不是装到/system/app下,而是装到/data/app/下,这两者是有区别是,
[plain] view plain copy
前者用户是不可以卸载的,后者用户可以卸载,我们现在实现的就是后者。
1 pm.jar包中添加preinstall命令
修改:frameworks/base/cmds/pm/src/com/android/commands/pm/pm.java
[java] view plain copy- --- a/cmds/pm/src/com/android/commands/pm/Pm.java
- +++ b/cmds/pm/src/com/android/commands/pm/Pm.java
- @@ -106,6 +106,10 @@ public final class Pm {
- runInstall();
- return;
- }
- + if ("preinstall".equals(op)) {
- + preInstall();
- + return;
- + }
- if ("uninstall".equals(op)) {
- runUninstall();
- @@ -763,7 +767,50 @@ public final class Pm {
- System.err.println(PM_NOT_RUNNING_ERR);
- }
- }
- -
- + private void preInstall() {
- + String path = nextArg();
- + int i;
- +
- + System.err.println("\t preInstall path: " + path);
- + if (path == null) {
- + System.err.println("Error: no package specified");
- + showUsage();
- + return;
- + }
- +
- + File[] files = new File(path).listFiles();
- +
- + for(File apkFilePath : files) {
- + System.err.println("\tpkg: " + apkFilePath);
- + PackageInstallObserver obs = new PackageInstallObserver();
- + try {
- + mPm.installPackage(Uri.fromFile(apkFilePath), obs, 0,null);
- + System.err.println("\t pkg----1------: ");
- + synchronized (obs) {
- + while (!obs.finished) {
- + try {
- + System.err.println("\t pkg----2------: ");
- + obs.wait();
- + System.err.println("\t pkg----3------: ");
- + } catch (InterruptedException e) {
- + System.err.println("\t pkg----4------: ");
- + }
- + }
- + if (obs.result == PackageManager.INSTALL_SUCCEEDED) {
- + System.out.println("Success");
- + } else {
- + System.err.println("Failure ["
- + + installFailureToString(obs.result)
- + + "]");
- + }
- + }
- + } catch (RemoteException e) {
- + System.err.println(e.toString());
- + System.err.println(PM_NOT_RUNNING_ERR);
- + }
- + }
- + System.err.println("\t preInstall path: " + path + " ok");
- + }
- private void runInstall() {
- int installFlags = 0;
- String installerPackageName = null;
2 在init.rc中定义一个preinstall服务
该服务去执行一个脚本,在脚本里面调用pm preinstall命令。
[plain] view plain copy- service preinstall /system/bin/busybox sh /system/bin/preinstall.sh
- user root
- group root
- disabled
- oneshot
- on property:sys.boot_completed=1
- start preinstall
将要执行/system/bin/preinstall.sh脚本完成预装动作,这个服务只能执行一次(oneshot)
好了,下面看看执行pm preinstall命令的脚本
[plain] view plain copy
- #!/system/bin/busybox sh
- BUSYBOX="/system/bin/busybox"
- if [ ! -e /data/system.notfirstrun ]; then
- echo "do preinstall job"
- /system/bin/sh /system/bin/pm preinstall /system/preinstall
- $BUSYBOX touch /data/system.notfirstrun
- echo "preinstall ok"
- fi
将 /system/preinstall作为参数(其实就是预装apk的目录),传给pm,将该目录下的apk一次预装。
pm preinstall 最终将调用到frameworks/base/cmds/pm/src/com/android/commands/pm/pm.java
文件中,一次安装apk。
所以,要预装apk,还需要将预装的第三方apk拷贝到/system/preinstall目录下,这里就不多说了。
更多相关文章
- Android(安卓)P wakeup 亮屏流程
- 使用cocos compile -p android -m release 报错
- 〖Android〗代理与正常网络分开同步CyangenMod源码
- android异步操作类----AsyncTask
- Android在真机调试的设置方法
- Gradle Android最新自动化编译脚本教程
- WakeLock & WifiLock的实现
- 编译Android源码制作ROM,烧录
- Android学习【3】Android开发问题记录