一、”/data/data/包名” 下面的目录
cache
databases
files
lib
shared_prefs
drwxrwx--x u0_a1971 u0_a1971 2016-10-12 16:05 cache
drwxrwx--x u0_a1971 u0_a1971 2016-10-01 08:33 databases
drwxrwx--x u0_a1971 u0_a1971 2016-10-01 08:33 files
lrwxrwxrwx install install 2016-10-11 08:48 lib
drwxrwx--x u0_a1971 u0_a1971 2016-10-12 16:05 shared_prefs
简单说说Linux中的文件权限构造
drwxrwx–x有十位
第1位表示文件类型,可以为p、d、l、s、c、b和-。
p表示命名管道文件
d表示目录文件
l表示符号连接文件
-表示普通文件
s表示socket文件
c表示字符设备文件
b表示块设备文件
第2-4位表示文件所有者的权限
第5-7位表示同组用户的权限
第8-10位表示其他用户的权限
其形式为rwx:
r表示可读,可以读出文件的内容,对应的数字是4
w表示可写,可以修改文件的内容,对应的数字是2
x表示可执行,可运行这个程序,对应的数字是1
从上面可以看到,其实/data/data/package/lib这个目录是可以直接访问的,也就是说adb shell后虽然无法读取/data目录,但是可以直接访问这个目录下的文件。
Android给每个APK进程分配一个单独的空间,manifest中的userid就是对应一个分配的Linux用户ID,并且为它创建一个沙箱,以防止影响其他应用程序(或者其他应用程序影响它)。如果设备没有root,是无法查看应用的沙盒数据(/data/data/目录内容)的。
二、访问其他应用数据的方法
如果我们希望读取data下面的数据,下面有两种方法:
1、利用run-as命令
前提:manifest中设置android:debuggable=”true”
$ adb shell
$ run-as 包名
$ cd /data/data/包名
2、通过shareduserid
使用同一个shareuserid,多个apk运行到同一个进程,实现多个apk之间的数据访问
例如:B应用把A应用 assets目录下的session.log拷贝到A应用的/data/data/A包名/目录下面
A应用
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demo1"
android:sharedUserId="com.example"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
上面的关键是sharedUserId属性的设置。
下面在B应用中对A应用的数据进行操作
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demo2"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="com.example">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
声明相同的sharedUserId
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Context context = null;
InputStream input = null;
OutputStream output = null;
try {
// 得到A应用的Context
context = this.createPackageContext("com.example.demo1",
Context.CONTEXT_IGNORE_SECURITY);
File file = new File("/data/data/com.example.demo1/session.log");
if (!file.exists()) {
file.createNewFile();
}
//操作A应用的Asset文件
input = context.getAssets().open("session.log");
output = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int readLength = 0;
while((readLength = input.read(buffer)) != -1){
output.write(buffer, 0, readLength);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
if(input!=null || output!= null){
input.close();
output.close();
input = null;
output = null;
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
3、ContentProvider跨进程访问
参考文章:
利用run-as命令在不root情况下读取data下面的数据