安卓实机上Runtime Permissions无法正常工作问题排查
嘿,碰到这种权限卡住的情况确实闹心,我来帮你捋捋可能的原因和排查方向,大概率是代码逻辑的问题,但也不排除设备的小概率异常:
你的日志只输出到"DO CHECK",说明后续代码根本没执行到,先从这里入手:
检查权限判断的分支逻辑
你是不是在ContextCompat.checkSelfPermission()之后的条件判断写错了?比如如果设置里已经显示权限授予,那checkSelfPermission会返回PackageManager.PERMISSION_GRANTED,这时候如果你的代码是只有权限拒绝才走请求逻辑,那自然不会触发requestPermissions和onRequestPermissionRationale。
举个常见的错误例子:如果把判断条件写成了== PERMISSION_DENIED但实际权限已授予,那后续代码直接跳过,日志就停在"DO CHECK"了。建议你在checkSelfPermission之后加个日志,输出权限状态:Log.d(TAG, "DO CHECK"); int permStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION); Log.d(TAG, "权限状态:" + permStatus); // 0是授予,-1是拒绝 if (permStatus != PackageManager.PERMISSION_GRANTED) { // 权限请求逻辑 } else { Log.d(TAG, "权限已授予,直接走定位逻辑"); }另外还要注意:你代码里请求的是精确位置(ACCESS_FINE_LOCATION)还是粗略位置(ACCESS_COARSE_LOCATION)?如果设置里只给了粗略位置,但代码检查的是精确位置,那
checkSelfPermission会返回拒绝,这时候应该会走到请求逻辑,你可以看看日志有没有这部分输出。检查上下文(Context)是否有效
调用checkSelfPermission和requestPermissions必须用Activity的上下文,如果用了Application Context,虽然权限检查能返回结果,但requestPermissions会直接失效,甚至可能抛出异常导致后续代码中断。建议你在代码里加个try-catch捕获异常,看看是不是有隐藏的错误:try { Log.d(TAG, "DO CHECK"); int permStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION); Log.d(TAG, "权限状态:" + permStatus); if (permStatus != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { Log.d(TAG, "显示权限说明弹窗"); onRequestPermissionRationale(); } else { Log.d(TAG, "发起权限请求"); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1001); } } } catch (Exception e) { Log.e(TAG, "权限检查出错:", e); }检查Manifest权限声明
有没有在AndroidManifest.xml里正确声明位置权限?比如:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />如果漏了声明,
checkSelfPermission会直接返回拒绝,但这时候应该会走到请求权限的逻辑,不过还是确认一下比较好。
如果代码排查完都没问题,再考虑设备的问题:
定制ROM的权限缓存异常
有些Nougat版本的定制ROM(比如小米、华为的旧系统)可能存在权限缓存bug,系统显示权限已授予,但实际应用读取不到权限状态。你可以试试:- 进入应用设置,把位置权限改成「拒绝」,重启设备后再改回「允许」,重新测试;
- 清除应用的缓存和数据,重新安装后测试。
位置服务未开启
虽然权限显示已授予,但如果设备的位置服务(GPS/网络定位)没开启,会不会间接影响权限检查的逻辑?不过这应该不会导致checkSelfPermission不执行,只是后续定位失败,但还是可以确认一下位置服务是否开启。
从你的描述来看,代码逻辑问题的可能性更大,尤其是权限判断分支写错或者上下文无效的情况。建议先添加详细的日志和异常捕获,看看后续的日志输出,这样能更快定位问题。
内容的提问来源于stack exchange,提问作者Andromeda

