权限部分
安卓软件希望实现蓝牙扫描设备功能在不同版本的Android系统中需要不同的权限和服务要求。
Android 12 (API Level 31) 及以上,蓝牙扫描设备需要以下权限:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- 需要位置权限,因为蓝牙扫描可以暴露用户的位置 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
新引入的三个权限就是
- BLUETOOTH_SCAN 用于使用蓝牙扫描附近其他的蓝牙设备
- BLUETOOTH_ADVERTISE 用于允许当前的设备被其他的蓝牙设备所发现
- BLUETOOTH_CONNECT 用于连接之前已经配对过的蓝牙设备
此外,需要动态申请的权限如下:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.BLUETOOTH_SCAN},
REQUEST_BLUETOOTH_SCAN);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.BLUETOOTH_CONNECT},
REQUEST_BLUETOOTH_CONNECT);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_ACCESS_FINE_LOCATION);
}
在Android 6.0 (API Level 23) 到 Android 11 (API Level 30),蓝牙扫描设备需要以下权限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
此外,需要动态申请的权限如下:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_ACCESS_FINE_LOCATION);
}
Android 6.0 以下,蓝牙扫描设备只需要以下权限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
不需要请求运行时权限,也不需要位置权限。
服务部分
蓝牙扫描设备肯定需要打开蓝牙服务。
Android 6.0 (API Level 23) 及以上版本,使用到定位权限,需要打开定位服务才能进行蓝牙扫描。
简单实现代码:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) &&
!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
总结表格
Android版本 | 权限 | 服务 | 动态申请权限 |
Android 12 (API Level 31)以上 | BLUETOOTH_SCAN BLUETOOTH_CONNECT ACCESS_FINE_LOCATION | 蓝牙、 定位 | BLUETOOTH_SCAN BLUETOOTH_CONNECT ACCESS_FINE_LOCATION |
Android 6.0 (API Level 23) 到 Android 11 (API Level 30) | BLUETOOTH BLUETOOTH_ADMIN ACCESS_FINE_LOCATION | 蓝牙、 定位 | ACCESS_FINE_LOCATION |
Android 6.0 以下 | BLUETOOTH BLUETOOTH_ADMIN | 蓝牙 | —— |