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

请求权限导致Android应用启动后无报错直接崩溃问题排查

应用发起权限请求时崩溃关闭问题排查

问题现象

  • 应用启动后调用权限请求代码时直接关闭,无任何错误提示
  • 注释掉ActivityCompat.requestPermissions(this, permissions, REQUEST_MICROPHONE);后,应用可正常启动
  • 需求权限:蓝牙相关权限、数据访问权限

问题相关代码

private static final int REQUEST_MICROPHONE = 1;

private void askPermissions(){
    String[] permissions = {Manifest.permission.RECORD_AUDIO,
            Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT};
    if (!hasPermissions(permissions)) {
        ActivityCompat.requestPermissions(this, permissions, REQUEST_MICROPHONE);
    }
}
private boolean hasPermissions(String[] permissions) {
    if(permissions != null){
        for(String perm : permissions){
            if(ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED)
                return false;
    }}
    return true;
}

Manifest配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">

    <uses-sdk android:minSdkVersion="21"
        android:targetSdkVersion="30"
        android:maxSdkVersion="30" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"  />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

    <!-- 仅向支持BLE的设备提供应用时添加以下配置 -->
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:configChanges="orientation|screenSize"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.myapp">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.myapp.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

排查与修复方案

1. 拆分跨组权限请求

Android 11(API 30)开始限制单次权限请求的分组范围,你当前的请求同时包含麦克风、蓝牙、位置、存储4个权限组,跨组请求会触发系统异常。需分批次申请:

// 请求码常量
private static final int REQUEST_MICROPHONE = 1;
private static final int REQUEST_BLUETOOTH_LOCATION = 2;
private static final int REQUEST_STORAGE = 3;

// 先申请麦克风权限
private void askMicPermission() {
    String[] micPerms = {Manifest.permission.RECORD_AUDIO};
    if (ContextCompat.checkSelfPermission(this, micPerms[0]) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, micPerms, REQUEST_MICROPHONE);
    } else {
        askBluetoothAndLocationPermissions();
    }
}

// 再申请蓝牙+位置权限
private void askBluetoothAndLocationPermissions() {
    String[] btLocPerms = {Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT};
    if (!hasPermissions(btLocPerms)) {
        ActivityCompat.requestPermissions(this, btLocPerms, REQUEST_BLUETOOTH_LOCATION);
    } else {
        askStoragePermission();
    }
}

// 最后申请存储权限
private void askStoragePermission() {
    String[] storagePerm = {Manifest.permission.READ_EXTERNAL_STORAGE};
    if (ContextCompat.checkSelfPermission(this, storagePerm[0]) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, storagePerm, REQUEST_STORAGE);
    }
}

2. 修正蓝牙权限声明

针对API 30,BLUETOOTH_SCAN需添加权限标记(若无需通过蓝牙获取位置),否则会和位置权限冲突:

<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

3. 规范权限请求时机

确保askPermissions()在Activity的onCreate()或onStart()方法中调用,避免在Activity未完全初始化时触发请求。

4. 添加权限回调处理

重写权限申请结果回调,确保流程连贯,避免潜在异常:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_MICROPHONE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                askBluetoothAndLocationPermissions();
            }
            break;
        case REQUEST_BLUETOOTH_LOCATION:
            boolean allGranted = true;
            for (int result : grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    allGranted = false;
                    break;
                }
            }
            if (allGranted) {
                askStoragePermission();
            }
            break;
        case REQUEST_STORAGE:
            // 处理存储权限申请结果
            break;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:45:41