アプリで Bluetooth 機能を使用するには、いくつかの権限を宣言する必要があります。また、アプリが Bluetooth クラシック または Bluetooth Low Energy(BLE)のサポートを必要とするかどうかを指定する必要があります。アプリで Bluetooth クラシックや BLE が必須ではないものの、これらのテクノロジーを利用できる場合は、実行時に利用可能かどうかを確認できます。
権限を宣言する
アプリで宣言する権限のセットは、アプリのターゲット SDK バージョンによって異なります。
Android 12 以降をターゲットとする
注: Android 8.0(API レベル 26)以降では、コンパニオン デバイス マネージャー(CDM)を使用することで、このセクションで説明する権限よりも効率的な方法でコンパニオン デバイスに接続できます。CDM システムは、アプリに代わってペア設定 UI を提供し、位置情報の利用許可を必要としません。
ペア設定と接続のエクスペリエンスをより細かく制御する場合は、このセクションで説明する権限を使用します。
アプリが Android 12(API レベル 31)以上をターゲットとしている場合は、アプリのマニフェスト ファイルで次の権限を宣言します。
- アプリが BLE 周辺機器などの Bluetooth デバイスを検索する場合は、
BLUETOOTH_SCAN権限を宣言します。 - アプリが現在のデバイスを他の Bluetooth デバイスから検出可能にする場合は、
BLUETOOTH_ADVERTISE権限を宣言します。 - アプリがすでにペア設定されている Bluetooth デバイスと通信する場合は、
BLUETOOTH_CONNECT権限を宣言します。 - 以前の Bluetooth 関連の権限の申告については、
android:maxSdkVersionを 30 に設定します。このアプリ互換性ステップにより、Android 12 以降を搭載したデバイスにインストールされたときに、アプリに必要な Bluetooth 権限のみをシステムが付与できるようになります。 - アプリが Bluetooth スキャン結果を使用して物理的な位置情報を取得する場合は、
ACCESS_FINE_LOCATION権限を宣言します。それ以外の場合は、アプリが物理的な位置情報を取得しないことを強く表明し、ACCESS_FINE_LOCATION権限のandroid:maxSdkVersionを 30 に設定します。
BLUETOOTH_ADVERTISE、BLUETOOTH_CONNECT、BLUETOOTH_SCAN の各権限は実行時の権限です。そのため、Bluetooth デバイスを検索したり、デバイスを他のデバイスから検出可能にしたり、すでにペア設定されている Bluetooth デバイスと通信したりする前に、アプリで明示的にユーザーの承認をリクエストする必要があります。アプリがこれらの権限の少なくとも 1 つをリクエストすると、図 1 に示すように、アプリが付近のデバイスにアクセスすることを許可するよう求めるメッセージがユーザーに表示されます。
次のコード スニペットは、Android 12 以降をターゲットとするアプリで Bluetooth 関連の権限を宣言する方法を示しています。
<manifest>
<!-- Request legacy Bluetooth permissions on older devices. -->
<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
<a href="#assert-never-for-location">strongly assert that your app
doesn't derive physical location</a>. -->
<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" />
...
</manifest>
アプリが物理的な位置情報を取得しないことを強く表明する
アプリが Bluetooth スキャン結果を使用して物理的な位置情報を取得しない場合は、アプリが Bluetooth 権限を使用して物理的な位置情報を取得しないことを強く表明できます。そのための手順は次のとおりです。
android:usesPermissionFlags属性をBLUETOOTH_SCAN権限宣言に追加し、この属性の値をneverForLocationに設定します。アプリで位置情報が必要ない場合は、アプリのマニフェストから
ACCESS_FINE_LOCATION権限を削除します。
次のコード スニペットは、アプリのマニフェスト ファイルを更新する方法を示しています。
<manifest>
<!-- Include "neverForLocation" only if you can strongly assert that
your app never derives physical location from Bluetooth scan results. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<!-- Set maxSdkVersion to 30 if you can strongly assert that, on
Android 12 and higher, your app never derives physical location from
Bluetooth scan results and doesn't need location access for any other
purpose. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
...
</manifest>
Android 11 以前をターゲットとする
アプリが Android 11(API レベル 30)以前をターゲットとしている場合は、アプリのマニフェスト ファイルで次の権限を宣言します。
BLUETOOTHは、接続のリクエスト、接続の受け入れ、データの転送など、Bluetooth クラシックまたは BLE 通信を実行するために必要です。ACCESS_FINE_LOCATIONが必要なのは、Android 11 以前では、Bluetooth スキャンを使用してユーザーの位置情報を収集できる可能性があるためです。
位置情報の利用許可は実行時の権限であるため、マニフェストで宣言するとともに、実行時にこれらの権限をリクエストする必要があります。
ローカル Bluetooth デバイスを検出する
アプリでデバイス検出を開始したり、Bluetooth 設定を操作したりする場合は、BLUETOOTH_ADMIN 権限を宣言する必要があります。ほとんどのアプリでは、ローカルの Bluetooth デバイスを検出する機能のためだけにこの権限が必要です。ユーザーのリクエストに応じて Bluetooth 設定を変更する「電源管理」アプリでない限り、この権限によって付与される他の機能は使用しないでください。アプリ マニフェスト ファイルで権限を宣言します。次に例を示します。
<manifest>
...
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
...
</manifest>
アプリがサービスをサポートし、Android 10(API レベル 29)または Android 11 で実行できる場合は、Bluetooth デバイスを検出するための ACCESS_BACKGROUND_LOCATION 権限も宣言する必要があります。この要件について詳しくは、バックグラウンドでの位置情報へのアクセスをご覧ください。
次のコード スニペットは、ACCESS_BACKGROUND_LOCATION 権限を宣言する方法を示しています。
<manifest>
...
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
...
</manifest>
アプリの権限の宣言について詳しくは、<uses-permission> のリファレンスをご覧ください。
Bluetooth 機能の使用を指定する
Bluetooth がアプリの重要な要素である場合は、この要件を示すフラグをマニフェスト ファイルに追加できます。<uses-feature> 要素を使用すると、アプリが使用するハードウェアの種類と、それが必須かどうかを指定できます。
次の例は、アプリに Bluetooth クラシック が必要であることを示す方法を示しています。
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
アプリが Bluetooth Low Energy に依存している場合は、以下を使用できます。
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
アプリにその機能が必要であると指定した場合、Google Play ストアは、その機能がないデバイスを使用しているユーザーに対してアプリを非表示にします。そのため、アプリがその機能なしでは動作しない場合にのみ、required 属性を true に設定する必要があります。
実行時に機能が使用できることを確認する
クラシック Bluetooth または BLE をサポートしていないデバイスでもアプリを利用できるようにするには、アプリのマニフェストに <uses-feature> 要素を含め、required="false" を設定する必要があります。その後、実行時に PackageManager.hasSystemFeature() を使用して、機能が利用可能かどうかを判断できます。
Kotlin
// Check to see if the Bluetooth classic feature is available. val bluetoothAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH) // Check to see if the BLE feature is available. val bluetoothLEAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
Java
// Use this check to determine whether Bluetooth classic is supported on the device. // Then you can selectively disable BLE-related features. boolean bluetoothAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); // Use this check to determine whether BLE is supported on the device. Then // you can selectively disable BLE-related features. boolean bluetoothLEAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);