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

Flutter SDK 31+已授权仍报MISSING_PERMISSIONS问题求助

解决SDK 31+读取通话记录权限缺失问题

针对你遇到的SDK 31+真机上出现MISSING_PERMISSIONS错误的问题,核心原因是Android 12(API 31)及以上版本对通话记录相关权限的申请逻辑和权限范围做了调整,以下是具体解决步骤:

1. 修正AndroidManifest权限声明

确保Manifest中添加了SDK 31+所需的完整权限,除了原有权限外,需补充READ_PHONE_NUMBERS权限:

<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Android 12+ 新增必填权限 -->
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />

注意检查是否误加了android:maxSdkVersion属性限制权限生效范围,避免SDK 31+版本无法获取权限。

2. 适配动态权限申请逻辑

Android 12+对敏感权限的申请要求更严格,需根据系统版本动态调整申请的权限列表:

  • 对于SDK 31及以上版本,申请READ_CALL_LOG + READ_PHONE_NUMBERS
  • 低于SDK 31版本,保持原有READ_CALL_LOG + READ_PHONE_STATE的申请组合

推荐使用ActivityResultContracts.RequestMultiplePermissions来处理权限申请(替代旧的onRequestPermissionsResult),示例代码如下:

// 注册权限申请回调
private final ActivityResultLauncher<String[]> permissionLauncher =
        registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> {
            boolean allGranted = true;
            for (Boolean granted : result.values()) {
                allGranted &= granted;
            }
            if (allGranted) {
                // 权限全部授予,执行通话记录读取逻辑
                loadCallLogs();
            } else {
                // 权限被拒绝,引导用户到设置页开启
                showPermissionGuide();
            }
        });

// 发起权限申请
private void requestCallPermissions() {
    String[] permissions;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        permissions = new String[]{Manifest.permission.READ_CALL_LOG, Manifest.permission.READ_PHONE_NUMBERS};
    } else {
        permissions = new String[]{Manifest.permission.READ_CALL_LOG, Manifest.permission.READ_PHONE_STATE};
    }
    permissionLauncher.launch(permissions);
}

3. 完善权限检查逻辑

在读取通话记录前,必须检查所有必要权限是否已授予,适配不同系统版本的权限检查逻辑:

private boolean hasRequiredPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED;
    } else {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
    }
}

4. 处理权限拒绝后的场景

如果用户拒绝权限后再次申请,Android 12+系统可能不再弹出权限申请弹窗,此时需要引导用户前往应用设置页面手动开启权限:

private void showPermissionGuide() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("权限需要")
            .setMessage("需要开启通话记录相关权限才能正常使用功能,请前往设置页开启")
            .setPositiveButton("去设置", (dialog, which) -> {
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivity(intent);
            })
            .setNegativeButton("取消", null)
            .show();
}

另外,需确保应用的targetSdkVersion设置为31或更高,编译SDK版本也对应匹配,否则可能触发系统的权限兼容性限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:25:18