安卓学习笔记:安卓11访问/读写 Android/data 目录

这篇具有很好参考价值的文章主要介绍了安卓学习笔记:安卓11访问/读写 Android/data 目录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

省流提示:采用android studio工具开发,记录一次低级的开发,避免以后忘记或者踩坑。


  • 最近有个业余项目开发到一小半,过程中需要读写 Android/data目录的文件,采用常规的文件操作总是提示权限被拒绝,无奈上网参考了很多资料,终于得到了解决。

  • 无法访问Android/data 的原因

  • 安卓11谷歌采用了文件沙盒存储模式,这就导致我的app无法直接访问android/data目录,即使我在清单文件中加了所有文件的读写权限、在程序中动态申请了所有文件的读写权限。当然如果有root权限那就另当别论了。

  • 作为开发者该如何访问Android/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" />
  1. 在java中动态申请:MainActivity.java的onCreate()周期中:

  
if (Build.VERSION.SDK_INT >= 23) {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(this,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框,这里就不展示了,可以自己写个申请权限的弹窗
          
            }
  1. 做完上面两步,接下来就是申请android/data的权限了,这里说明一下我的情况:

  1. 我的主页就一个:mainactivity,全部采用了动态替换Fragment的方法切换页面,而且需要申请特殊权限的还是fragment中的子framgent,这就需要在他们所依赖的activity中重写回调方法,并设置给fragment,然后通过这个fragment再次设置给子fragment。

  1. 在子fragment中某个按钮的点击事件中去调用SAF框架(Android Storage Access Framework),这个框架据说在4.4就引入了,可以自行百度了解。

  1. 获取Android/data的权限:子fragment中:

//在某个按钮的点击事件中:
 @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.xxxx:
                //把需要授权的目录转为Uri
                Uri uri = DocumentFileUtil.pathToUri("/storage/emulated/0/Android/data");
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
                intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI,uri1);
                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                         | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                         | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
                //这里的第二个参数是标志的意思,用来判断是谁把结果回调过来的。
               requireActivity().startActivityForResult(intent, 1001);
            break;
        }
}
  1. 这时候会调出这个页面:

android/data,android,android studio,Powered by 金山文档
  1. 在点击授权后,程序会返回到MainActivity,所以要在这个活动中重写onActivityResult:

     @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        //把onActivityResult设置fragment
        Fragment f = getSupportFragmentManager().findFragmentByTag("HOME_FRAGMENT");
        assert f != null;
        f.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case 1001:
                if (resultCode == Activity.RESULT_OK) {
                    //固定永久权限,否则当重启app时权限就没有了
                    assert data != null;
                    getContentResolver().takePersistableUriPermission(data.getData(),
                            Intent.FLAG_GRANT_READ_URI_PERMISSION
                                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

                }

                break;

            default:
                break;
        }
  1. 通过activity设置onActivityResult给framgent后,如果子fragment也需进行相关操作,则需要通过父fragment再把onActivityResult设置给子framgent。这里有一点需注意,当我们的子fragment是父fragment通过viewPager容器添加进去的时候,没有Tag也没有ID,如何精准的设置给需要的这个回调的子fragment呢?

  1. 如果适配器是继承的FragmentStatePagerAdapter,这就要用到fragment适配器的instantiateItem了。具体做法:在父fragment中寻找没有tag和id的子fragment:

  @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //实例化适配器
        MyFragmentAdapter fragmentAdapter = (MyFragmentAdapter) vp.getAdapter();
        assert fragmentAdapter != null;
        //通过子fragment在viewPager的position来定位。
        UpDataMsgFragment fragment = (UpDataMsgFragment) fragmentAdapter.instantiateItem(vp, 1);
        //设置
        fragment.onActivityResult(requestCode, resultCode, data);
}
  1. 这样一来子fragment就有了回调,然后看他何如使用:

//回调事件,可以得到上个活动或fragment返回的结果
    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //判断文件是否存在 DocumentFile
        switch (requestCode) {
            case 6666:
                if (resultCode == Activity.RESULT_OK) {
                    //persist uri
                    //固定永久权限
                    assert data != null;
                    requireActivity().getContentResolver().takePersistableUriPermission(data.getData(),
                            Intent.FLAG_GRANT_READ_URI_PERMISSION
                                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    Log.i("回调事件:", "Access persist uri permission to Android/data");
                }
        }
}
  1. 此时子fragment就有了回调结果,可以通过Document来操作andriod/data的文件了

  1. 注意:用户可以随时取消你的data访问权限,所以避免闪退,还需要在用到Document的地方寄一个判断有无相关目录的权限。

 public boolean isHaveAndroidDataGrant(Context context) {
        boolean b = true;
        for (UriPermission persistedUriPermission : context.getContentResolver().getPersistedUriPermissions()) {
            b = persistedUriPermission.getUri().toString().equals("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata");
                //这里的content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata不渴随意更改里面的%3Ahe %2F字符,可按此格式自行拼接需要的目录。
        }
        return  b;
    }

总结:先在清单文件申请权限,然后在程序中动态申请,其次在需要授权的activity(或fragment)中启用SFA框架,最后在回调回来的activity中重写onActivityResult,如果是多层嵌套的fragment,则通过tag或id或position找到对应的fragment,一层一层的传递过去。文章来源地址https://www.toymoban.com/news/detail-647355.html

到了这里,关于安卓学习笔记:安卓11访问/读写 Android/data 目录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android 11后文件读写访问权限申请

    android 11后对文件读写访问权限管理 与 android 10又有了新的要求,导致在读写或者访问时出现error:java.io.FileNotFoundException: /storage/emulated/0/file_path open failed: EACCES (Permission denied),以下为android 11文件管理权限申请办法 回忆android 10 文件访问权限申请 step 1: AndroidManifest中添加权限申

    2024年02月05日
    浏览(47)
  • Android 11 访问 Android/data/或者getExternalCacheDir() root方式

    前言 : 需求要求安装三方应用ExternalCacheDir()下载下来的apk文件。 getExternalCacheDir() : /storage/emulated/0/Android/data/com. . /cache/ 获取访问权限 如果手机安卓版本为Android10的时候,可以在AndroidManifest.xml中添加下列代码 以此禁用分区存储,但这在Android11及以上版本不起作用。 root方式 (

    2024年02月21日
    浏览(43)
  • 手机无法访问”xxx”目录(Android 11及以上授予文件管理权限)的解决方法

    Android11改变了此前安卓系统对文件管理的规则,在Android11上,文件读写变成了特殊权限。应用默认只能读写自己的目录/android/data/包名,这就导致我们想修改某个文件里的内容,结果却没有读写权限。本文主要提供一种解决方法——root+adb。 进入adb+ROOT权限开启 我们进入 adb s

    2024年02月16日
    浏览(61)
  • MAC访问MySQL下的data目录

    1.查看创建表存储路径 2.快捷键com+shift+G,输入查询到的地址 3.终端输入 然后输入密码即可  

    2024年02月12日
    浏览(35)
  • android 高版本sd卡目录读写权限

    1、从安卓11不允许访问sd目录,官方说明如下: https://developer.android.com/about/versions/11/privacy/storage?hl=zh-cn 2、使用MediaStore方法 一手遮天 Android - 存储: Android 11 通过 MediaStore 管理文件 - webabcd - 博客园 (cnblogs.com)  3、关于权限的文章 (31条消息) Android 10、11分区存储适配踩坑总结_安

    2024年02月15日
    浏览(44)
  • 安卓Android studio读写EM4305卡源码

    本示例使用的发卡器: https://item.taobao.com/item.htm?id=718720660087spm=a1z10.5-c.w4002-21818769070.15.57dc6f89txUhXE 源码下载:AndroidstudioRFIDNFC读写源码资源-CSDN文库

    2024年01月19日
    浏览(42)
  • Android Studi安卓读写NDEF智能海报源码

    本示例使用的发卡器:https://item.taobao.com/item.htm?id=615391857885spm=a1z10.5-c.w4002-21818769070.11.1f60789ey1EsPH 源码下载:AndroidstudioRFIDNFC读写源码资源-CSDN文库

    2024年01月18日
    浏览(50)
  • Android Studio安卓读写NFC Ntag标签源码

    本示例使用的发卡器:  https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-21818769070.11.3513789erHXVGxid=615391857885 源码下载:AndroidstudioRFIDNFC读写源码资源-CSDN文库 

    2024年01月15日
    浏览(44)
  • 安卓Android Studio读写MifareOne M1 IC卡源码

    本示例使用的发卡器: https://item.taobao.com/item.htm?id=615391857885spm=a1z10.5-c-s.w4002-21818769070.11.3d2f789eOUPJBK 源码下载:AndroidstudioRFIDNFC读写源码资源-CSDN文库

    2024年02月01日
    浏览(41)
  • android免root读写u盘最新方法,支持安卓Q+

    本人是在写一个app需要读取u盘文件列表,网上找了好多方法,要不就是没有media权限,要不就是收不到广播,全部用不了,就这样搁置了一段时间终于又找到了一个大佬的方法,在这做个笔记 谷歌从Android5.0以上已经不支持开发者随便读写手机的外部存储(包含tf卡、otg外接

    2023年04月16日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包