Android13关于获取外部存储文件的相关问题及解决方案记录

这篇具有很好参考价值的文章主要介绍了Android13关于获取外部存储文件的相关问题及解决方案记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  Android的学习路上...

  • 测试设备:vivo X90s
  • 安卓版本: Android13
  • 开发环境:AndroidStudio Flamingo
  • SDK:33

最近我在Android13的环境下尝试写一个文件选择器,以便日后的开发使用。但是我们知道,从Android13 (API33) 开始,外部存储权限发生了变化,要想读取外部存储文件,使用原来的权限注册方式已经失效了。

<!--以下方式在安卓13下已失效-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

测试一下:我在test文件夹内有4个文件和1个文件夹。

左图是系统自带的文件选择器,右图是我开发的文件选择器(我是以系统的选择器作为参照的,因此样子长得很像😄)。此时我的文件选择器只注册了 WRITE/READ_EXTERNAL_STORAGE 权限。可以看到,这种方式在Android13中是获取不到文件的,只能获取文件夹。

android 13 manage_external_storage,android
系统自带的文件选择器
android 13 manage_external_storage,android
我开发的文件选择器

这是因为Android13细化了外部存储权限,在我的理解里,Android13把文件分为了媒体文件非媒体文件。媒体文件包括照片视频音频,他们需要各自的权限才能获取。权限声明如下所示(在AndroidManifest.xml中声明后还需动态获取权限):

<!--照片-->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!--视频-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!--音频-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

在上图中,picture.png属于照片文件,video.mp4属于视频文件,music.mp3属于音频文件。而text.pdf就属于非媒体文件了。若现在赋予我的文件选择器媒体文件权限,如下图所示,此时就能看到:picture.png、video.mp4、music.mp3就能被获取了。

android 13 manage_external_storage,android
开启媒体文件权限
android 13 manage_external_storage,android
获取到媒体文件

那除了媒体文件外,其他的比如PDF文件、DOCX文件、TXT文件等等这些非媒体文件应该如何获取呢?其中之一可行的办法就是使用管理所有文件权限

<!--管理所有文件权限-->
<uses-permission
    android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />

 使用此权限时,需要现在AndroidManifest.xml中声明,但不需动态获取权限。而是要跳转到设置页面使用户手动开启权限,跳转代码如下:

// 跳转至设置页面,让用户手动开启
public void setting(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (!Environment.isExternalStorageManager()) {
            Intent intent = new Intent(
                Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            intent.setData(Uri.parse("package:" + activity.getPackageName()));
            activity.startActivity(intent);
        }
    }
}

 设置页面如下左图。手动开启了权限后,就可以获取到其他文件了,如下右图所示。 

android 13 manage_external_storage,android
管理所有文件权限设置页面
android 13 manage_external_storage,android
开启后就能获取到非媒体文件了

开启此权限值得注意的是: 

如果允许了此权限,那么即使应用无“照片与视频”、“音乐与音频”权限,仍可访问、写入、修改和删除所有文件。

 也就是说,如果开启了这个权限,就可以获取所有的文件了(包括媒体文件和非媒体文件),那么媒体文件的权限就算不申请也可以获得权限。

总结:

1.  如果业务需求只获取媒体文件,那么就 AndroidManifest.xml 注册以下权限并动态申请权限。

<!--照片-->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!--视频-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!--音频-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

2. 如果业务需求获取非媒体文件或所有文件,那么就在 AndroidManifest.xml 注册以下权限并跳转至设置页面使用户手动开启权限。

<!--管理所有文件权限-->
<uses-permission
    android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />
// 跳转至设置页面,让用户手动开启
public void setting(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (!Environment.isExternalStorageManager()) {
            Intent intent = new Intent(
                Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            intent.setData(Uri.parse("package:" + activity.getPackageName()));
            activity.startActivity(intent);
        }
    }
}

这是我在开发中尝试的一种可行的方案,如果大家有其他可行的方案欢迎留言。如文章有错误之处,强烈欢迎指正,在下萌新需要多多学习和积累,谢谢啦~文章来源地址https://www.toymoban.com/news/detail-791778.html

到了这里,关于Android13关于获取外部存储文件的相关问题及解决方案记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 关于Android 11、12和13服务保活问题

    物联网环境,为了解决不同厂商、不同设备、不同网络情况下使用顺畅,同时也考虑到节约成本,缩小应用体积的好处,我们需要一个服务应用一直存在系统中,保活它以提供服务给其他客户端调用。 开机自启动,通过广播通信, 必要权限 开机自启动Service相关代码 注意

    2023年04月08日
    浏览(86)
  • 【windows测试通过】关于Godot导入外部音频文件的问题

    代码给出,还没有测试过。(godot3.2测试未通过) 在运行时轻松加载外部音频 (WAV) 文件 ·问题 #732 ·Godotengine/Godot-proposals(戈多引擎) (github.com) 我给出的办法(windos测试通过) 1. 先把外部音频文件在游戏开发的时候导入在godot的res://目录下,然后复制导入后的.imoprt/文件夹

    2024年02月16日
    浏览(35)
  • Android 获取内部存储中音乐文件的正确姿势

    最近想写一个音乐的小APP出来(doge),借此熟悉音频开发的相关技术。但是在获取 内部存储的音乐文件 时踩了一些坑...所以有了这篇帖子,简单介绍下Android的存储类别,以及如何获取内部存储中的音乐文件。 首先要理解一个概念, 内存≠内部存储 。 内存 - 程序运行是内

    2024年02月08日
    浏览(40)
  • android内部存储和外部存储

    我们在开发Android应用的过程中,避免不了要用到数据持久化技术,所谓的数据持久化就是将RAM中的瞬时数据保存到ROM中,保证在App退出或者手机关机后数据不会丢失。我们常用的数据持久化的方式有文件存储,数据库存储,SharedPreference存储等。在window中,当我们存储文件或

    2024年02月09日
    浏览(45)
  • Android外部存储与内部存储详解

    内部储存(内部存储的文件夹其他应用和用户无法直接访问,可以用于存放敏感数据。app进行数据清理或卸载可以清理外部存储和内部存储下的所有文件目录, 不需要读写权限 ) getFilesDir() /data/data/包名/files 或者 /data/user/0/包名/files getCacheDir() /data/data/包名/cache 或者 /data/u

    2024年04月09日
    浏览(60)
  • Android 10-11适配外部存储方案

    Android Api 29 对文件和文件夹进行了重大更改。不允许使用外部存储,如下方法: Environment.getExternalStorageDirectory() = /mnt/sdcard   Environment.getExternalStoragePublicDirectory(“test”) = /mnt/sdcard/test 只能使用内部存储 getExternalFilesDir(“test”) = /mnt/sdcard/Android/data/com.my.app/files/test getExternalF

    2024年02月06日
    浏览(38)
  • Android内部存储与外部存储(私有目录与公共目录)图文详解

        目录 一、存储空间概述 二、存储空间的划分 1、存储划分 2、内部存储 2.1 内部存储概述 2.2 内部存储 - 私有目录 3. 外部存储 3.1 外部存储概述 3.2 外部存储 - 私有目录 3.3 外部存储 - 公共目录 三、内部存储与外部存储比较 1、横向对比 2、目录结构 3、存储分类 四、总结

    2024年02月11日
    浏览(40)
  • 【关于前端打开本地文件夹获取本地文件路径】碰到需要打开本地文件路径,然后选中路径保存问题功能实现

    需要导入const ipcRenderer = require(“electron”).ipcRenderer; 但是必须要选中的文件夹里含有文件,因为是截取的,如果没有文件获取到的就是空的,是无法得到路径的 还是不知道怎么完全写打开一个目录然后保存到此目录。目前选择的目录如果无文件则覆盖不到。

    2024年04月11日
    浏览(84)
  • Android 外部存储与内部存储详解,高级UI都没弄明白凭什么拿高薪

    FileOutputStream fos = new FileOutputStream(path, true); String str = infoEdt.getText().toString(); fos.write(str.getBytes()); } catch (IOException e) { e.printStackTrace(); } break; case R.id.read_btn: try { FileInputStream fis = new FileInputStream(path); byte[] b = new byte[1024]; int len = fis.read(b); String str2 = new String(b, 0, len); txt.setText(str

    2024年04月11日
    浏览(42)
  • Android 13 关于安卓判断通知权限

    判断权限是否开启: public class NoticePermissionUtil {       private static final String CHECK_OP_NO_THROW = \\\"checkOpNoThrow\\\";     private static final String OP_POST_NOTIFICATION = \\\"OP_POST_NOTIFICATION\\\";       //调用该方法获取是否开启通知栏权限     public static boolean isNotifyEnabled(Context context) {        

    2023年04月13日
    浏览(43)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包