写sdcard的权限,
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
很多时候可能会因为忘记这个调半天代码
另外要说的是,各个版本的sdcard的根目录不同,可以通过这个获取
File sdcard = Environment.getExternalStorageDirectory().getAbsoluteFile();
String mLocalExternalPath = sdcard.getAbsolutePath();
如果是写到手机本身存储的话,权限是
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.WRITE_OWNER_DATA" />
这个目前知道好像只能写到自己所在的包下面,也就是只能在自己的包下面来创建文件,但是可以去改写已经存在的文件
没什么变态的需求的话可以放到这个路径或者创建一个其子目录下面
/data/data/<pkg name>/files
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//http://seya.iteye.com/blog/897549
//转载一篇文章
通常情况下我们可以把从网络上下载的数据存放在SD卡上,只要在AndroidManifest.xml中加入<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>的权限就可以了。这样写到SD卡上的文件也可以被其他应用程序访问。
但是有的时候,我们在没有SD卡的情况下也要保持应用正常工作,可以把文件存放在该应用的data目录下(/data/data/com.aaa.yourpackage/)。通过代码来实现:
File mediaFilesDir = mContext.getDir("mediaFiles", Context.MODE_WORLD_READABLE);
这样会在/data/data/com.aaa.yourpackage/目录下创建一个名为app_mediaFiles的目录,然后可以在这个目录下创建新的文件。这样创建出来的文件与在SD卡上创建出来的有一个很大的区别,就是权限。其他应用程序无法像加个permission来访问SD卡上的文件一样来访问我们在当前应用下创建的这个文件。那么怎么办呢。我们知道,android提供了一个SharedPreference,也是在自己的当前应用data目录下创建的一个xml文件,但是它是可以设置权限的,MODE_PRIVATE, MODE_WORLD_READABLE, MODE_WORLD_WRITABLE. 这说明我们是可以去设置创建出来的文件的权限的,就需要去查看SharedPreference是如何实现对权限的设置的了。经过对源码的一番挖掘,发现原来在frameworks/base/core/java/android/app下面的ContextImpl中提供了这个方法来实现的:
private static void setFilePermissionsFromMode(String name, int mode,
int extraPermissions) {
int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
|FileUtils.S_IRGRP|FileUtils.S_IWGRP
|extraPermissions;
if ((mode&MODE_WORLD_READABLE) != 0) {
perms |= FileUtils.S_IROTH;
}
if ((mode&MODE_WORLD_WRITEABLE) != 0) {
perms |= FileUtils.S_IWOTH;
}
if (DEBUG) {
Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
+ ", perms=0x" + Integer.toHexString(perms));
}
FileUtils.setPermissions(name, perms, -1, -1);
}
这里的参数表中的mode就是我们在获取SharedPreference时传过去的mode(MODE_PRIVATE, MODE_WORLD_READABLE, MODE_WORLD_WRITABLE). 原来是用了FileUtils提供的静态方法 setPermissions()来设置的。这是一个native的方法,在对应的c++那边去实现了。
我们把setFilePermissionsFromMode稍微改造如下:
public static void setFilePermissionsFromMode(String name, int mode) {
int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
|FileUtils.S_IRGRP|FileUtils.S_IWGRP;
if ((mode&Context.MODE_WORLD_READABLE) != 0) {
perms |= FileUtils.S_IROTH;
}
if ((mode&Context.MODE_WORLD_WRITEABLE) != 0) {
perms |= FileUtils.S_IWOTH;
}
FileUtils.setPermissions(name, perms, -1, -1);
}
这样就可以去设置文件的权限了。注意这里说的是设置,不是修改。也就是说只能在第一次创建这个文件的时候,就要把权限设置好。如果等文件创建好,再去设置权限,是无法实现的。这个和SharedPreference创建文件时的权限设置道理是一样的。如下代码:
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file.getPath());
//change file permission, so Message is able to access this file.
MyUtil.setFilePermissionsFromMode(file.getPath(), Context.MODE_WORLD_READABLE);
fos.write(bs);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try
{
fos.close();
}
catch (IOException e)
{
e.printStackTrace();
handleErrorMessage(e);
}
}
}
如果我们把
MyUtil.setFilePermissionsFromMode(file.getPath(), Context.MODE_WORLD_READABLE);
放在fos.close()之后写,是无法设置该文件的权限的。
还有种更直接的方式,Context对象提供了openFileOutput(filename, mode); 作用于上文类似。
//-------------------------------------------------------------------------------------------------------
2010.10.24
参考http://blog.csdn.net/sodino/article/details/6549082
可以通过linux下的命令行来改变一个文件的读写执行的权限
chmod xxx /data/data/xxx
文件权限:chmod (change Mode) sudo chmod -R 666
sudo chmod 664 file
(7 4+2+1 rwx)
(6 4+2+0 rw_)
(5 4+0+1 r_x)
(4 4+0+0 r__)
(3 0+2+1 _wx)
(2 0+2+0 _w_)
(1 0+0+1 __r)
(0 0+0+0 ___)
//显示详情
ls -l
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是最不需要耗费脑细胞的)的权限分配详情如下为:
- 可安装
- # cd /data/data/lab.sodino.downloadbreak
- cd /data/data/lab.sodino.downloadbreak
- # ls -l
- ls -l
- drwx-----x app_38 app_38 2011-06-16 08:33 apps
- drwxr-xr-x system system 2011-06-16 08:31 lib
- # ls -l apps
- ls -l apps
- -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()开头处新增如下代码:
- // [文件夹705:drwx---r-x]
- String[] args1 = { "chmod", "705", RES_LOAD_FOLDER };
- exec(args1);
- // [文件604:-rw----r--]
- String[] args2 = { "chmod", "604", RES_LOAD_FOLDER + bean.name };
- exec(args2);
执行Linux命令的exec()方法实现如下:
- /** 执行Linux命令,并返回执行结果。 */
- public static String exec(String[] args) {
- String result = "";
- ProcessBuilder processBuilder = new ProcessBuilder(args);
- Process process = null;
- InputStream errIs = null;
- InputStream inIs = null;
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int read = -1;
- process = processBuilder.start();
- errIs = process.getErrorStream();
- while ((read = errIs.read()) != -1) {
- baos.write(read);
- }
- baos.write('/n');
- inIs = process.getInputStream();
- while ((read = inIs.read()) != -1) {
- baos.write(read);
- }
- byte[] data = baos.toByteArray();
- result = new String(data);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (errIs != null) {
- errIs.close();
- }
- if (inIs != null) {
- inIs.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (process != null) {
- process.destroy();
- }
- }
- return result;
- }