Bluetoothデバイスが接続されているかどうかをプログラムで確認するにはどうすればよいですか?


86

ペアリングされたデバイスのリストを取得する方法を理解していますが、それらが接続されているかどうかを確認するにはどうすればよいですか?

それらが私の電話のBluetoothデバイスリストにリストされているのを見て、それらの接続ステータスを示しているので、それは可能であるに違いありません。

回答:


155

AndroidManifestにBluetooth権限を追加します。

<uses-permission android:name="android.permission.BLUETOOTH" />

その後に耳を傾けるためにインテントフィルタを使用しACTION_ACL_CONNECTEDACTION_ACL_DISCONNECT_REQUESTED、およびACTION_ACL_DISCONNECTED放送:

public void onCreate() {
    ...
    IntentFilter filter = new IntentFilter();
    filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
    filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
    filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
    this.registerReceiver(mReceiver, filter);
}

//The BroadcastReceiver that listens for bluetooth broadcasts
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
           ... //Device found
        }
        else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
           ... //Device is now connected
        }
        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
           ... //Done searching
        }
        else if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
           ... //Device is about to disconnect
        }
        else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
           ... //Device has disconnected
        }           
    }
};

いくつかの注意:

  • アプリケーションの起動時に接続されているデバイスのリストを取得する方法はありません。Bluetooth APIではクエリを実行できませんが、代わりに変更を聞くことができます。
  • 上記の問題の厄介な回避策は、すべての既知の/ペアリングされたデバイスのリストを取得してから、それぞれに接続しようとすることです(接続されているかどうかを判断するため)。
  • または、バックグラウンドサービスでBluetooth APIを監視し、デバイスの状態をディスクに書き込んで、アプリケーションが後日使用できるようにすることもできます。

2
これは、アプリケーションが実行されている限り有効ですが、現在のリストを取得するにはどうすればよいですか?
dchappelle 2011年

2
アプリケーションを「実行」せずにコードを実行することをどのように計画していますか?アクティビティ以外からこれにアクセスする必要がある場合は、Google Androidサービスにアクセスし、ブロードキャストを聞くためのサービスの1つを作成して、リストに保持します。
スカイラーサットン

6
インテントを聞くことはできますが、接続されているBluetoothデバイスの初期リストを取得するにはどうすればよいですか?アクティビティまたはサービスが開始されるまでにすでに接続されているものがあるかどうかはわかりません。このデータがどこかで利用できると想像しますか(願っています)?これらの意図を聞くためだけに、サービス(電話がオンになっている限り常に実行される)を作成する必要はありません。
dchappelle 2011年

11
アプリケーションの起動時に接続されているデバイスのリストを取得する方法はありません。Bluetooth APIでは、接続の変更のみを聞くことができます。そうです、それを行う唯一の方法は、長時間実行されるサービスを作成し、パブリックリストに追加/削除することです。多くの開発者からの大きな不満です。パフォーマンスのニーズに応じて、ペアリングされたデバイスのリストを取得して、それぞれに接続してみることができます。失敗した場合は利用できません。ただし、警告の言葉:.connect()はブロッキング操作です。
スカイラーサットン

1
@skylarsutton +1この回答をたくさんありがとう、Bluetoothの使用を開始するのに役立ちました
AgentKnopf 2012

33

私のユースケースでは、BluetoothヘッドセットがVoIPアプリに接続されているかどうかだけを確認したかったのです。次の解決策は私のために働いた:

public static boolean isBluetoothHeadsetConnected() {
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()
            && mBluetoothAdapter.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothHeadset.STATE_CONNECTED;
} 

もちろん、Bluetoothの許可が必要です。

<uses-permission android:name="android.permission.BLUETOOTH" />


2
これは私が探していたものです。起動時にBluetoothが接続されているかどうかを確認するだけです。うまくいったありがとう!
sud007 2017

11

Skylarsuttonの回答に感謝します。彼への返信として投稿していますが、コードを投稿しているためコメントとして返信できません。私はすでに彼の答えに賛成しているので、何のポイントも探していません。ただそれを前払いします。

何らかの理由で、BluetoothAdapter.ACTION_ACL_CONNECTEDをAndroidStudioで解決できませんでした。おそらくそれはAndroid4.2.2で非推奨になりましたか?これが彼のコードの修正です。登録コードは同じです。レシーバーコードはわずかに異なります。これは、アプリの他の部分が参照するBluetooth接続フラグを更新するサービスで使用します。

    public void onCreate() {
        //...
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        this.registerReceiver(BTReceiver, filter);
    }

    //The BroadcastReceiver that listens for bluetooth broadcasts
    private final BroadcastReceiver BTReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
            //Do something if connected
            Toast.makeText(getApplicationContext(), "BT Connected", Toast.LENGTH_SHORT).show();
        }
        else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
            //Do something if disconnected
            Toast.makeText(getApplicationContext(), "BT Disconnected", Toast.LENGTH_SHORT).show();
        }
        //else if...
    }
};

1
あなたのコードは正しいです。4.2.2では非推奨ではありませんでした。BluetoothAdapterクラスには、ACTION_ACL_CONNECTEDが含まれていません。その文字列はBluetoothDeviceクラスにあります。
RobLabs 2013

それを明確にしてくれてありがとう!
pmont 2013

4

https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.javaのBluetoothDeviceシステムAPIにisConnected関数があります

有界(ペア)デバイスが現在接続されているかどうかを知りたい場合は、次の関数が正常に機能します。

public static boolean isConnected(BluetoothDevice device) {
    try {
        Method m = device.getClass().getMethod("isConnected", (Class[]) null);
        boolean connected = (boolean) m.invoke(device, (Object[]) null);
        return connected;
    } catch (Exception e) {
        throw new IllegalStateException(e);
    }
}

これが単にチェックするのとは異なる結果をもたらすのを見たことがありますかbluetoothManager.getConnectionState(device, BluetoothProfile.GATT) == BluetoothProfile.STATE_CONNECTED
ガンビーザグリーン

私が言えることから、彼らは同じ結果をもたらします。Kotlinユーザーの場合、最初の2行はちょうどval m: Method = device.javaClass.getMethod("isConnected")andval connected = m.invoke(device)です。
ガンビーザグリーン

ありがとう、まさに私が必要としていたもの!これは、このメソッドのkotlin同等です:fun isConnected(device: BluetoothDevice): Boolean { return try { val m: Method = device.javaClass.getMethod( "isConnected" ) m.invoke(device) as Boolean } catch (e: Exception) { throw IllegalStateException(e) } }
タケヤ

1

このコードはヘッドセットプロファイル用であり、おそらく他のプロファイルでも機能します。まず、プロファイルリスナー(Kotlinコード)を提供する必要があります。

private val mProfileListener = object : BluetoothProfile.ServiceListener {
    override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
        if (profile == BluetoothProfile.HEADSET) 
            mBluetoothHeadset = proxy as BluetoothHeadset            
    }

    override fun onServiceDisconnected(profile: Int) {
        if (profile == BluetoothProfile.HEADSET) {
            mBluetoothHeadset = null
        }
    }
}

次に、Bluetoothをチェックしながら:

mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET)
if (!mBluetoothAdapter.isEnabled) {
    return Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
}

onSeviceConnectedが呼び出されるまで少し時間がかかります。その後、接続されているヘッドセットデバイスのリストを次の場所から取得できます。

mBluetoothHeadset!!.connectedDevices

0

BluetoothAdapter.getDefaultAdapter().isEnabled -> Bluetoothが開いているときにtrueを返します

val audioManager = this.getSystemService(Context.AUDIO_SERVICE) as AudioManager

audioManager.isBluetoothScoOn ->デバイスが接続されている場合はtrueを返します


0

接続イベントをリッスンするのではなく、デバイスの接続ステータスを取得する方法を本当に探していました。これが私のために働いたものです:

BluetoothManager bm = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
List<BluetoothDevice> devices = bm.getConnectedDevices(BluetoothGatt.GATT);
int status = -1;

for (BluetoothDevice device : devices) {
  status = bm.getConnectionState(device, BLuetoothGatt.GATT);
  // compare status to:
  //   BluetoothProfile.STATE_CONNECTED
  //   BluetoothProfile.STATE_CONNECTING
  //   BluetoothProfile.STATE_DISCONNECTED
  //   BluetoothProfile.STATE_DISCONNECTING
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.