sdCard访问权限

P90访问SDCard

之前的文章说过,SDCard在O到P上有重大改动。在P上必须使用storageVolume.createAccessIntent

        if (storageVolume!=null&&canFindPath){
            Intent intent = storageVolume.createAccessIntent(getDirectoryName("DCIM"));//
            permissionPath=storagePath + File.separator+"DCIM";
            startActivityForResult(intent, OPEN_DIRECTORY_REQUEST_CODE);
        }

Q100上的改动

在Q上又有了一些改动,storageVolume.createAccessIntent一些action被禁用

* @deprecated Callers should migrate to using {@link Intent#ACTION_OPEN_DOCUMENT_TREE} instead.
     *             Launching this {@link Intent} on devices running
     *             {@link android.os.Build.VERSION_CODES#Q} or higher, will immediately finish
     *             with a result code of {@link android.app.Activity#RESULT_CANCELED}.

P90上的frameworks层启动log

实际上,P上通过storageVolume.createAccessIntent获得intent,请求权限,启动的是system.ui下面的ScopedAccessActivity

10-05 14:22:56.073 6246-6246/? D/GrantPermissionHelper: getSdCardPermission startActivityForResult intent Intent { act=android.os.storage.action.OPEN_EXTERNAL_DIRECTORY (has extras) }
10-05 14:22:56.077 1520-2111/system_process I/ActivityTaskManager: START u0 {act=android.os.storage.action.OPEN_EXTERNAL_DIRECTORY cmp=com.android.documentsui/.ScopedAccessActivity (has extras)} from uid 10147 pid 6246
10-05 14:22:56.080 1520-2111/system_process D/BoostFramework: perfHint : hint: 0x1081 pkg_name(userDataStr): android duration(userData1): -1 type(userData2): 1
10-05 14:22:56.080 1520-1606/system_process I/system_server: Compiler filter for /data/app/com.htc.zero-V5KQqHfsFhUeIDCLbDnbRA==/oat/arm64/base.odex is quicken
10-05 14:22:56.080 1520-1606/system_process I/system_server: Compiler filter for /data/app/com.htc.zero-V5KQqHfsFhUeIDCLbDnbRA==/oat/arm64/base.odex is quicken
10-05 14:22:56.084 1520-1606/system_process I/ActivityTaskManager: Displayed com.htc.zero/.activity.GrantPermissionActivity: +514ms

Q100上frameworks一些类被禁用

但是在Q上ScopedAccessActivity被废弃,禁止通过代码StorageVolume#createAccessIntent(String)直接申请某个目录的读写权限

建议使用Callers should migrate to using {@link Intent#ACTION_OPEN_DOCUMENT_TREE} instead

这个intent会打开一个文件目录让用户自己选择授权的目录,给了用户更多的选择权,禁止了应用私自申请目录权限创建文件。

相当于进一步规范了SDCard目录

26/**
27 * Activity responsible for handling {@link StorageVolume#createAccessIntent(String)}.
28 *
29 * @deprecated This class handles the deprecated {@link StorageVolume#createAccessIntent(String)}.
30 */
31@Deprecated
32public class ScopedAccessActivity extends Activity {
33    @Override
34    public void onCreate(Bundle savedInstanceState) {
35        super.onCreate(savedInstanceState);
36        logInvalidScopedAccessRequest(SCOPED_DIRECTORY_ACCESS_DEPRECATED);
37        setResult(RESULT_CANCELED);
38        finish();
39    }
40}

==================----------------------------------------======================

三方应用Android 4.4之后不能直接对外置SD卡通过FileOutputStream写数据,只能通过DocumentFile这个接口来实现

Android 6.0 运行时权限

系统应用Android 9.0之后不能直接对外置SD卡通过FileOutputStream写数据,只能通过DocumentFile这个接口来实现

AndroidQ上禁止通过代码StorageVolume#createAccessIntent(String)直接申请某个目录的读写权限

只能使用Intent#ACTION_OPEN_DOCUMENT_TREE让用户选择某个目录

Android R上 对ACTION_OPEN_DOCUMENT_TREE 或 ACTION_OPEN_DOCUMENT也进行了限制

改为使用MANAGE_EXTERNAL_STORAGE进行大量的文件操作

==================----------------------------------------======================

Android 4.4(API 19 级)引入了存储访问框架 (SAF)

尾注:

  • 从4.4开始google开始规范SDCard卡读写问题,旨在保护用户空间和规范空间使用。
  • 让程序员更不容易操作存储空间目录。
  • P90上强制执行,删除了SDCard写权限,必须使用DocumentFile进行存储访问。
  • Q上对DocumentFile的访问方式也进行了限制,让程序员无法直接申请想要读写的路径,改为用户去选择给app的访问路径。
  • R上进一步对ACTION_OPEN_DOCUMENT_TREE 或 ACTION_OPEN_DOCUMENT进行限制,

无法再使用 ACTION_OPEN_DOCUMENT_TREE intent 操作来请求访问以下目录:

1.Downloads 根目录。

2.设备制造商认为可靠的各个 SD 卡卷的根目录,无论该卡是模拟卡还是可移除的卡。

无法再使用 ACTION_OPEN_DOCUMENT_TREE 或 ACTION_OPEN_DOCUMENT intent 操作来请求用户从以下目录中选择单独的文件:

3.Android/data/ 目录及其所有子目录。

4.Android/obb/ 目录及其所有子目录。

以上 是各个版本对存储进行的限制访问。

由于公司项目只做到Q,P上面的方式已经验证可行,Q上被弃用的方式也跟踪了源码进行验证。让用户选择路径不符合app设计,也由底层frameworks那边直接授权,所以不需要使用DocumentFile,R上面的访问没有进行验证。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中申请访问 sdcard 的权限,你需要在 AndroidManifest.xml 文件中添加以下权限声明: ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` READ_EXTERNAL_STORAGE 权限用于读取外部存储器(如 sdcard)中的文件,而 WRITE_EXTERNAL_STORAGE 权限用于向外部存储器写入文件。 请注意,自 Android 6.0(API 级别 23)起,访问外部存储器被认为是危险权限,需要在运行时请求。你可以使用以下代码在运行时请求这些权限: ```java // 检查是否已经获得了权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 请求权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE); } // 处理权限请求的结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == READ_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 已经获得了访问 sdcard 的权限,可以进行相关操作 } else { // 未获得访问 sdcard 的权限,无法进行相关操作 } } } ``` 请记得在请求 WRITE_EXTERNAL_STORAGE 权限时也需要类似的处理逻辑。 希望这些信息对你有所帮助!如果有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值