アプリで 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
権限を宣言します。それ以外の場合は、アプリが物理的な位置情報を取得しないことを強くアサートできます。
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" />
<!-- Not needed if you can strongly assert that your app never derives
physical location from Bluetooth scan results and doesn't need location
access for any other purpose. -->
<strike><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /></strike>
...
</manifest>
Android 11 以前をターゲットとする
Android 11(API レベル 30)以前をターゲットとするアプリの場合は、アプリのマニフェスト ファイルで次の権限を宣言します。
BLUETOOTH
は、接続のリクエスト、接続の受け入れ、データ転送など、Bluetooth Classic または BLE の通信を行うために必要です。- Android 11 以前では、Bluetooth スキャンを使用してユーザーの位置情報に関する情報を収集できる可能性があるため、
ACCESS_FINE_LOCATION
が必要です。
位置情報の利用許可は実行時の権限であるため、マニフェストで宣言するとともに、実行時にこれらの権限をリクエストする必要があります。
ローカルの 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 ストアは、その機能がないデバイスのユーザーにはアプリを非表示にします。このため、必須属性を 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);