You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android位置权限异常求助:弹窗不稳定+Android10无始终允许选项

问题分析与解决方案

问题1:位置权限请求弹窗偶尔出现

你的代码中多次单独调用requestPermissions,而Android系统同一时间只能显示一个权限请求弹窗。当短信权限和位置权限的请求同时触发时,后发起的请求会覆盖先发起的,导致部分位置权限的请求被“吞掉”,表现为弹窗偶尔出现。

所有权限请求应该合并为一次调用,避免系统处理冲突。

问题2:Android 10(API 29)无“始终允许”选项

Android Q(API 29)对ACCESS_BACKGROUND_LOCATION的申请有严格要求:

  1. 必须先获得前台位置权限(ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION)的授权(用户选择“使用期间允许”);
  2. 不能单独请求ACCESS_BACKGROUND_LOCATION,需要在用户已授予前台权限的前提下,再发起后台权限请求,此时弹窗才会显示“始终允许”选项。

你的代码中直接单独请求ACCESS_BACKGROUND_LOCATION,不符合系统权限申请逻辑,因此不会出现“始终允许”选项。


修正后的代码示例

步骤1:合并前台权限请求(短信+位置前台权限)

// 合并需要申请的前台权限列表
List<String> requestPermissions = new ArrayList<>();

// 短信权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {
    requestPermissions.add(Manifest.permission.RECEIVE_SMS);
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
    requestPermissions.add(Manifest.permission.SEND_SMS);
}

// 前台位置权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    requestPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
}

// 发起前台权限请求
if (!requestPermissions.isEmpty()) {
    ActivityCompat.requestPermissions(this,
            requestPermissions.toArray(new String[0]),
            Utils.PERMISSION_REQUEST_FOREGROUND); // 自定义请求码
}

步骤2:在权限回调中请求后台位置权限

重写onRequestPermissionsResult方法,在前台权限授予后,再请求后台位置权限:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == Utils.PERMISSION_REQUEST_FOREGROUND) {
        // 检查前台位置权限是否已授予
        boolean hasFineLocation = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        boolean hasCoarseLocation = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && (hasFineLocation || hasCoarseLocation)) {
            // 前台权限已授予,请求后台位置权限
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
                        Utils.PERMISSION_ACCESS_BACKGROUND_LOCATION);
            }
        }
    }
}

额外注意事项

  • 申请权限前,建议先向用户说明权限用途(比如弹窗提示为什么需要位置权限),提高用户授权意愿;
  • 避免在App启动时一次性请求过多权限,可根据功能触发时机按需申请;
  • 对于Android 11+(API 30),后台权限的申请逻辑类似,但系统会直接跳转到权限设置页,而非弹窗。

内容的提问来源于stack exchange,提问作者Alessandro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 04:30:30