Sending DTMF tones over the uplink in-call

Simon McCorkindale picture Simon McCorkindale · Jun 14, 2011 · Viewed 25.9k times · Source

I'm working on a project that requires my app to be able to send DTMF tones on the voice's uplink frequency during an active call.

My 2 conditions are:

  • We don't use a customized Android platform
  • We don't need to root the phone

I've spent several days doing my homework and am aware that in-call DTMF sending is not supported by the current SDK/standard APIs. However, by using the relevant classes in com.android.internal.telephony I am hoping to mimic how the native Phone app does this. I followed this site on how to use internal APIs for standard 3rd party apps.

I've also set myself up with the Android OS dev environment and am able to run the Phone app in debug mode on an emulator to figure its inner workings.

I tried various ways on a stock standard emulator but the errors I got were:

  1. After trying to install a renamed app based on Phone.apk's source using the sharedUserId of android.uid.phone, I got:

    Installation error: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE

    No doubt due to the fact I don't have the system cert to sign it.

  2. After trying to write a custom app based on the relevant DTMF tone sending code from Phone.apk's source, I get the following error at setting up the PhoneFactory;

    java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.provider.Telephony.SPN_STRINGS_UPDATED.

    No doubt due to the fact my app doesn't have the right permissions, although AndroidManifest.xml is setup with the same permissions as Phone.apk.

I'm at a loss as to what else I could try. Does anyone have any suggestions?

Thanks in advance, Simon.

Answer

Paul Lammertsma picture Paul Lammertsma · Jul 5, 2011

You've taken an interesting approach, and I commend your efforts. Unfortunately, there are some reserved internal privileges (evidently, such as SPN_STRINGS_UPDATED) that you aren't allowed to use as an app developer, which more or less breaks this approach. You could try removing the area of code causing this, but I'm fairly certain you will run into a blocking problem.

Hence, I'm afraid this is not possible at the moment. There's an open feature request on Android for sending DTMF tones over an existing phone call, but it has been dormant there for almost two years.

I understand that this doesn't resolve your problem, but take note that you can send DTMF tones directly after dialing a number:

Intent i = new Intent("android.intent.action.CALL",
                      Uri.parse("tel://" + number + "," + dtmfTones));