需求:使用一个写数据应用在/data/data/包名/files对应目录下创建四个文件,分别是私有,只读,只写,可读可写文件;然后用另一个应用去读和写上面四个文件
这里涉及到安卓下创建对应权限的文件的一个方法:openFileOutput(String filename,int mode),第一个参数是文件名,这个文件名是不可以带目录"/"的,因为该方法默认创建文件在/data/data/包名/files目录下,第二个参数是设定文件的读写权限,有这么三种权限:Context.MODE_PRIVATE,Context.MODE_WORLD_READABLE,Context.MODE_WORLD_WRITEABLE,其中除了Context.MODE_PRIVATE之外,另外两个都已经过时了,其实也可以想象,如果一个文件创建出来全世界都可以读或者写的话简直是一个天大的漏洞,这里面可以做很多文章。。,anyway这里只是拿过来用一下,看看演示效果
关于Android下的文件权限,实际上是继承自Linux下的文件权限的安排,我们可以进入adb-shell下使用ls-l来查看文件列表以及其对应的权限。
与Linux下一样,Android下的权限表示也是:rwx的形式。使用ls-l命令查看出来的权限一共有10位:
① ②③④ ⑤⑥⑦ ⑧⑨⑩
其中,第1位表示文件的类型:d 表示文件夹,- 表示文件,l 表示某种挂载的链接
第2~4位表示当前用户的权限也就是文件创建者的权限,用rwx来表示,r代表有读权限,w代表有写权限,x代表有执行权限,而 - 则代表不具备当前权限,如:rwx代表具有可读可写可执行权限,而r-x就代表可读不可写可执行,以此类推;并且这种权限也可以每三位使用二进制数的值来表示,如果某位有权限就代表1,那么rwx就代表二进制的111,就可以用十进制的7来表示,对应的r--就可以表示为4
第5~7位表示当前用户所在组的其他组员的权限,也是用rwx来表示
第8~10位表示其他所有人的权限,同样用rwx来表示,也可以用数字来表示
那么如果三类用户都是满权限的话,可以使用777来表示,也就代表着rwx rwx rwx
第一个应用写入数据,那么也不需要界面,直接在onCreate方法里实现,代码如下:
package com.alexchen.writepermission;
import java.io.FileOutputStream;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
writeToData();
finish();
}
private void writeToData() {
FileOutputStream ofo = null;
try {
// openFileOutput的第一个参数是文件名,该参数不允许出现/直接创建在/data/data/包名/files目录下,第二个参数是文件权限模式,
// 私有文件
ofo = openFileOutput("pri.txt", Context.MODE_PRIVATE);
ofo.write("这是私有文件,读取成功".getBytes());
ofo.flush();
// 只读文件
ofo = openFileOutput("r.txt", Context.MODE_WORLD_READABLE);
ofo.write("这是只读文件,读取成功".getBytes());
ofo.flush();
// 只写文件
ofo = openFileOutput("w.txt", Context.MODE_WORLD_WRITEABLE);
ofo.write("这是只写文件,读取成功".getBytes());
ofo.flush();
// 可读可写文件
ofo = openFileOutput("r&w.txt", Context.MODE_WORLD_READABLE
| Context.MODE_WORLD_WRITEABLE);
ofo.write("这是可读可写文件,读取成功".getBytes());
ofo.flush();
ofo.close();
Toast.makeText(this, "创建文件完毕", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "创建文件失败", Toast.LENGTH_SHORT).show();
}
}
}
第二个应用用来读取第一个应用创建的四个文件:
package com.alexchen.readpermission;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private FileInputStream fis;
private FileOutputStream fos;
private int len;
private byte[] buffer;
// private String content;
private StringBuffer sb;
private TextView tvPrivate;
private TextView tvRead;
private TextView tvWrite;
private TextView tvRW;
private String path = "/data/data/com.alexchen.writepermission/files/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvPrivate = (TextView) findViewById(R.id.tv_p);
tvRead = (TextView) findViewById(R.id.tv_r);
tvWrite = (TextView) findViewById(R.id.tv_w);
tvRW = (TextView) findViewById(R.id.tv_rw);
}
public void rpClick(View v) {
tvPrivate.setText(readFromData(path + "pri.txt"));
}
public void wpClick(View v) {
writeToData(path + "pri.txt");
}
public void rrClick(View v) {
tvRead.setText(readFromData(path + "r.txt"));
}
public void wrClick(View v) {
writeToData(path + "r.txt");
}
public void rwClick(View v) {
tvWrite.setText(readFromData(path + "w.txt"));
}
public void wwClick(View v) {
writeToData(path + "w.txt");
}
public void rrwClick(View v) {
tvRW.setText(readFromData(path + "r&w.txt"));
}
public void wrwClick(View v) {
writeToData(path + "r&w.txt");
}
public String readFromData(String fileName) {
String content = "";
fis = null;
try {
fis = new FileInputStream(fileName);
len = 0;
buffer = new byte[1024];
sb = new StringBuffer("");
while ((len = fis.read(buffer)) != -1) {
sb.append(new String(buffer));
}
content = sb.toString().trim();
Toast.makeText(this, "读取" + fileName + "成功", Toast.LENGTH_SHORT)
.show();
return content;
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "读取" + fileName + "失败", Toast.LENGTH_SHORT)
.show();
return content;
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void writeToData(String fileName) {
fos = null;
try {
fos = new FileOutputStream(fileName);
switch (fileName) {
case "/data/data/com.alexchen.writepermission/files/pri.txt":
fos.write("私有文件被写入成功".getBytes());
fos.flush();
break;
case "/data/data/com.alexchen.writepermission/files/r.txt":
fos.write("只读文件被写入成功".getBytes());
fos.flush();
break;
case "/data/data/com.alexchen.writepermission/files/w.txt":
fos.write("只写文件被写入成功".getBytes());
fos.flush();
break;
case "/data/data/com.alexchen.writepermission/files/r&w.txt":
fos.write("可读可写文件被写入成功".getBytes());
fos.flush();
break;
default:
break;
}
Toast.makeText(this, "写入成功", 0).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "写入失败", 0).show();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
这个应用需要一个界面,对应的布局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp"
tools:context="${relativePackage}.${activityClass}" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:padding="1dp" >
<TextView
android:id="@+id/tv_p"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="rpClick"
android:text="读取私有文件" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="wpClick"
android:text="写入私有文件" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:padding="1dp" >
<TextView
android:id="@+id/tv_r"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="rrClick"
android:text="读取只读文件" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="wrClick"
android:text="写入只读文件" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:padding="1dp" >
<TextView
android:id="@+id/tv_w"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="rwClick"
android:text="读取只写文件" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="wwClick"
android:text="写入只写文件" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:padding="1dp" >
<TextView
android:id="@+id/tv_rw"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="rrwClick"
android:text="读可读写文件" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="wrwClick"
android:text="写可读写文件" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
界面如图所示:
如同权限描述一样,只有可读和可读可写文件可以被其他应用读取,也只有可写和可读可写文件可以被其他应用写,而私有文件(private)既不可以被别的应用读也不可以被别的应用写入数据