Bluetooth デバイスを探す

BluetoothAdapter を使用して、 リモートの Bluetooth デバイスは、デバイスの検出または ペア設定したデバイスのリストをクエリする。

適切な Bluetooth の権限があることを確認します。 アプリを Bluetooth 対応に設定 確認してください。

デバイス検出とは、ローカルエリアで Bluetooth が有効なデバイスであり、各デバイスに関する情報をリクエストします。この 検出、照会、スキャンとも呼ばれます。 近くにある Bluetooth デバイスは、次の場合にのみ検出リクエストに応答します。 情報リクエストを受け付けることができます。デバイスが 検出可能な場合、いくつかの情報を共有して検出リクエストに応答します。 (デバイスの名前、クラス、一意の MAC アドレスなど)にアクセスできます。こちらの 検出プロセスを実行しているデバイスは 検出されたデバイスへの接続を開始します。

検出可能なデバイスによってユーザーの現在地に関する情報が提供される場合があるため、 デバイス検出プロセスには位置情報へのアクセスが必要です。アプリが使用中の場合 Android 8.0(API レベル 26)以降を搭載しているデバイスを使用する場合は、 コンパニオン デバイス マネージャー API を使用してください。この API アプリに代わってデバイスの検出を実行するため、アプリが 位置情報の利用許可をリクエストします。

リモート デバイスと初めて接続すると、ペア設定が ユーザーに自動的に表示されます。デバイスをペア設定すると、 そのデバイスの基本情報(デバイスの名前、クラス、MAC など) 保存され、Bluetooth API を使用して読み取ることができます。既知の MAC を使用する 指定した場合、そのアドレスを使用していつでも接続を開始できます。 デバイスがまだ通信範囲内にあることを前提とします。

なお、ペア設定と接続には違いがあります。

  • ペア設定とは、2 つのデバイスが互いの存在を認識していることを意味します。 認証に使用できる共有リンクキーが用意されている。 相互に暗号化された接続を確立します
  • 「接続」とは、デバイスが現在 RFCOMM チャネルを共有しており、 相互にデータを転送できます現在の Bluetooth RFCOMM 接続を行うには、API でデバイスをペア設定する必要があります あります。暗号化された通信を開始すると、自動的にペア設定されます Bluetooth API と接続します

以下のセクションでは、ペア設定されたデバイスを探す方法について説明します。 デバイス検出を使用して新しいデバイスを検出する。

ペア設定したデバイスをクエリする

デバイス検出を実行する前に、ペアに設定されたペアを 目的のデバイスがすでに認識されているかどうかを確認します。これを行うには、 getBondedDevices()。 このメソッドは、 BluetoothDevice オブジェクト ペア設定されたデバイスを表します。たとえば、ペア設定されたすべてのデバイスをクエリし、 次のコード スニペットのように、各デバイスの名前と MAC アドレスを取得します。 以下を示しています。

Kotlin

val pairedDevices: Set<BluetoothDevice>? = bluetoothAdapter?.bondedDevices
pairedDevices?.forEach { device ->
   val deviceName = device.name
   val deviceHardwareAddress = device.address // MAC address
}

Java

Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();

if (pairedDevices.size() > 0) {
   // There are paired devices. Get the name and address of each paired device.
   for (BluetoothDevice device : pairedDevices) {
       String deviceName = device.getName();
       String deviceHardwareAddress = device.getAddress(); // MAC address
   }
}

Bluetooth デバイスと接続を開始するには、 関連付けられた BluetoothDevice オブジェクトは MAC アドレスであり、 通話中 getAddress()。マイページ 接続の作成について詳しくは、Bluetooth を接続する 。

デバイスの検出

デバイスの検出を開始するには、 startDiscovery()。 この処理は非同期で、 検出が開始されました。調査プロセスは通常 約 12 秒の問い合わせスキャンの後に、検出された各デバイスのページスキャンが実行される Bluetooth 名を取得します。

検出された各デバイスに関する情報を受け取るには、アプリで BroadcastReceiverACTION_FOUND 使用します。このインテントは、システムによってデバイスごとにブロードキャストされます。インテントには次のものが含まれます。 追加フィールド EXTRA_DEVICEEXTRA_CLASS さらに BluetoothDeviceBluetoothClass。 次のコード スニペットは、ブロードキャストを処理するよう登録する方法を示しています。 デバイスが発見された場合:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
   ...

   // Register for broadcasts when a device is discovered.
   val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
   registerReceiver(receiver, filter)
}

// Create a BroadcastReceiver for ACTION_FOUND.
private val receiver = object : BroadcastReceiver() {

   override fun onReceive(context: Context, intent: Intent) {
       val action: String = intent.action
       when(action) {
           BluetoothDevice.ACTION_FOUND -> {
               // Discovery has found a device. Get the BluetoothDevice
               // object and its info from the Intent.
               val device: BluetoothDevice =
                       intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
               val deviceName = device.name
               val deviceHardwareAddress = device.address // MAC address
           }
       }
   }
}

override fun onDestroy() {
   super.onDestroy()
   ...

   // Don't forget to unregister the ACTION_FOUND receiver.
   unregisterReceiver(receiver)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
   ...

   // Register for broadcasts when a device is discovered.
   IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
   registerReceiver(receiver, filter);
}

// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
   public void onReceive(Context context, Intent intent) {
       String action = intent.getAction();
       if (BluetoothDevice.ACTION_FOUND.equals(action)) {
           // Discovery has found a device. Get the BluetoothDevice
           // object and its info from the Intent.
           BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
           String deviceName = device.getName();
           String deviceHardwareAddress = device.getAddress(); // MAC address
       }
   }
};

@Override
protected void onDestroy() {
   super.onDestroy();
   ...

   // Don't forget to unregister the ACTION_FOUND receiver.
   unregisterReceiver(receiver);
}

Bluetooth デバイスとの接続を開始するには、getAddress()BluetoothDevice: 関連付けられた MAC アドレスを取得します。

検出の許可を有効にする

他のデバイスがローカル デバイスを検出できるようにするには、 startActivityForResult(Intent, int) 新しい ACTION_REQUEST_DISCOVERABLE 使用します。システムの検出可能モードを有効にするよう求めるリクエストが発行されます。 設定アプリに移動する必要があり、そのためアプリが停止します。方法 デフォルトでは、デバイスは 2 分間検出可能になります。「新規顧客の獲得」目標を 最大 1 時間までさまざまに変更できます。 EXTRA_DISCOVERABLE_DURATION 追加できます

次のコード スニペットでは、デバイスが 5 分間検出可能になるように設定しています。

Kotlin

val requestCode = 1;
val discoverableIntent: Intent = Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE).apply {
   putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300)
}
startActivityForResult(discoverableIntent, requestCode)

Java

int requestCode = 1;
Intent discoverableIntent =
       new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivityForResult(discoverableIntent, requestCode);


図 2: 検出の許可設定の有効化ダイアログ

ユーザーにデバイスの作成を許可するよう求めるダイアログが表示されます。 できます。ユーザーが [Allow](許可)という応答を返した場合、次に 指定の時間の間、デバイスが検出可能になります。その後のアクティビティ 着信があると onActivityResult() デバイスが完了するまでの時間と同じ結果コードを 見つけやすいようにします。ユーザーが [拒否] と返信した場合、またはエラーが発生した場合は、 コードは RESULT_CANCELED です。

デバイスは、割り当てられた時間の間、検出可能なモードのままになります。今後 検出可能なモードが変更されたときに通知されるように、BroadcastReceiver を登録 の ACTION_SCAN_MODE_CHANGED 使用します。このインテントには追加フィールドが含まれています EXTRA_SCAN_MODE および EXTRA_PREVIOUS_SCAN_MODE, それぞれ新しいスキャンモードと古いスキャンモードを指定します。各値に指定できる値 エクストラは次のとおりです。

SCAN_MODE_CONNECTABLE_DISCOVERABLE
デバイスが検出可能モードになっています。
SCAN_MODE_CONNECTABLE
デバイスが検出可能モードではないものの、接続は受信できる場合。
SCAN_MODE_NONE
デバイスが検出可能モードになっておらず、接続を受信できません。

リモート デバイスへの接続を開始する場合は、 デバイスの検出の許可を有効にする。検出の許可は、次の場合にのみ必要です。 受信リクエストを受け付けるサーバー ソケットをアプリでホストし、 接続を維持する必要があります。これは、リモート デバイスが事前に他のデバイスを 接続を開始します