Bluetooth 장치가 연결되어 있는지 프로그래밍 방식으로 확인하는 방법은 무엇입니까?


87

페어링 된 장치 목록을 얻는 방법을 알고 있지만 연결되었는지 어떻게 알 수 있습니까?

내 휴대폰의 블루투스 장치 목록에 나열되고 연결 상태가 표시되므로 가능해야합니다.

답변:


156

AndroidManifest에 블루투스 권한 추가,

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

그런 다음을 듣고 텐트 필터를 사용 ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECT_REQUESTEDACTION_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는 QUERY를 허용하지 않고 대신 변경 사항을 수신 할 수 있습니다.
  • 위의 문제를 해결하는 방법은 알려진 / 페어링 된 모든 장치 목록을 검색 한 다음 각 장치에 연결을 시도하는 것입니다 (연결되어 있는지 확인하기 위해).
  • 또는 백그라운드 서비스에서 Bluetooth API를 감시하고 나중에 응용 프로그램에서 사용할 수 있도록 장치 상태를 디스크에 쓸 수 있습니다.

2
내 응용 프로그램이 실행되는 한 유용하지만 현재 목록을 얻으려면 어떻게해야합니까?
dchappelle 2011 년

2
응용 프로그램을 "실행"하지 않고 코드를 실행하려면 어떻게 계획합니까? 활동이 아닌 다른 곳에서이 서비스에 액세스해야하는 경우 ... Google Android 서비스로 이동하여 브로드 캐스트를 청취 할 서비스 중 하나를 빌드하고 목록에 유지하십시오.
Skylar Sutton

6
의도를들을 수 있지만 연결된 Bluetooth 장치의 초기 목록을 얻으려면 어떻게해야합니까? 내 활동 또는 서비스가 시작될 때 이미 연결된 경우 알 수 없습니다. 이 데이터를 어딘가에서 사용할 수 있다고 생각합니까? 이러한 의도를 듣기 위해 서비스 (전화가 켜져있는 동안 계속 실행 됨)를 만들 필요가 없습니다.
dchappelle

11
응용 프로그램 시작시 연결된 장치 목록을 검색 할 수있는 방법이 없습니다. Bluetooth API를 사용하면 연결 변경 사항 만들을 수 있습니다. 예,이를 수행하는 유일한 방법은 장기 실행 서비스를 만들고 공개 목록에 추가 / 제거하는 것입니다. 많은 개발자들의 큰 불만입니다. 성능 요구 사항에 따라 페어링 된 장치 목록을 검색하고 각 장치에 연결을 시도 할 수 있습니다. 실패하면 사용할 수 없습니다. 그러나 경고의 말씀 : .connect ()는 차단 작업입니다.
Skylar Sutton

1
한 덕분에이 답변 무리 @skylarsutton, 나 블루투스에 시작 도움이
AgentKnopf

34

제 사용 사례에서는 블루투스 헤드셋이 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

11

그의 답변에 대해 Skylarsutton에게 큰 감사를 표합니다. 나는 그의 답변으로 이것을 게시하고 있지만 나는 코드를 게시하고 있기 때문에 나는 댓글로 답할 수 없다. 나는 이미 그의 대답을 찬성했기 때문에 어떤 점도 찾고 있지 않습니다. 앞으로 지불하십시오.

어떤 이유로 BluetoothAdapter.ACTION_ACL_CONNECTED는 Android Studio에서 확인할 수 없습니다. Android 4.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

명확히 해주셔서 감사합니다!
pmont 2013-08-12

6

는, isConnected의 BluetoothDevice 시스템 API의 기능에 https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java

제한된 (페어링 된) 장치가 현재 연결되어 있는지 알고 싶다면 다음 기능이 잘 작동합니다.

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습니까?
Gumby The Green

내가 알 수 있듯이 그들은 동일한 결과를 제공합니다. Kotlin 사용자의 경우 처음 두 줄은 val m: Method = device.javaClass.getMethod("isConnected")val connected = m.invoke(device).
Gumby The Green

고마워요, 정확히 제가 필요한 것입니다! 다음은이 방법에 해당하는 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) } }
Takeya

(Class []) null 👈 멋지네요!
linjiejun

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
        }
    }
}

그런 다음 블루투스를 확인하는 동안 :

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

onSeviceConnected가 호출 될 때까지 약간의 시간이 걸립니다. 그 후에 다음에서 연결된 헤드셋 장치 목록을 얻을 수 있습니다.

mBluetoothHeadset!!.connectedDevices

0

BluetoothAdapter.getDefaultAdapter().isEnabled -> 블루투스가 열려있을 때 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.