Sending DTMF tones over the uplink in-call

2019-01-13 08:33发布

问题:

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.

回答1:

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


回答2:

Simply put, you won't be able to do it without customizing at least the Phone app, which has to run as a system user in order to access the modem. In order to do this, you have to root your phone.

To meet your requirements the only possible solution is to enhance the android platform. We did just that, and already sent in our patches to the AOSP project:

https://android-review.googlesource.com/32820

https://android-review.googlesource.com/32821

We are currently waiting for the Google developers to review and accept our contribution. If you are interested, please let Google know on the various AOSP lists (android-contrib, android-platform). It will hopefully expedite the review.

Best Regards, Gergely



回答3:

You can't send DTMF tones during an active call, but you can send them when you "program" them when you initiate the call. see the following post: https://stackoverflow.com/a/12986066/475472