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

Android Studio简单蓝牙应用权限问题求助:5个权限相关错误无法解决

Android Studio简单蓝牙应用权限问题求助:5个权限相关错误无法解决

嗨,我完全懂你被权限问题卡壳的挫败感!咱们一步步拆解这个问题——你的错误提示已经说得很清楚了:Android从6.0(API 23)开始,要求调用敏感的蓝牙API前必须主动检查权限是否授予,或者显式处理SecurityException。你的代码里那些标粗的蓝牙操作(获取配对设备、创建Socket、连接)都是需要权限的关键点,咱们来逐个修复:

第一步:在Manifest中声明必要的权限

首先得在AndroidManifest.xml里把需要的蓝牙和位置权限加上(不同Android版本的权限要求不一样,得兼容):

<!-- 基础蓝牙权限(适用于Android 11及以下) -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

<!-- Android 6.0+ 位置权限(蓝牙扫描/获取配对设备需要) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- Android 12+ 新增的细分蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

<!-- 声明设备支持蓝牙(可选,但建议加上) -->
<uses-feature android:name="android.hardware.bluetooth" android:required="true" />

第二步:在代码中添加权限检查与请求逻辑

在你的MainActivity里添加以下代码,用来检查权限和请求用户授权:

// 权限请求的请求码
private static final int REQUEST_BLUETOOTH_PERMISSIONS = 1001;

// 检查是否拥有所需的蓝牙权限
private boolean hasBluetoothPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        // Android 12+ 需要检查CONNECT和SCAN权限
        return ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED;
    } else {
        // 旧版本需要检查基础蓝牙权限+位置权限
        return ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
    }
}

// 请求蓝牙权限
private void requestBluetoothPermissions() {
    String[] permissions;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        permissions = new String[]{Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_SCAN};
    } else {
        permissions = new String[]{Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_FINE_LOCATION};
    }
    ActivityCompat.requestPermissions(this, permissions, REQUEST_BLUETOOTH_PERMISSIONS);
}

第三步:修改按钮点击事件,先检查权限再执行操作

把你原来的按钮点击逻辑加上权限检查,确保只有权限授予后才执行蓝牙操作:

修改获取设备按钮的点击事件:

GetDevBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 先检查权限,没有就请求
        if (!hasBluetoothPermissions()) {
            requestBluetoothPermissions();
            return;
        }
        // 原来的获取配对设备逻辑
        Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();
        for (BluetoothDevice dev : devices) {
            if (dev.getName().equals("PARTHA BT0")) {
                bluetoothDevice = dev;
                bluetoothAdapter.cancelDiscovery();
                break;
            }
        }
    }
});

修改连接按钮的点击事件:

ConnectBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 先检查权限
        if (!hasBluetoothPermissions()) {
            requestBluetoothPermissions();
            return;
        }
        try {
            bluetoothSocket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
            bluetoothSocket.connect();
            inputStream = bluetoothSocket.getInputStream();
            outputStream = bluetoothSocket.getOutputStream();
            rxThread.start();
            Toast.makeText(MainActivity.this,"CONNECTED",Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            // 别空catch!加上异常提示方便排查问题
            Toast.makeText(MainActivity.this,"连接失败:" + e.getMessage(),Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
});

第四步:处理权限请求的回调

重写onRequestPermissionsResult方法,处理用户授权后的逻辑:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_BLUETOOTH_PERMISSIONS) {
        boolean allPermissionsGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allPermissionsGranted = false;
                break;
            }
        }
        if (allPermissionsGranted) {
            Toast.makeText(this,"权限已获取,可以继续操作",Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this,"需要授予蓝牙权限才能使用功能",Toast.LENGTH_SHORT).show();
        }
    }
}

额外提醒:确保蓝牙已启用

你已经有REQUEST_ENABLE_BLUETOOTH常量,可以在onCreate里加上蓝牙状态检查:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // ... 其他初始化代码
    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    
    // 检查设备是否支持蓝牙
    if (bluetoothAdapter == null) {
        Toast.makeText(this,"当前设备不支持蓝牙",Toast.LENGTH_SHORT).show();
        finish();
        return;
    }
    // 检查蓝牙是否开启,没开启就请求用户开启
    if (!bluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BLUETOOTH);
    }
    // ... 其他代码
}

做完这些修改后,你的权限错误应该就能解决了——现在每次调用敏感蓝牙API前都会先检查权限,并且在权限缺失时主动请求用户授权。另外记得别再用空的catch块,这样遇到问题能快速定位原因~

备注:内容来源于stack exchange,提问作者Hygge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 12:19:52