最近遇到一个问题,之前运行好好的程序,在最近的daily build版本上无法正常运行,后来发现问题是:
我的程序在SDCard中找文件时找不到,而我shell进去后看到文件明明存在,而程序对该文件却视而不见。折腾了颇久,发现了一个问题:
正常版本上 adb shell mount 后:
/dev/block/vold/179:19 /storage/sdcard1 vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0002,dmask=0002,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
不可使用的版本:
/dev/block/vold/179:19 /storage/sdcard1 vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
后来问模块owner才知道:
平台做的改进,禁止具有system权限的进程访问sdcard,防止sdcard unmount时,导致system_server进程发生crash,从而被kill掉。
一听到这个理由后,我真是发飙了,为了解决某个问题而对系统做这么大的改变,真想投诉那家伙。
后来到网上搜了一下,发现很多程序员遇到这个问题。看来谷歌也是这么做的,我还能说什么呢,认命了。
访问SDcard成功的要素:
androidManifest..xml中包含:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
不能包含: android:sharedUserId="android.uid.system"
如果有system权限又想访问sdcard,怎么办?
android2.2以后修改
修改/system/core/vold/Volume.cpp 文件
将
Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false,
1000, 1015, 0702, true))
修改为:
[html]
Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false,
1000, 1015, 0002, true))
参数含义:
1000代表的是uid,即sytem
1015代表的是gid,
0002:是对权限的掩码
0002:表示 system: rwx-rwxr-x,此时system有读写执行权限
如果system不需要写权限可以将0002改为
0202: 表示 r-xrwxr-x。
默认的0702代表 ---rwxr-x
。
然后将vold重新编译一下,用adb push 命令push到 /system/bin/目录下。重新启动一下机器就OK了。
对于android 2.1以下:
可以
修改/system/core/vold/volmgr_vfat.c
[html]
rc = mount(devpath, vol->mount_point, "vfat", flags,"utf8,uid=1000,gid=1000,fmask=711,dmask=700,shortname=mixed");
改为
[html]rc = mount(devpath, vol->mount_point, "vfat", flags,"utf8,uid=1000,gid=1000,fmask=0,dmask=0,shortname=mixed");
这里的dmask和fmask和上面的作用类似。通过改写711和700可以配置出不同的权限。