BluetoothHeadsetClient: Could not bind to Bluetooth Headset Client Service with Intent

3.7k Views Asked by At

I want to use the BluetoothHeadsetClient. in order to use this hidden SDK code I use reflection.

I want to call

mBluetoothAdapter.getProfileProxy(this, mHeadsetProfileListener, BluetoothProfile.HEADSET_CLIENT);

but BluetoothProfile.HEADSET_CLIENT is hidden in BluetoothProfile.java. in order to solve it I run the following code

protected BluetoothProfile.ServiceListener mHeadsetProfileListener = new  BluetoothProfile.ServiceListener()
{
    @Override
    public void onServiceDisconnected(int profile) {            

    }

    @Override
    public void onServiceConnected(int profile, BluetoothProfile proxy)
    {

        mlisten = mHeadsetProfileListener;
        mHeadSetCleintObj = proxy;

        // reflection for getting the HEADSET_CLIENT type
        try {

            Class classRef = Class.forName("android.bluetooth.BluetoothProfile");
            Field field = classRef.getField("HEADSET_CLIENT");                
            if(profile == BluetoothProfile.HEADSET ) {
                mBluetoothAdapter.getProfileProxy(getApplicationContext(), mHeadsetProfileListener, field.getInt(proxy));
            }

        }
        catch (Exception e) {
            e.printStackTrace();
        }

        mBluetoothHeadset.getConnectedDevices();

    }
};


@Override
public void onDestroy() {
    unregisterReceiver(mPairReceiver);

    super.onDestroy();
}

field.getInt(proxy) value == 16 --> BluetoothProfile.HEADSET_CLIENT as I wanted. but when I run the

mBluetoothAdapter.getProfileProxy(getApplicationContext(), mHeadsetProfileListener, field.getInt(proxy));

I see the following error

E/BluetoothHeadsetClient﹕ Could not bind to Bluetooth Headset Client Service with Intent { act=android.bluetooth.IBluetoothHeadsetClient }

do you know how to solve this type of error?

Thanks!

2

There are 2 best solutions below

0
David On

I found an API from robolectric which makes the hidden parts of the API visible. You could use it with scope provided in your build.gradle.

provided 'org.robolectric:android-all:5.0.0_r2-robolectric-1'

Unfortunately I'm also not able to get a working proxy, but debugging into BluetoothHeadsetClient shows that doBind ist successfully called. In my case, onServiceConnected from BluetoothProfile.ServiceListener is never called and so the "working" proxy is never returned to my activity.

0
tchelidze On

Probably, problem is calling mBluetoothAdapter.getProfileProxy(getApplicationContext(), mHeadsetProfileListener, field.getInt(proxy)); from inside BluetoothProfile.ServiceListener.onServiceConnected.

Following works :

try {
  final int Bluetooth_Profile_HEADSET_CLIENT = 
      (int) BluetoothProfile.class.getField("HEADSET_CLIENT").get(null);

  BluetoothProfile.ServiceListener mProfileListener = 
     new BluetoothProfile.ServiceListener() {
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
          if (profile == Bluetooth_Profile_HEADSET_CLIENT) {
              //proxy is BluetoothHeadsetClient
          }
       }

       public void onServiceDisconnected(int profile) {

       }
 };

  BluetoothAdapter
          .getDefaultAdapter()
          .getProfileProxy(this, mProfileListener, Bluetooth_Profile_HEADSET_CLIENT);
}catch(Exception ex) {}