问题:应用在AndroidManifest.xml 文件 申请WRITE_EXTERNAL_STORAGE 权限即可对sdcard 下文件进行操作。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
应用的用户id 和所属组是什么?
adb shell 查看 sdcard 文件读写执行权限:
- dengpei@dengpei-pc:~$ adb shell
- # cd /mnt/sdcard
- # ls -al |grep "fileForTestRight.txt"
- ----rwxr-x 1 system sdcard_rw 0 Jan 18 11:20 fileForTestRight.txt
- # whoami
- root
- #
文件
fileForTestRight.txt
权限:
system --x
sdcard_r rwx
other r_x
sdcrad 文件 权限定义由VoId 设置
gingerbread/system/vold/Volume.cpp
:
- int Volume::mountVol() {
- dev_t deviceNodes[4];
- int n, i, rc = 0;
- char errmsg[255];
- if (getState() == Volume::State_NoMedia) {
- snprintf(errmsg, sizeof(errmsg),
- "Volume %s %s mount failed - no media",
- getLabel(), getMountpoint());
- mVm->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeMountFailedNoMedia,
- errmsg, false);
- errno = ENODEV;
- return -1;
- } else if (getState() != Volume::State_Idle) {
- errno = EBUSY;
- return -1;
- }
- if (isMountpointMounted(getMountpoint())) {
- SLOGW("Volume is idle but appears to be mounted - fixing");
- setState(Volume::State_Mounted);
- // mCurrentlyMountedKdev = XXX
- return 0;
- }
- n = getDeviceNodes((dev_t *) &deviceNodes, 4);
- if (!n) {
- SLOGE("Failed to get device nodes (%s)\n", strerror(errno));
- return -1;
- }
- for (i = 0; i < n; i++) {
- char devicePath[255];
- sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]),
- MINOR(deviceNodes[i]));
- SLOGI("%s being considered for volume %s\n", devicePath, getLabel());
- errno = 0;
- setState(Volume::State_Checking);
- if (Fat::check(devicePath)) {
- if (errno == ENODATA) {
- SLOGW("%s does not contain a FAT filesystem\n", devicePath);
- continue;
- }
- errno = EIO;
- /* Badness - abort the mount */
- SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
- setState(Volume::State_Idle);
- return -1;
- }
- /*
- * Mount the device on our internal staging mountpoint so we can
- * muck with it before exposing it to non priviledged users.
- */
- errno = 0;
- if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false,
- 1000, 1015, 0702, true)) {
- SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
- continue;
- }
- SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint());
- protectFromAutorunStupidity();
- if (createBindMounts()) {
- SLOGE("Failed to create bindmounts (%s)", strerror(errno));
- umount("/mnt/secure/staging");
- setState(Volume::State_Idle);
- return -1;
- }
- /*
- * Now that the bindmount trickery is done, atomically move the
- * whole subtree to expose it to non priviledged users.
- */
- if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) {
- SLOGE("Failed to move mount (%s)", strerror(errno));
- umount("/mnt/secure/staging");
- setState(Volume::State_Idle);
- return -1;
- }
- setState(Volume::State_Mounted);
- mCurrentlyMountedKdev = deviceNodes[i];
- return 0;
- }
- SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel());
- setState(Volume::State_Idle);
- return -1;
- }
- doMount(devicePath, "/mnt/secure/staging", false, false, false,
- 1000, 1015, 0702, true)
定义 uid 1000 gid 1015 文件读写执行权限 为 0702
即 075 ---rwxr-x
继续查看:
gingerbread/system/core/include/private/android_filesystem_config.h
- /* This is the master Users and Groups config for the platform.
- ** DO NOT EVER RENUMBER.
- */
- #define AID_ROOT 0 /* traditional unix root user */
- #define AID_SYSTEM 1000 /* system server */
- #define AID_RADIO 1001 /* telephony subsystem, RIL */
- #define AID_BLUETOOTH 1002 /* bluetooth subsystem */
- #define AID_GRAPHICS 1003 /* graphics devices */
- #define AID_INPUT 1004 /* input devices */
- #define AID_AUDIO 1005 /* audio devices */
- #define AID_CAMERA 1006 /* camera devices */
- #define AID_LOG 1007 /* log devices */
- #define AID_COMPASS 1008 /* compass device */
- #define AID_MOUNT 1009 /* mountd socket */
- #define AID_WIFI 1010 /* wifi subsystem */
- #define AID_ADB 1011 /* android debug bridge (adbd) */
- #define AID_INSTALL 1012 /* group for installing packages */
- #define AID_MEDIA 1013 /* mediaserver process */
- #define AID_DHCP 1014 /* dhcp client */
- #define AID_SDCARD_RW 1015 /* external storage write access */
- #define AID_VPN 1016 /* vpn system */
- #define AID_KEYSTORE 1017 /* keystore subsystem */
- #define AID_USB 1018 /* USB devices */
- #define AID_GPS 1021 /* GPS daemon */
- #define AID_UNUSED1 1022 /* deprecated, DO NOT USE */
- #define AID_RFU1 1023 /* RFU */
- #define AID_RFU2 1024 /* RFU */
- #define AID_NFC 1025 /* nfc subsystem */
- #define AID_SHELL 2000 /* adb and debug shell user */
- #define AID_CACHE 2001 /* cache access */
- #define AID_DIAG 2002 /* access to diagnostic resources */
- /* The 3000 series are intended for use as supplemental group id's only.
- * They indicate special Android capabilities that the kernel is aware of. */
- #define AID_NET_BT_ADMIN 3001 /* bluetooth: create any socket */
- #define AID_NET_BT 3002 /* bluetooth: create sco, rfcomm or l2cap sockets */
- #define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */
- #define AID_NET_RAW 3004 /* can create raw INET sockets */
- #define AID_NET_ADMIN 3005 /* can configure interfaces and routing tables. */
- #define AID_MISC 9998 /* access to misc storage */
- #define AID_NOBODY 9999
- #define AID_APP 10000 /* first app user */
可知
- AID_SYSTEM 1000 /* system server */
- AID_SDCARD_RW 1015 /* external storage write access */
- AID_APP 10000 /* first app user */
每个 apk 安装时 PackageInstaller 都会分配一个 userid
并记录在
- # ls
- accounts.db packages.xml
- appwidgets.xml password.key
- batterystats.bin registered_services
- called_pre_boots.dat shared_prefs
- cameraCalFile.bin sync
- confirmed_package_behavior.authz theme
- confirmed_package_behavior.log throttle
- customized_icons_1 trafficstats.bin
- device_policies.xml uiderrors.txt
- dropbox usagestats
- entropy.dat wallpaper_info.xml
- gesture.key wallpapers
- packages.list
- # pwd
- /data/system
- #
package.xml中,同时也包含 uses-permission 信息
- <package name="com.pathfindeng.test" codePath="/data/app/com.pathfindeng.test-1.apk" nativeLibraryPath="/data/data/com.pathfindeng.test/lib" flags="268435456" ft="134eed493a0" it="134eeba07a2" ut="134eed49801" version="1" userId="10137">
- <sigs count="1">
- <cert index="34" />
- </sigs>
- <perms>
- <item name="android.permission.WRITE_EXTERNAL_STORAGE" />
- </perms>
查看 data/data/app目录
- # pwd
- /data/data
- # cd com.pathfindeng.test
- # ls -al
- drwxr-x--x 4 app_137 app_137 4096 Jan 18 11:20 .
- drwxrwx--x 175 system system 12288 Jan 18 10:51 ..
- drwxr-xr-x 2 system system 4096 Jan 18 11:20 lib
- drwxrwx--x 2 app_137 app_137 4096 Jan 18 10:51 shared_prefs
- # cd shar*
- # ls -al
- drwxrwx--x 2 app_137 app_137 4096 Jan 18 10:51 .
- drwxr-x--x 4 app_137 app_137 4096 Jan 18 11:20 ..
- -rw-rw---- 1 app_137 app_137 112 Jan 18 10:51 MODE_APPEND.xml
- -rw-rw---- 1 app_137 app_137 113 Jan 18 10:51 MODE_PRIVATE.xml
- -rw-rw-r-- 1 app_137 app_137 120 Jan 18 10:51 MODE_WORLD_READABLE.xml
- -rw-rw--w- 1 app_137 app_137 121 Jan 18 10:51 MODE_WORLD_WRITEABLE.xml
可以看出应用id 为137 其实为 10137. 及该用户权限,所属组权限。
该应用主要代码,及manifest文件
AppRightActivity.java
- package com.pathfindeng.test;
- import java.io.File;
- import java.io.IOException;
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.os.Bundle;
- import android.os.Environment;
- import android.util.Log;
- import android.widget.Toast;
- public class AppRightActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- setSharedPreferencesData();
- }
- public void setSdcardData(){
- File sdcard = Environment.getExternalStorageDirectory();
- String[] fileNames = sdcard.list();
- Log.d("pathfindeng","fileNames.length is "+fileNames.length);
- File testRight = new File(sdcard, "fileForTestRight.txt");
- if(testRight.exists()){
- testRight.delete();
- Log.d("pathfindeng","delete file ok");
- }else{
- try {
- testRight.createNewFile();
- Log.d("pathfindeng","create file ok");
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- Log.d("pathfindeng", testRight.canRead()+""+testRight.canWrite()+""+testRight.canExecute());
- }
- public void setSharedPreferencesData (){
- SharedPreferences mSharedPreferences;
- Editor mEditor;
- //
- mSharedPreferences = getSharedPreferences("MODE_PRIVATE",MODE_PRIVATE);
- mEditor = mSharedPreferences.edit();
- mEditor.putString("right", "MODE_PRIVATE");
- mEditor.commit();
- //
- mSharedPreferences = getSharedPreferences("MODE_WORLD_READABLE",MODE_WORLD_READABLE);
- mEditor = mSharedPreferences.edit();
- mEditor.putString("right", "MODE_WORLD_READABLE");
- mEditor.commit();
- //
- mSharedPreferences = getSharedPreferences("MODE_WORLD_WRITEABLE",MODE_WORLD_WRITEABLE);
- mEditor = mSharedPreferences.edit();
- mEditor.putString("right", "MODE_WORLD_WRITEABLE");
- mEditor.commit();
- //
- mSharedPreferences = getSharedPreferences("MODE_APPEND",MODE_APPEND);
- mEditor = mSharedPreferences.edit();
- mEditor.putString("right", "MODE_APPEND");
- mEditor.commit();
- }
- /* (non-Javadoc)
- * @see android.app.Activity#onResume()
- */
- @Override
- protected void onResume() {
- // TODO Auto-generated method stub
- super.onResume();
- setSdcardData();
- }
- /* (non-Javadoc)
- * @see android.app.Activity#onDestroy()
- */
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- }
- }
manifest.xml
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.pathfindeng.test"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="10" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:label="@string/app_name"
- android:name=".AppRightActivity" >
- <intent-filter >
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
继续查看
/gingerbread/frameworks/base/data/etc/platform.xml
- <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
- <group gid="sdcard_rw" />
- </permission>
应用申请
- WRITE_EXTERNAL_STORAGE
即拥有
- sdcard_rw
所以即可解答开篇提出的问题。