Fragment内onRequestPermissionsResult权限回调不生效无法调用方法
Fragment位置权限回调中getUserLocation()不生效排查方案
问题对应代码
override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { // super.onRequestPermissionsResult(requestCode, permissions, grantResults) Log.wtf("here grand result" , requestCode.toString(),) Log.wtf("here grand result" , grantResults.toString(),) if(requestCode == PERMISSION_REQUEST_ACCESS_LOCATION){ if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){ Toast.makeText(requireActivity(),"permission granted",Toast.LENGTH_SHORT).show() getUserLocation() }else{ Toast.makeText(requireActivity(),"Denied",Toast.LENGTH_SHORT).show() } } }
排查&修复点
- 恢复被注释的父类方法调用
代码中注释掉的super.onRequestPermissionsResult(requestCode, permissions, grantResults)必须放开,AndroidX Fragment的权限结果分发、状态同步依赖父类逻辑,不调用super会出现回调参数异常、嵌套Fragment结果无法正常传递的问题,哪怕Toast能正常弹出,分支判断逻辑也可能不符合预期。 - 修正错误的日志打印逻辑
当前代码直接调用grantResults.toString()打印的是Int数组的对象内存地址,不是数组内存储的实际授权结果值,你无法通过现有日志判断grantResults[0]是否真的等于PackageManager.PERMISSION_GRANTED。替换为grantResults.contentToString()或者直接打印grantResults[0]的数值,就能看到真实的授权返回值,避免误判权限状态。 - 确认权限请求的调用方正确
如果在Fragment内发起位置权限请求,必须调用Fragment自身的requestPermissions()方法,不能直接调用宿主Activity的requestPermissions(),否则权限结果只会回调到Activity的onRequestPermissionsResult,不会正常分发到当前Fragment,你在Fragment重写的回调拿到的参数可能是无效值。 - 校验getUserLocation()方法本身的执行状态
在getUserLocation()方法第一行添加日志打印,确认方法是否真的被调用:- 如果日志正常打印,说明权限回调逻辑没有问题,故障出在定位方法内部,比如设备定位开关未开启、定位服务初始化失败、清单文件中位置权限声明缺失、未做位置设置可用性检查等
- 如果日志没有打印,回到前面三个点逐一校验即可。
修正后可正常运行的代码
override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { // 必须保留super调用 super.onRequestPermissionsResult(requestCode, permissions, grantResults) // 打印真实回调参数 Log.wtf("permission callback", "requestCode: $requestCode, grant result: ${grantResults.contentToString()}") if(requestCode == PERMISSION_REQUEST_ACCESS_LOCATION){ if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){ Toast.makeText(requireActivity(),"permission granted",Toast.LENGTH_SHORT).show() Log.d("location", "start get user location") getUserLocation() }else{ Toast.makeText(requireActivity(),"Denied",Toast.LENGTH_SHORT).show() } } }
补充说明:如果targetSdkVersion >= 31,申请位置权限时需要注意区分前台位置权限(
ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION)和后台位置权限(ACCESS_BACKGROUND_LOCATION),如果清单文件漏声明对应权限,也会导致授权流程异常。
内容的提问来源于stack exchange,提问作者Sajib saha
相关产品推荐
相关产品推荐

