Android蓝牙扫描应用BLUETOOTH_CONNECT权限缺失问题排查
问题描述
我开发了一款蓝牙设备扫描应用,所有权限看起来都配置好了,但还是遇到报错,找不到问题所在。
报错信息:
Need android.permission.BLUETOOTH_CONNECT permission for AttributeSource ( uid = 10151, packageName = com.test8, attributionTag = null, token = android.os.BinderProxy@197a119, next = null ): AdapterService getBondedDevices
我的Manifest配置如下:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <!-- Needed only if your app looks for Bluetooth devices. If your app doesn't use Bluetooth scan results to derive physical location information, you can strongly assert that your app doesn't derive physical location. --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- Needed only if your app makes the device discoverable to Bluetooth devices. --> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <!-- Needed only if your app communicates with already-paired Bluetooth devices. --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- Needed only if your app uses Bluetooth scan results to derive physical location. --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
解决办法
你已经在Manifest里声明了BLUETOOTH_CONNECT权限,但Android 12(API 31)及以上版本中,这个权限属于危险权限,必须在运行时动态申请,仅在Manifest声明无效。
- 动态申请权限
在调用getBondedDevices()前,先检查并申请权限:
// 自定义请求码,比如1001 private val REQUEST_BLUETOOTH_CONNECT = 1001 // 检查权限是否已授予 if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { // 发起权限申请 ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.BLUETOOTH_CONNECT), REQUEST_BLUETOOTH_CONNECT ) } else { // 权限已授予,执行获取绑定设备逻辑 val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() val bondedDevices = bluetoothAdapter.bondedDevices // 处理绑定设备列表 }
- 处理权限申请结果
重写onRequestPermissionsResult方法,响应用户的权限选择:
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == REQUEST_BLUETOOTH_CONNECT) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意权限,执行逻辑 val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() val bondedDevices = bluetoothAdapter.bondedDevices // 处理绑定设备列表 } else { // 用户拒绝权限,给出提示 Toast.makeText(this, "需要蓝牙连接权限才能查看已绑定设备", Toast.LENGTH_SHORT).show() } } }
- 额外注意
- 若应用运行在Android 12+设备上,
BLUETOOTH_CONNECT必须动态申请; - 如果用到
BLUETOOTH_SCAN,同样需要动态申请(涉及位置信息时,还要处理位置权限的动态申请); - 所有需要蓝牙权限的API调用,都要先完成权限检查和申请。
内容的提问来源于stack exchange,提问作者Kyryll Podlipnyi
相关产品推荐
相关产品推荐

