[Android]应用程序无SDCard安装APK

来源:互联网 发布:美国电视直播软件 编辑:程序博客网 时间:2024/05/16 11:34

安装存储于SDCard的APK包很顺利,但如果恰巧手机没SDCard,将APK包下载到/data/data/<app_package>/下后,再用之前的方式安装,一直提示"There is a problem parsing the package"。好吧,悲剧的程序员在需求至上的原则下又要解决此问题了。

1.准备
以上次写过的断点续传的代码[CSDN]为例,将APK包下载存放路径改为"/data/data/<app_packages>/apps/":

[java] view plaincopy
  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的文件系统权限详情如下:

[java] view plaincopy
  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详解(用户组区分))。

文件夹的读权限是指可以读取该文件目录结构信息,写权限是指可以更改文件目录结构信息,位于其[other]组的用户能否读取该文件夹下的文件与文件夹是否开放读权限无关,只与文件夹开放的执行权限有关。原因为文件夹在不具备执行权限时,是无法执行"cd"命令进入该文件夹(也无法执行"ls"命令读取文件夹下的文件详情)。所以对apps和file.apk最精简(当然直接设置为rwxrwxrwx是最不需要耗费脑细胞的)的权限分配详情如下为:

 
[java] view plaincopy
  1. 可安装  
  2. # cd /data/data/lab.sodino.downloadbreak  
  3. cd /data/data/lab.sodino.downloadbreak  
  4. # ls -l  
  5. ls -l  
  6. drwx-----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-----x  →   (4+2+1) + (0+0+0) + (0+0+1)  →   701
    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()开头处新增如下代码:
 
[java] view plaincopy
  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()方法实现如下:
    
[java] view plaincopy
  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.

 

本文内容归CSDN博客博主Sodino 所有
转载请注明出处:http://blog.csdn.net/sodino/archive/2011/06/16/6549082.aspx


原创粉丝点击