Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 初級開發 >> 應用程序無SDCard安裝APK

應用程序無SDCard安裝APK

編輯:初級開發

安裝存儲於SDCard的APK包很順利,但如果恰巧手機沒SDCard,將APK包下載到/data/data/<app_package>/下後,再用之前的方式安裝,一直提示"There is a problem parsing the package"。好吧,悲劇的程序員在需求至上的原則下又要解決此問題了。
1.准備
以上次寫過的斷點續傳的代碼 [DEVDIV]為例,將APK包下載存放路徑改為"/data/data/<app_packages>/aPPS/":
  1.     public static final String RES_LOAD_FOLDER = File.separator + "data" + File.separator + "data"
     
  2.             + File.separator + "lab.sodino.downloadbreak" + File.separator + "aPPS"
     
  3.             + File.separator;
復制代碼為方便,將"微信.apk"也改為"file.apk"。
下載後,點擊"安裝",出錯了。

2.找原因
這時進入adb shell,查看aPPS和file.apk的文件系統權限詳情如下:
  1. 不可安裝
     
  2. # cd /data/data/lab.sodino.downloadbreak
     
  3. cd /data/data/lab.sodino.downloadbreak
     
  4. # ls -l
     
  5. ls -l
     
  6. drwx------ app_38   app_38            2011-06-16 08:42 aPPS
     
  7. drwxr-xr-x system   system            2011-06-16 08:40 lib
     
  8. # ls -l aPPS
     
  9. ls -l aPPS
     
  10. -rw------- app_38   app_38    2708419 2011-06-16 08:42 file.apk
復制代碼可見文件夾aPPS僅對其擁有者app_38開放了讀、寫、執行權限,file.apk也僅僅是app_38有讀、寫權限。好了,問題找到了。即系統的應用程序安裝器無法讀取到file.apk導致的。

3.文件夾、文件的權限分配
系統的應用程序安裝器與app_38不同組,所以對aPPS和file.apk的文件系統權限修改應為修改其[other]組權限。(分為user/group/other三組,詳解請自行google或訪問:http://blog.csdn.Net/sodino/archive/2011/03/09/6234713.ASPx中的12.chmod詳解(用戶組區分))。

讀權限是必須的,但有一點要特別注意:僅對文件夾分配讀權限時,仍然無法讀取該文件夾下的內容。原因為文件夾在不具備執行權限時,是無法執行"cd"命令進入該文件夾,也無法執行"ls"命令讀取文件夾下的文件詳情。所以對aPPS和file.apk最精簡(當然直接設置為rwxrwxrwx是最不需要耗費腦細胞的)的權限分配詳情如下為:
  1. 可安裝
     
  2. # cd /data/data/lab.sodino.downloadbreak
     
  3. cd /data/data/lab.sodino.downloadbreak
     
  4. # ls -l
     
  5. ls -l
     
  6. drwx---r-x app_38   app_38            2011-06-16 08:33 aPPS
     
  7. drwxr-xr-x system   system            2011-06-16 08:31 lib
     
  8. # ls -l aPPS
     
  9. ls -l aPPS
     
  10. -rw----r-- app_38   app_38    2708419 2011-06-16 08:33 file.apk
復制代碼4.修改權限的方法
    aPPS        :drwx---r-x  →   (4+2+1) + (0+0+0) + (4+0+1)  →   705
    files.apk    :-rw----r--  →     (4+2+0) + (0+0+0) + (4+0+0)  →   604
    即對apps執行:chmod 705 /data/data/<app_package>/aPPS
    對file.apk執行:chmod 604 /data/data/<app_package>/aPPS/file.apk
    具體代碼為在lab.sodino.downloadbreak.ActDownload類中的installDownload()開頭處新增如下代碼:
  1.             // [文件夾705:drwx---r-x]
     
  2.         String[] args1 = { "chmod", "705", RES_LOAD_FOLDER };
     
  3.         exec(args1);
     
  4.         // [文件604:-rw----r--]
     
  5.         String[] args2 = { "chmod", "604", RES_LOAD_FOLDER + bean.name };
     
  6.         exec(args2);
復制代碼執行Linux命令的exec()方法實現如下:
  1.     /** 執行Linux命令,並返回執行結果。 */
     
  2.     public static String exec(String[] args) {
     
  3.         String result = "";
     
  4.         ProcessBuilder processBuilder = new ProcessBuilder(args);
     
  5.         Process process = null;
     
  6.         InputStream errIs = null;
     
  7.         InputStream inIs = null;
     
  8.         try {
     
  9.             ByteArrayOutputStream baos = new ByteArrayOutputStream();
     
  10.             int read = -1;
     
  11.             process = processBuilder.start();
     
  12.             errIs = process.getErrorStream();
     
  13.             while ((read = errIs.read()) != -1) {
     
  14.                 baos.write(read);
     
  15.             }
     
  16.             baos.write('\n');
     
  17.             inIs = process.getInputStream();
     
  18.             while ((read = inIs.read()) != -1) {
     
  19.                 baos.write(read);
     
  20.             }
     
  21.             byte[] data = baos.toByteArray();
     
  22.             result = new String(data);
     
  23.         } catch (IOException e) {
     
  24.             e.printStackTrace();
     
  25.         } catch (Exception e) {
     
  26.             e.printStackTrace();
     
  27.         } finally {
     
  28.             try {
     
  29.                 if (errIs != null) {
     
  30.                     errIs.close();
     
  31.                 }
     
  32.                 if (inIs != null) {
     
  33.                     inIs.close();
     
  34.                 }
     
  35.             } catch (IOException e) {
     
  36.                 e.printStackTrace();
     
  37.             }
     
  38.             if (process != null) {
     
  39.                 process.destroy();
     
  40.             }
     
  41.         }
     
  42.         return result;
     
  43.     }
復制代碼OK,Sodino Done it.
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved