精华内容
下载资源
问答
  • 安卓不root访问data目录文件

    万次阅读 2017-05-10 13:39:42
    一般情况下,我们调试程序的时候,需要查看程序的一些数据,我们会想到使用adb命令来完成,可能你会...shell@QK1505_A01:/ $ cd /data shell@QK1505_A01:/data $ ls opendir failed, Permission denied 255|shell@QK1
    一般情况下,我们调试程序的时候,需要查看程序的一些数据,我们会想到使用adb命令来完成,可能你会这样来访问:
    
    • 直接访问
    C:\Users\Wihatow\Desktop>adb shell
    shell@QK1505_A01:/ $ cd /data
    shell@QK1505_A01:/data $ ls
    opendir failed, Permission denied
    255|shell@QK1505_A01:/data $
    然而,并没有什么卵用,没有访问权限。但是,如果手机已经root了,你可以输入:
    su命令来获取root权限,然后在手机上选择同意,然后在输入上面的命令就可以访问数据了。
    但是,大多数情况下,我们的设备是没有root过的,那么又该如果才能在不root的情况下查看程序数据呢?
    
    • 如果你这样来访问,你会发现可以读取程序数据了:

    1、首先你需要在manifest文件中添加debuggable,如图所示:

    这里写图片描述

    2、然后按照如下方式进行访问:

    
    C:\Users\Wihatow\Desktop>adb shell
    shell@QK1505_A01:/ $ run-as com.hhwy.ydOA
    shell@QK1505_A01:/data/data/com.hhwy.ydOA $ ls
    app_outdex
    cache
    code_cache
    files
    lib
    program_cache
    qt-reserved-files
    shared_prefs
    shell@QK1505_A01:/data/data/com.hhwy.ydOA $

    正如上面你所看到的,能够访问程序数据了。

    展开全文
  • Android11 无Root 访问data目录实现、Android11访问data目录、Android11解除data目录限制、Android11 data空白解决、SAF文件访问框架

    正文开始

    关于Android11权限变化

    谷歌在Android11及以上系统中采用了文件沙盒存储模式,导致第三方应用无法像以前一样访问Android/data目录,这是好事。但是我所不能理解的是已经获得"所有文件管理"权限的APP为何还是限制了,岂不是完全不留给清理、文件管理类软件后路?实在不应该!

    作为普通安卓用户该如何方便快速地访问Android/data目录

    众所周知,不能访问Android/data目录非常不方便,比如要管理QQ、微信接收到的文件、其他App下载的数据(如迅雷等等)。

    现本人开发的应用已实现无Root访问Android/data目录(其中文件浏览器功能),并且可以方便地进行管理。

    https://www.coolapk.com/apk/com.magicalstory.cleaner

    软件下载

    欢迎安卓手机用户下载使用 和 Android开发者下载预览功能的实现。

    App界面预览
    在这里插入图片描述

    开发者该如何实现无ROOT访问Data目录

    1.首先,可根据需要获取所有文件管理权限:
    在清单中声明:

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission
            android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
            tools:ignore="ScopedStorage" />
    

    2.动态获取读写权限,这个不用多说了吧,如果觉得麻烦可以使用郭霖大神的permissionX库
    Github

    关于"管理所有文件"权限
    这个权限可以让你的App跟Android11以前一样,通过File API访问所有文件(除Android/data目录)

    如有需要,请在清单声明不启用沙盒存储

            android:preserveLegacyExternalStorage="true"
            android:requestLegacyExternalStorage="true"
    

    相关判断

       //判断是否需要所有文件权限
                if (!(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager())) {
                //表明已经有这个权限了
                }
    

    获取权限

      Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                startActivity(intent);
    

    正式开始解决Android/data问题

    首先,使用的方式是SAF框架(Android Storage Access Framework)
    这个框架在Android4.4就引入了,如果没有了解过的话,可以百度。

    获取某个文件目录的权限

    方法很简单,使用android.intent.action.OPEN_DOCUMENT_TREE(调用SAF框架的文件选择器选择一个文件夹)的Intent就可以授权了
    等下会放出工具类,现在看下例子:

    //获取指定目录的访问权限
     public static void startFor(String path, Activity context, int REQUEST_CODE_FOR_DIR) {
            statusHolder.path = path;//这里主要是我的一个状态保存类,说明现在获取权限的路径是他,大家不用管。
            String uri = changeToUri(path);//调用方法,把path转换成可解析的uri文本,这个方法在下面会公布
            Uri parse = Uri.parse(uri);
            Intent intent = new Intent("android.intent.action.OPEN_DOCUMENT_TREE");
            intent.addFlags(
                    Intent.FLAG_GRANT_READ_URI_PERMISSION
                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                            | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
                            | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, parse);
            }
            context.startActivityForResult(intent, REQUEST_CODE_FOR_DIR);//开始授权
        }
    

    调用后的示意图:
    在这里插入图片描述

    回调并永久保存某个目录的权限

        //返回授权状态
        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            Uri uri;
    
            if (data == null) {
                return;
            }
    
            if (requestCode == REQUEST_CODE_FOR_DIR && (uri = data.getData()) != null) {
                getContentResolver().takePersistableUriPermission(uri, data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION));//关键是这里,这个就是保存这个目录的访问权限
                PreferencesUtil.saveString(MainActivity.this, statusHolder.path + "授权", "true");//我自己处理的逻辑,大家不用管
    
            }
    
        }
    
    

    权限授权并永久保存成功
    在这里插入图片描述

    通过DocumentFile Api访问目录

    使用起来非常简单
    先看看怎么生成DocumentFile对象

    DocumentFile documentFile = DocumentFile.fromTreeUri(context, Uri.parse(fileUriUtils.changeToUri3(path)));
    //changeToUri3方法是我封装好的方法,后面会用到,这个是通过path生成指定可解析URI的方法
    

    真所谓有手就行,调用DocumentFile.fromTreeUri()方法就可以了,这个方法说的是从一个文件夹URI生成DocumentFile对象(treeUri就是文件夹URI)

    当然还有其他方法:
    DocumentFile.fromSingleUri();
    DocumentFile.fromFile();
    DocumentFile.isDocumentUri();

    看名字就明白了,但是我们有的的是一个文件夹uri,当然使用这个方法来生成DocumentFile对象,不同方法生成的DocumentFile对象有不同效果,如果你用fromTreeUri生成的默认是文件夹对象,有ListFiles() 方法
    DocumentFile.ListFiles()也就是列出文件夹里面的全部子文件,类似于File.listFiles()方法

    然后就这样啊,得到了DocumentFile对象就可以进行骚操作了啊,比如列出子文件啊,删除文件啊,移动啊,删除啊什么的都可以,没错,Android/data目录就是这样进行操作和访问的!

    实现遍历或管理Android/data文件目录

    比较基础,我就不多说啦,简单讲讲实现方案和踩过的坑

    1.遍历,跟普通全遍历没啥差别,但是不能通过直接传入Path进行遍历

    
        //遍历示例,不进行额外逻辑处理
        void getFiles(DocumentFile documentFile) {
            Log.d("文件:", documentFile.getName());
            if (documentFile.isDirectory()) {
                for (DocumentFile file : documentFile.listFiles()) {
                    Log.d("子文件", file.getName());
                    if (file.isDirectory()) {
                        getFiles(file);//递归调用
                    }
                }
                
            }
        }
    

    2.实现文件管理器方案(管理Android/data目录就是这个方案)
    以下仅介绍方法

     class file{
            String title;
            DocumentFile documentFile;
    
            public String getTitle() {
                return title;
            }
    
            public void setTitle(String title) {
                this.title = title;
            }
    
            public DocumentFile getDocumentFile() {
                return documentFile;
            }
    
            public void setDocumentFile(DocumentFile documentFile) {
                this.documentFile = documentFile;
            }
        }
    
        MainActivity{
            //加载数据
            void getFiles(DocumentFile documentFile) {
                ArrayList<file> arrayList = new ArrayList<>();
                if (documentFile.isDirectory()) {
                    for (DocumentFile documentFile_inner : documentFile.listFiles()) {
                        file file = new file();
                        file.setTitle(documentFile_inner.getName());
                        file.setDocumentFile(documentFile_inner);
                    }
                }
            }
            }
        }
    

    当列表被点击了,处理方案:

      public void onclick(int postion){
           file file = arrayList.get(postion);
           getFiles(file.getDocumentFile());//获取该文件夹的document对象,再把该文件夹遍历出来
           //然后再次显示就完事了
       }
    
    

    以上就是模拟实现文件管理器->文件浏览功能,大家应该一目了然,只介绍方案。

    我实现的文件管理(Android11上直接免root管理data目录)
    在这里插入图片描述

    重要的坑:为什么不直接使用路径Path来实现文件浏览呢?

    对呀,很明显使用传统的通过文件的path来实现文件管理岂不是更加方便?
    我也这样觉得的,在我当时在对Android11进行适配的时候为了改动小,肯定是想用这个方法来进行适配,但是根本行不通!

    我们不是获取了Android/data目录的权限了吗? 明明说好的获取该目录的权限后拥有该文件夹及所有子文件的读写权限的!
    我为什么不能直接通过调用changToUri把path转换成uri,再生成DocumentFile对象呢?
    这样岂不是更加方便嘛? 而且SAF的文件效率比File低多了。
    但是试了好几次后,我确定这样是不行的!

    就算你生成的是Android/data目录下子文件的正确URI,再生成DocumentFile对象,还是不行,因为你生成的DocumentFile对象始终指向Android/data(也就是你授权过的那个目录), 无解!

    刚刚开始我还以为是我生成的URI不正确,但是当我尝试再次把我想获取的子目录路径进行文件目录授权后,再用同一个URI生成DocumentFile对象却能指向正正确目录了。

    看到这里大家应该懂了吧,是谷歌对没有授权的子文件夹目录进行了限制,不让你直接通过TreeUri生成正确的Docment对象,至少在Android/data目录是这样的。

    现在是不是觉得谷歌官方解释: 获取该目录的权限后拥有该文件夹及所有子文件的读写权限的!
    是放屁?确实是!

    解决方案

    既然我们不能直接生成不了已授权目录的子目录DocumentFile对象,那我能不能试试直接对应子路径生成DocumentFile对象(非treeUri),我们试试用fromSingleUri()方法:

        //根据路径获得document文件
        public static DocumentFile getDoucmentFile(Context context, String path) {
            if (path.endsWith("/")) {
                path = path.substring(0, path.length() - 1);
            }
            String path2 = path.replace("/storage/emulated/0/", "").replace("/", "%2F");
            return DocumentFile.fromSingleUri(context, Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3A" + path2));
        }
    

    很显然,可以了!可以生成正确的DocumentFile对象了,我们又可以用它来做一些好玩的东西了,比如直接通过path生成DocumentFile对象对某个文件获取大小啊、判断存在状态啊,等等。
    这个Android11上Android/data受限后,我觉得这个是很好的解决方案了,毕竟可以实现无Root访问并实现管理。

    SAF方案缺点

    很显然,通过SAF文件存储框架访问文件,速度和效率远远低于File API,因为SAF本来用途就不是用来解决Android11/data目录文件访问的。

    但是对于一些涉及文件管理类的App来说目前这个算是最全或较优的解决方案了。

    放大招,ROOT权限直接解锁后带权访问Data目录

    通过ROOT权限执行
    "chmod -R 777 /storage/emulated/0/Android/data"
    命令就可以解锁Android/data目录,注意:不可逆。

    至于怎么通过ROOT权限访问目录,就需要参考MT文件管理器或张海大神开源的文件管理器了

    Github
    Github:https://github.com/zhanghai/MaterialFiles

    结语

    以上就是我的解决方案了,已经完全解决Android11系统访问Android/data的问题,有问题可以留言哦,我看到会回复的,如果您有更好的解决的方案请在评论区留言,我会及时更新上去。

    当然,这个方案肯定会有些不如意,但是这已经是没方案中的最好的办法,毕竟谷歌限制不让你访问data目录,我们某些涉及文件管理的应用又确实需要访问,方案亲测可用,我已经按照以上方案在我的app中进行了Android11适配,算是差强人意吧。

    我的App:
    软件下载
    https://www.coolapk.com/apk/com.magicalstory.cleaner
    欢迎各位看官下载体验。

    封装好的工具类

    因为个人项目还在运营不方便把全部代码都开源至GitHub,所以就放出工具类给大家使用吧。
    真的超级简单呀,认真看一遍就可以上手了,都是日常操作,对于各位大佬来说就是有手就行。

    public class fileUriUtils {
        public static String root = Environment.getExternalStorageDirectory().getPath() + "/";
    
        public static String treeToPath(String path) {
            String path2;
            if (path.contains("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary")) {
                path2 = path.replace("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3A", root);
                path2 = path2.replace("%2F", "/");
            } else {
                path2 = root + textUtils.getSubString(path + "测试", "document/primary%3A", "测试").replace("%2F", "/");
    
            }
            return path2;
        }
    
    
        //判断是否已经获取了Data权限,改改逻辑就能判断其他目录,懂得都懂
        public static boolean isGrant(Context context) {
            for (UriPermission persistedUriPermission : context.getContentResolver().getPersistedUriPermissions()) {
                if (persistedUriPermission.isReadPermission() && persistedUriPermission.getUri().toString().equals("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata")) {
                    return true;
                }
            }
            return false;
        }
    
        //直接返回DocumentFile
        public static DocumentFile getDocumentFilePath(Context context, String path, String sdCardUri) {
            DocumentFile document = DocumentFile.fromTreeUri(context, Uri.parse(sdCardUri));
            String[] parts = path.split("/");
            for (int i = 3; i < parts.length; i++) {
                document = document.findFile(parts[i]);
            }
            return document;
        }
    
        //转换至uriTree的路径
        public static String changeToUri(String path) {
            if (path.endsWith("/")) {
                path = path.substring(0, path.length() - 1);
            }
            String path2 = path.replace("/storage/emulated/0/", "").replace("/", "%2F");
            return "content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3A" + path2;
        }
    
        //转换至uriTree的路径
        public static DocumentFile getDoucmentFile(Context context, String path) {
            if (path.endsWith("/")) {
                path = path.substring(0, path.length() - 1);
            }
            String path2 = path.replace("/storage/emulated/0/", "").replace("/", "%2F");
            return DocumentFile.fromSingleUri(context, Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3A" + path2));
        }
    
    
        //转换至uriTree的路径
        public static String changeToUri2(String path) {
            String[] paths = path.replaceAll("/storage/emulated/0/Android/data", "").split("/");
            StringBuilder stringBuilder = new StringBuilder("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3AAndroid%2Fdata");
            for (String p : paths) {
                if (p.length() == 0) continue;
                stringBuilder.append("%2F").append(p);
            }
            return stringBuilder.toString();
    
        }
    
    
        //转换至uriTree的路径
        public static String changeToUri3(String path) {
            path = path.replace("/storage/emulated/0/", "").replace("/", "%2F");
            return ("content://com.android.externalstorage.documents/tree/primary%3A" + path);
    
        }
    
    //获取指定目录的权限
        public static void startFor(String path, Activity context, int REQUEST_CODE_FOR_DIR) {
            statusHolder.path = path;
            String uri = changeToUri(path);
            Uri parse = Uri.parse(uri);
            Intent intent = new Intent("android.intent.action.OPEN_DOCUMENT_TREE");
            intent.addFlags(
                    Intent.FLAG_GRANT_READ_URI_PERMISSION
                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                            | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
                            | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, parse);
            }
            context.startActivityForResult(intent, REQUEST_CODE_FOR_DIR);
    
        }
    
    //直接获取data权限,推荐使用这种方案
        public static void startForRoot(Activity context, int REQUEST_CODE_FOR_DIR) {
            Uri uri1 = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata");
    //        DocumentFile documentFile = DocumentFile.fromTreeUri(context, uri1);
            String uri = changeToUri(Environment.getExternalStorageDirectory().getPath());
            uri = uri + "/document/primary%3A" + Environment.getExternalStorageDirectory().getPath().replace("/storage/emulated/0/", "").replace("/", "%2F");
            Uri parse = Uri.parse(uri);
            DocumentFile documentFile = DocumentFile.fromTreeUri(context, uri1);
            Intent intent1 = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
            intent1.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
            intent1.putExtra(DocumentsContract.EXTRA_INITIAL_URI, documentFile.getUri());
            context.startActivityForResult(intent1, REQUEST_CODE_FOR_DIR);
    
        }
    
    }
    
    
    展开全文
  • 条件: 首先必须是Android Debug签名的应用才可以 adb shell run - as 应用包名 cd / data / data /应用包名

    条件:
    首先必须是Android Debug签名的应用才可以

    adb shell
    run-as 应用包名
    cd /data/data/应用包名
    展开全文
  • 1、查看当前设备 adb devices 2、进入shell命令模式 ...3、查看目录下文件,进入指定包名 没有权限,这时需要对apk进行反编译后在Manifest.xml中加上 android:debuggable="true" 再执行以上步骤 ...

    1、查看当前设备

    adb devices
    

    2、进入shell命令模式

    adb shell
    

    3、查看目录下文件,进入指定包名
    在这里插入图片描述
    没有权限,这时需要对apk进行反编译后在Manifest.xml中加上

    android:debuggable="true"
    

    再执行以上步骤

    展开全文
  • 127|shell@android:/$cd/data cd/data shell@android:/data$ls ls opendirfailed,Permissiondenied ...正确使用adb读取data目录下的文件方式 [plain]view plaincopy shell@android:/data$run-...
  • 不root权限下读取data目录下的文件

    千次阅读 2019-10-21 08:08:58
    ls BookStore.db BookStore.db-journal 按照上图的步骤输入命令之后就可以找到data目录下的数据库了,这里并没有获取root权限,也没有切换超级管理员。安全性很高。接下来就可以用命令行操作数据库了。如下: sqlite...
  • 现在问题是,不rootdata/data目录。 即使我们使用debugable=true并对某个应用重新打包进入调试模式能打开这个应用的目录,但别忘了,VirtualXposed里面应用的目录不是/data/data/com.xxxx,而是/data/data/io....
  • linux-root修改文件权限

    千次阅读 2020-08-14 21:08:20
    现有认知觉得,linux中只要有root,啥都能干,也确实如此,但是在某种情况下,你还能赤裸裸的直接干,干了还。到底是个什么问题呢?Go ahead 问题现象 从上图可以看到,owner 为HwHiAiUser, group 为HwHiAiUser...
  • 如果访问了真机上面的data/ data 数据库文件那么是因为缺少root 权限; 申请root 权限之后如果还不行 可以下载安装个android终端模拟器再试试;
  • 有没有方法在不root手机的情况下读取Data目录下的文件 网上有代码是这样的: public void execMethod(){ String line =""; String args[] = new String[3]; args[0] = "chmod";
  • Android 手机root修改文件系统属性

    千次阅读 2012-10-24 11:09:55
    1. 首先你可以先root手机,如何root...2. root后,如果我们想修改文件系统的属性,如何实现?  实例如下: (1). List current mounted system : mount shell@android:/system/xbin # mount rootfs / roo
  • Android真机获得root权限修改文件权限

    千次阅读 2016-08-23 15:32:30
    好久没有更新博客了,最近因为重装了系统导致所有的配置都存在了,当要修改Android权限去查看数据库文件的时候,发现又忘记了怎么去获得修改权限(其实第一次弄这个内容的时候就费了很大的劲),所以打算记录一下...
  • 原文链接:http://blog.csdn.net/yangzl2008/article/details/8498196 使用adb命令时的错误 如果直接使用adb命令会产生以下错误: ...127|shell@android:/ $ cd /data  cd /data  shell@and
  • android DDMS 连接真机(己ROOT),用file explore无法查看修改data/data文件夹的解决办法: 原因:目录或文件无权限,adb shell命令,但android下的shell是能用-R参数 既使su到root帐号也执行了 简单加...
  • [root@Iuu mysql]# rm -rf dumpback/ rm: 无法删除目录‘dumpback//2011_10_21’: 权限不够 rm: 无法删除目录‘dumpback//2011_09_23’: 权限不够 rm: 无法删除目录‘dumpback//2011_10_14’: 权限不够 rm: 无法删除...
  • 输入adb shell进入真机调试模式 (如果adb命令能使用,首先将platform-...这是data目录可以打开了,可是data目录里面还有一个data,仍然打开 此时继续使用命令chmod 755获得权限:chmod 755 /data/data  ...
  • 我用小米手机做实验获得root权限并修改文件目录权限(手机已被刷机,系统有root权限,知道有没有影响) 1、首先adb shell 进入手机 2、键入命令su获取root权限,获取到的标志是由$符号变成#号 3、键入mount查看...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 725,715
精华内容 290,286
关键字:

不root怎么修改data文件