はじめに
Android 12でBluetooth接続を行う際のPermissionが少し変わったようです。
自アプリがクライアントとして他のBLEデバイスに接続する場合のPermissionにどのような違いがあるのかを触ってみました。
シミュレータの動作ベースで確認した内容でまとめますが、探り探りのため記載に関して誤りやご指摘を頂けると助かります。
基本的なAPIのAPI LevelによるPermission要求の違い
API | API Level 30 | API Level 31 |
---|---|---|
BluetoothAdapter.isEnabled() | BLUETOOTH | BLUETOOTH, BLUETOOTH_CONNECT |
BluetoothLeScanner.startScan() | BLUETOOTH_ADMIN, ACCESS_FINE_LOCATION | BLUETOOTH_ADMIN, BLUETOOTH_CONNECT, BLUETOOTH_SCAN |
- Beta1時点において、API Level 30未満(Android 12未満)はtargetSdkVersion 30と同じく位置情報のPermissionが必要。
- API Level 30未満に対しては旧来のパーミッションが引き続き必要となるので、AndroidManifest上でandroid:maxSdkVersion="30"を指定して要求する必要がある。
コードサンプル
BluetoothDeviceの利用時に位置情報が不要な場合、AndroidManifest.xmlに*android:usesPermissionFlags="neverForLocation"*を指定します。
- Simulator使用時にはusesPermissionFlagsをfalseに設定しないとscan結果が得られませんでした。
- usesPermissionFlagsをfalseにした状態でもrssi値は取得できました。
if (checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permissions are already granted.", Toast.LENGTH_SHORT).show();
} else {
requestPermissions(new String[]{Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_SCAN}, CHECK_PERMISSION);
}
AndroidManifest.xml
<!-- API Level 30未満では古いPermissionを使用する -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- API Level 31以降で必要なPermission -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
上記コードでPermission要求した時に表示されるシステムダイアログ 
参考文献
New Bluetooth permissions in Android 12
Bluetooth Low Energy の概要