Using telecomManager with our custom protocol

2019-08-08 10:29发布

问题:

I`m trying to implement interconnection with telecom service with this guide: https://developer.android.com/guide/topics/connectivity/telecom/

I'm are already can show my own fullscreen incoming call UI without Telecom service, make and receive video calls. All, that I want to do with Telecomservice, is just tell Android OS, that our application is starting/stopping video call in particular moment, and receive call holded/unholded events from other calling apps.

The main problems are:

1) addNewIncomingCall in case of incoming call does nothing: onCreateIncomingConnection callback not fired (even onCreate callback of mine ConnectionService not fired at all). Why connection service is not started?

2) in case of outgoing call placeCall tries to open system calling app with our user id, call it as phone or SIP number. Can I use placeCall without system UI?

Or, if I just want to inform system about video call, I can use other option than TelecomService?

Connection created as follows:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        connection?.connectionProperties = Connection.PROPERTY_SELF_MANAGED
    }
    connection?.connectionCapabilities = Connection.CAPABILITY_HOLD and Connection.CAPABILITY_SUPPORT_HOLD
    connection?.setVideoState(VideoProfile.STATE_BIDIRECTIONAL)

Placing call:

val telecomService = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
                    try {
                        val uri = Uri.fromParts(PhoneAccount.SCHEME_SIP, teacherInfo.name, null)
                        telecomService.placeCall(uri, Bundle.EMPTY)
                    } catch (e: Throwable) {
                        e.printStackTrace()
                    }

Receiving call:

val telecomService = applicationContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
                      try {
                          Log.d("VideoCOnnection", "addNewIncomingCall")
                          telecomService.addNewIncomingCall(CallUtils.getAccountConnection(telecomService), Bundle.EMPTY)
                      } catch (e: Throwable) {
                          Log.d("VideoCOnnection", "crash")
                          e.printStackTrace()
                      }


@SuppressLint("MissingPermission")
fun getAccountConnection(teleconManager: TelecomManager) : PhoneAccountHandle? {
    return if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val enabledAccounts = teleconManager.callCapablePhoneAccounts
        for(account in enabledAccounts) {
            if(account.componentName.className.equals(BindTelecomService::class.java.canonicalName)) {
                return account
            }
        }
        return null
    } else
        null
}

回答1:

https://github.com/pranksterN1/TComTest https://stackoverflow.com/users/4466771/prankstern1 posted this example, which worked, but I still can not find, what's wrong with my code:) Additional Services, such as CallService from example is used for connection listening only, and can be replaced with GreenRobot's eventbus or Rx for simplification



回答2:

Looks like you want to implement the app with self-managed connection service.

Check that you have permissions:

  • MANAGE_OWN_CALLS
  • READ_CALL_LOG
  • READ_PHONE_STATE

Register the phone account with CAPABILITY_SELF_MANAGED.

final String phoneAccountLabel = "myPhoneApp";

ComponentName connectionServiceName = new ComponentName(context.getApplicationContext(), TcService.class);
accountHandle = new PhoneAccountHandle(connectionServiceName, phoneAccountLabel);

PhoneAccount phoneAccount = telecom.getPhoneAccount(accountHandle);
if (phoneAccount == null) {
    PhoneAccount.Builder builder = PhoneAccount.builder(accountHandle, phoneAccountLabel);
    builder.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED);
    phoneAccount = builder.build();
    telecom.registerPhoneAccount(phoneAccount);
}

When you add new incoming or outgoing calls, you must add extra EXTRA_PHONE_ACCOUNT_HANDLE.

Uri uri = generateCallUri();
extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
telecom.addNewIncomingCall(accountHandle, extras);

Update: there is an example