android 預裝第三方apk的方法

        預裝第三方apk,並不是裝到/system/app下,而是裝到/data/app/下,這兩者是有區別是,

前者用戶是不可以卸載的,後者用戶可以卸載,我們現在實現的就是後者。

1 pm.jar包中添加preinstall命令

修改:frameworks/base/cmds/pm/src/com/android/commands/pm/pm.java

--- 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命令。

service  preinstall  /system/bin/busybox  sh  /system/bin/preinstall.sh
  user root
  group root
  disabled
  oneshot
on property:sys.boot_completed=1
    start preinstall
有了以上定義之後,當系統啓動完成首,啓動preinstall服務,該服務呢,

將要執行/system/bin/preinstall.sh腳本完成預裝動作,這個服務只能執行一次(oneshot)

好了,下面看看執行pm preinstall命令的腳本

3 執行執行pm preinstall命令的腳本preinstall.sh

#!/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目錄下,這裏就不多說了。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章