getActivity / XXPermissions

Android 权限请求框架,已适配 Android 14
Apache License 2.0
5.44k stars 735 forks source link

[Bug]:升级android13, 首次请求权限出现权限被拒绝的问题。 #243

Closed qingmulang closed 6 months ago

qingmulang commented 7 months ago

框架版本【必填】

18.2

问题描述【必填】

复现步骤【必填】

XXPermissions.with(this)
        // 适配分区存储应该这样写
        .permission(Permission.READ_MEDIA_IMAGES)
        .permission(Permission.READ_MEDIA_VIDEO)
        .permission(Permission.READ_MEDIA_AUDIO)
        .permission(Permission.WRITE_EXTERNAL_STORAGE)
        .interceptor(new PermissionInterceptor())
        .request(new OnPermissionCallback() {
            @Override
            public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                if (!allGranted) {
                    return;
                }
                toast(String.format(getString(R.string.demo_obtain_permission_success_hint),
                        PermissionNameConvert.getPermissionString(MainActivity.this, permissions)));
                String storePath = Environment.getExternalStoragePublicDirectory(
                        Environment.DIRECTORY_PICTURES
                ).getAbsolutePath();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        File dirF = new File(storePath);
                        if (!dirF.exists() || !dirF.isDirectory()) {
                            if (!dirF.mkdirs()) {
                                toast("mkdirs 创建失败");
                                return;
                            }
                        }
                        try {
                            final File writeFile = File.createTempFile("colorMaster", ".png", dirF);
                            Log.e("Permission","创建成功");
                        } catch (IOException e) {
                            Log.e("Permission","创建失败:" + e.getMessage());
                            throw new RuntimeException(e);
                        }
                    }
                }).start();
            }
        });

targetVersion = 33,以上是请求权限的代码,问题: app 首次请求后,点击《仅在使用中允许》或者《总是允许》这两个按钮,都会走 onGranted,但是会报 java.io.IOException: Permission denied 的错误。但是再杀死 app,重新打开再次点击保存,就可以保存成功。

是否必现【必填】

项目 targetSdkVersion【必填】

33

出现问题的手机信息【必填】

Redmi Note 5 [android 9]亲测出现,线上用户反馈Samsung galaxy J4+ [android 9]

出现问题的安卓版本【必填】

9

问题信息的来源渠道【必填】

自己遇到的, 用户反馈

是部分机型还是所有机型都会出现【必答】

红米三星出现,其他手机未测试

框架最新的版本是否存在这个问题【必答】

框架文档是否提及了该问题【必答】

是否已经查阅框架文档但还未能解决的【必答】

issue 列表中是否有人曾提过类似的问题【必答】

是否已经搜索过了 issue 列表但还未能解决的【必答】

是否可以通过 Demo 来复现该问题【必答】

提供报错堆栈

Caused by: java.io.IOException: Permission denied
   at java.io.UnixFileSystem.createFileExclusively0(Native Method)
   at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:281)
   at java.io.File.createTempFile(File.java:2018)

提供截图或视频

No response

提供解决方案

No response

getActivity commented 7 months ago
image image

小伙子,我拷贝了你的代码,然后用红米 Redmi Note 5(Android 9.0) 和 Android 9.0 模拟器均没有复现到这个问题。

qingmulang commented 7 months ago

轮子哥,这是修改demo做的改动。

必现 第一次点击 crash,查看权限是已经申请成功;第二次成功。下面是设备信息,录屏和错误信息。

gradle:7.3.3 AGP:7.2.2

app-build.gradle targetSdkVersion 33

AndroidManifest.xml
    <meta-data
            android:name="ScopedStorage"
            android:value="true" />
MAinActivity.java
...
else if (viewId == R.id.btn_main_request_read_media_permission) {
            long delayMillis = 0;
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
                delayMillis = 2000;
                toast(getString(R.string.demo_android_13_read_media_permission_hint));
            }
            view.postDelayed(new Runnable() {
                @Override
                public void run() {
                    XXPermissions.with(MainActivity.this)
                            // 不适配分区存储应该这样写
//                            .permission(Permission.MANAGE_EXTERNAL_STORAGE)
                            // 适配分区存储应该这样写
                            .permission(Permission.READ_MEDIA_IMAGES)
                            .permission(Permission.READ_MEDIA_VIDEO)
                            .permission(Permission.READ_MEDIA_AUDIO)
//                            .permission(Permission.READ_MEDIA_VISUAL_USER_SELECTED)
                            .permission(Permission.WRITE_EXTERNAL_STORAGE)
                            .interceptor(new PermissionInterceptor())
                            .request(new OnPermissionCallback() {
                                @Override
                                public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                                    if (!allGranted) {
                                        return;
                                    }
                                    toast(String.format(getString(R.string.demo_obtain_permission_success_hint),
                                            PermissionNameConvert.getPermissionString(MainActivity.this, permissions)));

                                    String storePath = Environment.getExternalStoragePublicDirectory(
                                            Environment.DIRECTORY_PICTURES
                                    ).getAbsolutePath();

                                    new Thread(new Runnable() {
                                        @Override
                                        public void run() {
                                            File dirF = new File(storePath);
                                            if (!dirF.exists() || !dirF.isDirectory()) {
                                                if (!dirF.mkdirs()) {
                                                    toast("mkdirs 创建失败");
                                                    return;
                                                }
                                            }

                                            try {
                                                final File writeFile = File.createTempFile("colorMaster", ".png", dirF);

                                                Log.e("Permission","创建成功");
                                            } catch (IOException e) {
                                                Log.e("Permission","创建失败:" + e.getMessage());
                                                throw new RuntimeException(e);
                                            }

                                        }
                                    }).start();
                                }
                            });
                }
            }, delayMillis);
        }

img_v2_21d7f064-57d2-48b5-8f8d-7aa9a16de79g

https://github.com/getActivity/XXPermissions/assets/8425325/bb6acb70-ec9e-400b-a2ae-1c0a5531ad73

img_v2_bd51f42b-8351-4fdf-a94d-82185a1717fg

qingmulang commented 7 months ago

第一次测试前,先将权限设置为询问。

getActivity commented 7 months ago

小伙子,我看了你的视频,确认了你的操作跟我的操作一模一样,但是我在云测上面找了相同的机型还是复现不了。

getActivity commented 7 months ago

@qingmulang 小伙子,这个问题我建议你先升级一下手机的系统版本看看,说不定这个是系统的 Bug。如果还是不行的话,我希望你能帮我研究一下为什么会这样,如果研究不到也没关系,另外你可以考虑尝试在权限申请成功后加几秒的延迟,然后再写入文件,看看这样是否还会出现崩溃的情况。

qingmulang commented 7 months ago

手机系统版本已经是最新:MIUI12.0.3.0,我又借到一个相同的手机,还是一样的问题,可能是这款手机系统的bug。当前比较赶时间,有时间看看啥原因导致的

getActivity commented 7 months ago

@qingmulang 小伙子,我这边是复现不了,你可以研究一下看看是什么问题,如果有最新的进展,欢迎和我反馈。