2

Here I am trying to connect two android devices using Bluetooth classic and transfer calls through HFP profile.

If Device A has an incoming call, I need to notify Device B and accept/decline from the device B side and even need to talk from device B side.

I have made changes from source side in Bluetooth configs to enable A2DP sink and HF role (disabled AG role) for HFP profile in Device B.

I am confused about How AT commands works. I have to pass AT commands through output stream (Bluetooth classic connection).

Is it enough just pass AT commands(as per HFP document) to accept the call or Do I have to handle calls in the Device B side based on received AT command? I am creating an app for this work.

And also calls automatically will stream through the connection if the call accepted through AT command or Do i have to manually do something for this from the app level?

Dhina17
  • 123
  • 1
  • 8

1 Answers1

3

Android framework provide good support for HFP.

  1. AG role: BluetoothHeadset. Most phone act as AG role, and the phone app will call BluetoothHeadset API to act as AG role. This profile is enabled by default.
  2. HF role: BluetoothHeadsetClient. This API is hided, cannot be used by third apps. For most phone, no app will handle as HF role. So you need to develep an APP to do this. And android cars, it can act as HF role to connect with an phone. There is an example from AOSP CarSystemUI. This profile is disabled by default. You should enable this profile by overlay profile_supported_hfpclient to ture.

As how to act as an HF role:

  • Connect to the HFP profile, get an BluetoothHeadsetClient:

    private BluetoothHeadsetClient mBluetoothHeadsetClient;
    private final ServiceListener mHfpServiceListener = new ServiceListener() {
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (profile == BluetoothProfile.HEADSET_CLIENT) {
                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
            }
        }

        @Override
        public void onServiceDisconnected(int profile) {
            if (profile == BluetoothProfile.HEADSET_CLIENT) {
                mBluetoothHeadsetClient = null;
            }
        }
    };

   mAdapter.getProfileProxy(context.getApplicationContext(), mHfpServiceListener,
     BluetoothProfile.HEADSET_CLIENT);

  • Connect to the remote device:
   mBluetoothHeadsetClient.connect(remoteDevice)
  • Monitor the connection status, call changes, ag events:
   IntentFilter filter = new IntentFilter();
   filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
   filter.addAction(BluetoothHeadsetClient.ACTION_AG_EVENT);
        mContext.registerReceiver(this, filter);
   filter.addAction(BluetoothHeadsetClient.ACTION_CALL_CHANGED);
        mContext.registerReceiver(this, filter);
  • Trigger an call, accept an call or send vendor AT command:
   mBluetoothHeadsetClient.dail
   mBluetoothHeadsetClient.acceptCall
   mBluetoothHeadsetClient.sendVendorAtCommand

Android provide high level APIs, and you don't need to send a AT comand to accept the call.

Jaroslav Záruba
  • 4,694
  • 5
  • 39
  • 58
Yong
  • 1,529
  • 12
  • 21
  • Please Can you provide any example for this? So I don't need any specific app to handle this in HF role device side? Still confused. Can you please update your answer with more explanation? How to handle AT commands and all – Dhina17 Aug 11 '21 at 11:18
  • Has improved with more details – Yong Aug 12 '21 at 03:05
  • Found an example in github: https://github.com/lbdroid/HFPClient – Yong Aug 12 '21 at 08:34
  • Thank you. Just enabling the overlay https://github.com/Dhina17/android_device_xiaomi_onclite/commit/b628306cdfd8a7252fa4e58069aabe5710902374 did the work fine what i wanted to do. And its helpful to understand how hfp works in android. Thank you – Dhina17 Aug 12 '21 at 08:47