Android查看应用数据或者跨进程查看和访问数据

一、”/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跨进程访问

参考文章:

Android如何通过shareduserid获取系统权限

利用run-as命令在不root情况下读取data下面的数据

Android开发使用run-as获取应用数据

欢迎关注微信公众号:DroidMind
精品内容独家发布平台


呈现与博客不一样的技术干货

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值