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
相关产品推荐
相关产品推荐

