[笔记]适配Android 11(api 30) (分区存储Scoped Storage相关)经验小结

事件背景:

[笔记]适配Android 11(api 30) (分区存储Scoped Storage相关)经验小结_第1张图片

首先是谷歌应用市场在之前已经提示大家在今年下半年开始上架应用必须targetsdkversion到30了也就是android11。

[笔记]适配Android 11(api 30) (分区存储Scoped Storage相关)经验小结_第2张图片

Starting May 5th, you must let us know why your app requires broad storage access

We've detected that your app contains the requestLegacyExternalStorage flag in the manifest file of 1 or more of your app bundles or APKs.

Developers with apps on devices running Android 11+ must use Scoped Storage to give users better access control over their device storage. To release your app on Android 11 or newer after May 5th, you must either:

Update your app to use more privacy friendly best practices, such as the Storage Access Framework or Media Store API
Update your app to declare the All files access (MANAGE_EXTERNAL_STORAGE) permission in the manifest file, and complete the All files access permission declaration in Play Console from May 5th
Remove the All files access permission from your app entirely
For apps targeting Android 11, the requestLegacyExternalStorage flag will be ignored. You must use the All files access permission to retain broad access.

Apps requesting access to the All files access permission without a permitted use will be removed from Google Play, and you won't be able to publish updates.

另外还收到了这样的通知。

网上也有很多从android10 (api 29) Q开始的适配分区存储(Scoped Storage)的文章,但是在api29中使用分区存储将无法使用file api,google在API 30中又恢复了file api。

相关视频:https://www.youtube.com/watch?v=RjyYCUW-9tY&feature=youtu.be

官方文档

  • 使用直接文件路径和原生库访问文件
  • 为了帮助您的应用更顺畅地使用第三方媒体库,Android 11 允许您使用除 MediaStore API 之外的 API 通过直接文件路径访问共享存储空间中的媒体文件。其中包括:
  • File API。
  • 原生库,例如 fopen()。

存在的疑问:

按照通知的描述,如果将targetsdkversion升至30,那么停用分区存储就会失效,在android10(api29)的设备上我还没法申请

ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 这个权限,那么有一些类文件管理的操作就不好实现了吗?

进行的验证1,在真机上运行

后续我进行了测试,实际这个情况暂时并没有发生,我将targetsdkversion 30 

requestLegacyExternalStorage="true"

的应用安装到android10的小米手机上,发现还是可以使用传统的文件访问方式。

验证2,查看微信的解决方法

因为这个事情比较困扰,就决定看一看微信目前是怎么做的。

百度了一个以下版本(2021-04-01更新的)

[笔记]适配Android 11(api 30) (分区存储Scoped Storage相关)经验小结_第3张图片

使用AAPT 工具 

aapt dump badging xxx.apk

[笔记]适配Android 11(api 30) (分区存储Scoped Storage相关)经验小结_第4张图片

再找一个谷歌应用市场的海外版本试试(7.0.21)

[笔记]适配Android 11(api 30) (分区存储Scoped Storage相关)经验小结_第5张图片

target SDK 也是29

[笔记]适配Android 11(api 30) (分区存储Scoped Storage相关)经验小结_第6张图片

再看一下微信有没有停用分区存储呢? 结果是停用的。

当前可进行的调整:

目前可以将不必要在公共目录操作的文件读写转移到私有目录下进行,

总结一下想继续在公共目录操作文件的几种方式就是:

  • MediaStore Api
  • SAF
  • 申请所有文件读写权限 (MANAGE_EXTERNAL_STORAGE)

简单记录一下:

MediaStore Api:

并不能拿全想要的文件,满足不了需求

SAF:

//假设没有权限时的备选方案:存在的问题:可能会选择到后缀为.1的文件(当筛选.bin文件时)
            //android 11及以上时使用
            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("application/zip");
            // 其他文件类型举例:bin:"application/octet-stream",所有文件:"*/*"
            startActivityForResult(intent, REQUEST_CODE_SAF);

申请所有文件读写权限:

AndroidManifest中添加以下权限

            if (Environment.isExternalStorageManager()) {
                //已经开启权限
            } else {
                //建议再增加一个提示 提醒用户 需要授权权限才可以继续使用该功能
                //未开启权限,弹窗申请权限
                openAllFilesPermission();
            }
    private void openAllFilesPermission(){
//        Log.d(TAG, "MainActivity getPackageName"+getApplicationContext().getPackageName());
        Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
//    intent.setData(Uri.parse("package:" + getApplicationContext().getPackageName())); //此处注释,增加后会报错,暂未解决
        getCurrentActivity(). startActivityForResult(intent, ALL_FILE_REQUEST_CODE);
    }

这里有一点疑惑的是,当我给intent设置包名参数后 运行就会闪退,暂去。

目前记录到这么多,后续有好的解决方式再来补充。

零碎的踩坑记录:

context.getFilesDir().getAbsolutePath() 这句在api 30里面 位置不一样了

另外api 30时。linking 这个 rn库跳email会失效,可区分版本后使用原生替代

Intent data= new  Intent(Intent.ACTION_SENDTO);
        data.setData(Uri.parse( "mailto:[email protected]" ));
        data.putExtra(Intent.EXTRA_SUBJECT,  "这是标题" );
        data.putExtra(Intent.EXTRA_TEXT,  "这是内容" );
        getCurrentActivity().startActivity(data);
isExternalStorageManager在华为emui中直接调用会闪退(miui和一加的android10不会闪退)(问题复现:p30 pro emui:11.0.0.137),增加安卓版本过滤即可(华为当前还没有android11机型)

[笔记]适配Android 11(api 30) (分区存储Scoped Storage相关)经验小结_第7张图片

你可能感兴趣的:(android,android)