getActivity / XXPermissions

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

[Bug]:安卓14,申请READ_MEDIA_IMAGES时,当用户选择部分允许后,READ_MEDIA_IMAGES的isGranted=true #244

Closed kevinfd2x closed 1 year ago

kevinfd2x commented 1 year ago

框架版本【必填】

18.5

问题描述【必填】

安卓14,申请READ_MEDIA_IMAGES时,当用户选择部分允许后,READ_MEDIA_IMAGES的isGranted=true, 预想中应该是false,READ_MEDIA_VISUAL_USER_SELECTED的isGranted=true才对,导致无法区分用户是部分允许还是全部允许。 请参考复现步骤中的代码

复现步骤【必填】

//下面这句允许访问部分照片时为false,允许访问全部时为true
ToastUtils.showLong("" + (ContextCompat.checkSelfPermission(mContext, READ_MEDIA_IMAGES) == PERMISSION_GRANTED));
String[] permissions = new String[] { Permission.READ_MEDIA_IMAGES, Permission.READ_MEDIA_VIDEO };
//下面这个if判断不管是部分允许还是全部允许后都是granted
if (!XXPermissions.isGranted(mContext, permissions)) {
    XXPermissions.with(mContext)
        .permission(permissions)
        .request(new OnPermissionCallback() {
                                            @Override
                                            public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                                                //这里总是allGranted=true
                                                }
                                            }

                                            @Override
                                            public void onDenied(List<String> permissions, boolean doNotAskAgain) {

                                            }
                                        });
}

是否必现【必填】

项目 targetSdkVersion【必填】

34

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

小米13pro(小米云测远程真机)

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

安卓14

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

自己遇到的

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

没有试

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

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

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

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

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

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

提供报错堆栈

No response

提供截图或视频

No response

提供解决方案

No response

getActivity commented 1 year ago

小伙子,你想要知道用户部分允许之后想要干什么?

kevinfd2x commented 1 year ago

小伙子,你想要知道用户部分允许之后想要干什么?

app的照片上传功能,如果用户选择部分允许,再次需要上传照片时还需要申请权限

zengx1998 commented 1 year ago

我也遇到啦 跟我一样的照片上传功能 我的是vivo xc90 华为手机基本上没有遇到这个问题

getActivity commented 1 year ago

@kevinfd2x 小伙子,如果是这样的话,你在上传照片直接再写一个权限申请不就可以了?

kevinfd2x commented 1 year ago

@kevinfd2x 小伙子,如果是这样的话,你在上传照片直接再写一个权限申请不就可以了?

单独用原生API写一个肯定是可以,但我觉得XXPermission对于安卓14的这个新权限的处理不太合适,现在的结果是READ_MEDIA_IMAGE并没有granted,但是却返回了true。 而且上传照片这种用法感觉应该挺常见的,用户第一次选择好部分可见的上传完成,第二次想上传别的时还会选择新的可见照片。

zengx1998 commented 1 year ago

@kevinfd2x 大佬 可以加下你联系方式 具体问下不

kevinfd2x commented 1 year ago

@kevinfd2x 大佬 可以加下你联系方式 具体问下不

要问啥?我看你之前说的华为没问题,据我所知华为还没有安卓14的设备

getActivity commented 1 year ago

@kevinfd2x 小伙子,框架之所以这样设计是有原因的,具体原因如下:

  1. 如果只允许选择部分照片/视频,那么在理解上来看,此时应用其实获取到了照片/视频权限,只不过不是全部图片都有权限。

  2. 框架目前的回调策略有三种情况,(1)如果全部权限都授予就会回调 onGranted 方法;(2)如果全部权限都拒绝授予就会回调 onDenied 方法的;(3)如果部分权限授予,部分权限拒绝授予的话,则会先回调 onDenied 方法,然后再回调 onGranted 方法。而你说的那种方法,会导致第三种情况触发,站在正常人逻辑的视角,照片权限只有一个,要么成功的状态,照片权限,要么失败的状态,整出来一个拒绝了但是又没完全拒绝的状态是什么意思?这样会给人造成一定的理解成本和消化成本。与其这样,不如简单一点,部分授予照片权限约等于全部授予,换另外用户的角度来讲,应用是出于什么目的要拿人家全部照片信息?作为用户就是不给你应用全部的照片权限,你又能拿我怎么样?难不成还想硬上?或者干脆不给人家用?

kevinfd2x commented 1 year ago

@kevinfd2x 小伙子,框架之所以这样设计是有原因的,具体原因如下:

  1. 如果只允许选择部分照片/视频,那么在理解上来看,此时应用其实获取到了照片/视频权限,只不过不是全部图片都有权限。
  2. 框架目前的回调策略有三种情况,(1)如果全部权限都授予就会回调 onGranted 方法;(2)如果全部权限都拒绝授予就会回调 onDenied 方法的;(3)如果部分权限授予,部分权限拒绝授予的话,则会先回调 onDenied 方法,然后再回调 onGranted 方法。而你说的那种方法,会导致第三种情况触发,站在正常人逻辑的视角,照片权限只有一个,要么成功的状态,照片权限,要么失败的状态,整出来一个拒绝了但是又没完全拒绝的状态是什么意思?这样会给人造成一定的理解成本和消化成本。与其这样,不如简单一点,部分授予照片权限约等于全部授予,换另外用户的角度来讲,应用是出于什么目的要拿人家全部照片信息?作为用户就是不给你应用全部的照片权限,你又能拿我怎么样?难不成还想硬上?或者干脆不给人家用?

照片权限部分授予这里,比如今天我要上传照片A,那我可以只授予APP读取A的权限,明天我要上传B那我只再追加授予B的读取权限即可,而我的照片C等永远是安全的,系统在第二次权限申请提示文字也和初次不一样。 以前只有是否授予,但14开始多出的这个部分授予权限开发者不能简单忽略,需要做单独适配处理,我觉得框架这里直接忽略掉不合适。

kevinfd2x commented 1 year ago

我觉得至少isGranted判断时不能没有获取到READ_MEDIA_IMAGE权限但还返回了true,虽然可能是故意这样设计,但怎么看都像是bug

getActivity commented 1 year ago

授予对照片和视频的部分访问权限

image
getActivity commented 1 year ago

小伙子,对于这个问题,我思考了很久,决定还是保留这一处理,我认为作为开发者来讲,不应该去知道用户到底是部分授予还是全部授予,因为用户选择哪一个,都可以正常读取相册的内容,并且两者读取相册的实现方式没有任何区别。

同理,另外你也可以看到,在高版本的 Android 上申请危险权限,还有《仅允许一次》和《始终允许》的选项,用户无论选择哪一个,系统都会告诉开发者用户是授予状态。

kevinfd2x commented 1 year ago

小伙子,对于这个问题,我思考了很久,决定还是保留这一处理,我认为作为开发者来讲,不应该去知道用户到底是部分授予还是全部授予,因为用户选择哪一个,都可以正常读取相册的内容,并且两者读取相册的实现方式没有任何区别。

同理,另外你也可以看到,在高版本的 Android 上申请危险权限,还有《仅允许一次》和《始终允许》的选项,用户无论选择哪一个,系统都会告诉开发者用户是授予状态。

要不再等等看吧,毕竟现在安卓14还比较少,没准儿以后类似我这种需求就多了,当然现在也可以用原生api来判断,但我觉得既然用了框架还是都用框架管理比较好。

另外您发的这个链接往下有专门介绍照片re-selection处理的章节: https://developer.android.google.cn/about/versions/14/changes/partial-photo-video-access?hl=zh-cn#media-reselection

也有写app应该让用户可以再次选择不同的图片

With the Selected Photos Access feature in Android 14, your app should adopt the new READ_MEDIA_VISUAL_USER_SELECTED permission to control media re-selection, and update your app's interface to let users grant your app access to a different set of images and videos.

getActivity commented 1 year ago

小伙子,你每次读取相册都去申请权限,只要用户选择的是授予部分照片访问,这样不是每次可以选择不同的照片?

kevinfd2x commented 1 year ago

小伙子,你每次读取相册都去申请权限,只要用户选择的是授予部分照片访问,这样不是每次可以选择不同的照片?

是这样,但如果用户选择全部授予,那app就不应该再申请权限了。 现在框架无法判断用户是给了READ_MEDIA_VISUAL_USER_SELECTED还是READ_MEDIA,当部分授予时框架的api这两个权限都会返回granted,但其实只granted了其中的READ_MEDIA_VISUAL_USER_SELECTED,所以不得不用原生api来判断是否granted了READ_MEDIA

getActivity commented 1 year ago

小伙子,这个 issue 我先关闭了,后续有类似意见的同学,可以在这个 issue 继续讨论,我看到会回复。

yangfengfandev commented 9 months ago

小伙子,这个 issue 我先关闭了,后续有类似意见的同学,可以在这个 issue 继续讨论,我看到会回复。

我这边也是需要同样的需求。如果用户只给了「部分图片权限」,给用户提供一个按钮可以重新选择更多图片。用这个库目前判断不了是「全部图片权限」还是「部分图片权限」

yangfengfandev commented 9 months ago

期望XXPermissions能够支持一下这个判断,要不我们就需要自己另外再单独写一个请求判断逻辑了

getActivity commented 9 months ago

@yangfengfandev 小伙子,目前还是建议你还是用原生的 API 做判断,这种场景我觉得比较少见的。

aheven commented 9 months ago

期望XXPermissions能够支持一下这个判断,要不我们就需要自己另外再单独写一个请求判断逻辑了

getActivity commented 9 months ago

期望XXPermissions能够支持一下这个判断,要不我们就需要自己另外再单独写一个请求判断逻辑了

@aheven 小伙子,劳烦描述一下你那边的业务场景是什么样的。

704480904 commented 8 months ago

出现了一样的需求 一样的问题 用户在Android 14的手机系统访问相册 ,选择访问部分图片之后,就再也没法选择其他的照片了

我这边也是需要同样的需求。如果用户只给了「部分图片权限」,给用户提供一个按钮可以重新选择更多图片。用这个库目前判断不了是「全部图片权限」还是「部分图片权限」 因为APP功能里面很多地方有选图的权限判断与权限申请

这个用原生的是可以实现这个需求的是吧?

getActivity commented 8 months ago

@704480904 是的,小伙子,你可以先这样判断。

lltbegin commented 4 months ago

在图片使用频率比较高的软件,如图片编辑类和文本日记类软件都有这个场景,如果用户在首次使用图片选择时出于尝试的目的选择了部分授权(或是用户以为可以这次选这些作为部分授权,下次还可以选其他的作为部分授权的想法),当用户想编辑其他不在范围内的图片时,XXpermissions此时判断READ_MEDIA_IMAGES是已授权,所以无法唤起新的权限请求,用户依旧只能看到部分授权图片。 在使用频率比较小的情景下,如只是更换头像,用户选择部分授权,选中了一个头像图片,当他后面又添加了一个新的照片在手机里,当他想更换时,也需要能准确判断是否要再次请求授权才可以,不然他无法更改部分授权范围。 感谢作者的付出👍,希望作者再考虑一下,谢谢

Equalzys commented 4 months ago

建议框架不要处理业务逻辑,代码请求框架弹权限窗时,框架就弹权限窗就行了,发现api34的代码对业务有冲突:

image

android 14这块权限场景还是挺常见的,用户第一次打开app授权了某个视频,第二次打开app,可以不自动弹权限窗,但是app的优化场景里需要有个点击入口给到用户以后能申请其他视频或全部视频的权限;现在授权部分视频后,再次调用框架去请求权限时,框架不会弹权限弹窗,导致只能使用原生api去给用户再次请求权限了

getActivity commented 4 months ago

XXPermissions-18.68.aar.zip

getActivity commented 4 months ago

@Equalzys 小伙子,经过仔细斟酌后,我对此处的代码逻辑进行了优化,使得用户在只获得部分媒体文件授权的情况下,再次请求权限还会弹窗给用户选择,具体涉及到改动的代码如下:

image image
getActivity commented 4 months ago

你可以下载上面我发的 aar 包进行测试,如果还有问题请及时和我反馈,如果没有问题我会在最近发布远程依赖。

getActivity commented 4 months ago

@704480904 @aheven @lltbegin @yangfengfandev 其他反馈此问题的小伙子们,有空也可以帮忙测试一下。

Equalzys commented 4 months ago

你可以下载上面我发的 aar 包进行测试,如果还有问题请及时和我反馈,如果没有问题我会在最近发布远程依赖。

用了68的包,有问题: 1、第一次调用框架,选择授权部分视频。 2、第二次手动调用框架,再次选择授权部分视频。 3、第三次手动调用框架,此时会闪烁一下,然后直接自动打开了系统选择视频的页面;没有弹系统授权弹窗; 4、之后的再次调用框架,情况同三;

发现不是框架的问题,调用原生API也是闪一下,直接自动打开了系统选择视频的页面

getActivity commented 4 months ago

@Equalzys 你调用系统 API 也会出现的问题,这种肯定不是框架的问题。

Equalzys commented 4 months ago

@Equalzys 你调用系统 API 也会出现的问题,这种肯定不是框架的问题。

像14系统bug

getActivity commented 4 months ago

@Equalzys 小伙子,如果你用的是第三方厂商定制的 Android 14 系统,可以考虑使用 Android 14 模拟器进行测试,反之则亦然,确定问题的来源后,你需要反馈给对应的人,如果原生 Android 14 也会出现的问题,你可以通过 IssueTracker 反馈给谷歌的工程师,如果只是第三方厂商会出现的,你可以在网上找到他们的开放平台并进行反馈。

getActivity commented 4 months ago

@Equalzys 小伙子,你看看还用有无其他问题,如果没有的话我就准备发布远程依赖了。

ImVeryGood commented 3 months ago

我遇到同样的场景,用户选择部分允许之后,下次想再选别的只能再次申请权限,用户继续选择部分允许然后跳到相册,感觉比较麻烦,iOS 如果设置了部分允许下次可以继续添加不用再次授权部分!可以直接拉起相册选择!