How to programmatically tell if a Bluetooth device is connected?

前端 未结 7 1406
耶瑟儿~
耶瑟儿~ 2020-11-22 13:14

I understand how to get a list of paired devices but how can I tell if they are connected?

It must be possible since I see them listed in my phone\'s Bluetooth devi

相关标签:
7条回答
  • 2020-11-22 13:27

    In my use case I only wanted to see if a Bluetooth headset is connected for a VoIP app. The following solution worked for me:

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

    Of course you'll need the Bluetooth permission:

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

    0 讨论(0)
  • 2020-11-22 13:27

    BluetoothAdapter.getDefaultAdapter().isEnabled -> returns true when bluetooth is open

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

    audioManager.isBluetoothScoOn -> returns true when device connected

    0 讨论(0)
  • 2020-11-22 13:31

    I was really looking for a way to fetch the connection status of a device, not listen to connection events. Here's what worked for me:

    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
    }
    
    0 讨论(0)
  • 2020-11-22 13:33

    Add bluetooth permission to your AndroidManifest,

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

    Then use intent filters to listen to the ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECT_REQUESTED, and ACTION_ACL_DISCONNECTED broadcasts:

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

    A few notes:

    • There is no way to retrieve a list of connected devices at application startup. The Bluetooth API does not allow you to QUERY, instead it allows you to listen to CHANGES.
    • A hoaky work around to the above problem would be to retrieve the list of all known/paired devices... then trying to connect to each one (to determine if you're connected).
    • Alternatively, you could have a background service watch the Bluetooth API and write the device states to disk for your application to use at a later date.
    0 讨论(0)
  • 2020-11-22 13:36

    There is an isConnected function in BluetoothDevice system API in https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java

    If you want to know if the a bounded(paired) device is currently connected or not, the following function works fine for me:

    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 13:38

    This code is for the headset profiles, probably it will work for other profiles too. First you need to provide profile listener (Kotlin code):

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

    Then while checking bluetooth:

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

    It takes a bit of time until onSeviceConnected is called. After that you may get the list of the connected headset devices from:

    mBluetoothHeadset!!.connectedDevices
    
    0 讨论(0)
提交回复
热议问题