How to (actually) send DTMF on Android without being the default call app

39 EDM115 30 6/6/2025, 11:29:11 AM edm115.dev ↗

Comments (30)

frankus · 8h ago
I imagine the requirement to be the default phone app is in part to prevent rogue apps from colluding with rogue expensive-toll-services to place calls to them without the user's authorization.
bobbiechen · 2h ago
It's not hard for apps to commit toll fraud - all it takes is sending SMS or phone calls programmatically. Here's the Google Play page on billing fraud: https://developers.google.com/android/play-protect/phacatego... , and a writeup about malware used for WAP billing fraud: https://www.humansecurity.com/learn/blog/satori-perpectives-... .
viraptor · 1h ago
I don't think that applies here. You get billed for the connection. But you can't send DTMF without being already connected (not in the GSM world anyway), so this can't affect the call billing.
edent · 5h ago
There is a sort of way around this.

You can generate phone numbers with embedded DTMF codes - including pause and wait.

For example `<a href="tel:+447700900000,12#">` will pre-fill the dialler with that number. After dialling, it will pause for a few seconds then sent DTMF 1 2 #.

You can make it slightly interactive with the "wait" command. For example `<a href="tel:+447700900000;#9">`. The semicolon should* give the user a prompt asking them if they want to send the DTMF `#9`.

Of course, this is no use if the app is to be used interactively. But if you know that you need to send a predefined sequence, it is useful.

DoctorOW · 4h ago
I knew about the comma, but not about the semicolon. Very cool information!
EDM115 · 5h ago
yes, this is particularly useful ! but sadly yep, the app needs to be interactive as it's basically users controlling their phone using their pc, and a much bigger screen :)
shawnz · 9h ago
It seems totally reasonable to me that arbitrary apps can't insert sounds into my call audio, am I wrong here? And this app is most certainly an accessibility app so it makes sense that it would have to take advantage of the accessibility permissions to do this kind of thing
SkyeCA · 4h ago
> It seems totally reasonable to me that arbitrary apps can't insert sounds into my call audio, am I wrong here?

No, though I will say I'm upset with how protected calls have become on phones in recent years. I used to record every phone call with an app so I had a record of it, something which is completely legal to do where I live, but that really isn't possible anymore.

Now all my calls go through a VOIP provider and call recording is a feature they offer.

genewitch · 1h ago
I could never figure out how to get call recording to work on 3cx, after the end of android call recording.

So a trrs plug splitter I can record to a tascam. And use a fancy mic.

Still, nicer to press a big record button, by a lot.

jeroenhd · 8h ago
I think isolating the call stream to authorised apps makes a lot of sense. Using a accessibility feature to make accessibility work seems like the right solution to this problem. The initial hack (just injecting tones into the system) sounds like a bad solution to be honest.

For other advanced stuff you have to be the default dialer app which also makes a lot of sense. If you're going to be an accessible dialer, you may as well actually communicate to the system that that is what you are. With plenty of open source dialer apps to borrow from, I don't expect the burden to even be that high.

Interestingly, the post writes that the app communicates with the phone over ADB. I wonder if you could just inject keypad button presses using adb, so the app doesn't need to even be an accessibility service to get the tones across? Although I guess that only works if the dialer is in the foreground.

EDM115 · 5h ago
from my searches, sadly ADB doesn't allow for it :(
deepsun · 6h ago
Well, unless it's the app that makes the call.

But AFAIK both Android and iOS disabled all call apps except for their own.

Previously they allowed as long as the keypad looked "distinctively different from the default call app", but turned that off some time ago. I can see the security reasoning, but still think there were ways to make it possible and secure.

A similar question, for example, is how to record a call, default or not. AFAIK there's no way.

shawnz · 6h ago
Android supports third party dialer apps and the article notes that this is one way you can overcome the problem (but they didn't want to take that route because entirely replacing the dialer is out of scope for their app)
1970-01-01 · 5h ago
kelnos · 4h ago
That app doesn't allow you to inject the tones into an in-progress call; it just plays the tone. If the phone is in speakerphone mode it might work, though would probably still be unreliable. If not, then it just won't work.
ajb · 4h ago
Yeah, the echo canceller is going to try to make that not work, and DTMF tones are simple enough that it will likely succeed.
nancyminusone · 10h ago
I'm going to assume this is more complex than generating DTMF tones yourself and injecting them into the audio stream?
imurray · 9h ago
> generating DTMF tones yourself and injecting them into the audio stream?

When I was an undergrad I had an audio file for each digit and a winamp playlist for each of my frequently dialed numbers. I'd hold my (landline) phone against the computer speakers and double-click the playlist to dial. I'm sure I spent more time setting this up than it ever saved, but it was somehow pleasing that this ridiculously over-powered speed dialer worked.

gh02t · 6h ago
Back in the days of phone line modems, there used to be a program that you could type in a number, the modem would emit the corresponding tones, and then you could pick up a phone and it'd already be connected. I can't remember what the one I saw was, but I'm sure there were multiple different ones, and I also vaguely recall there were dedicated physical machines that could before that.
neckro23 · 5h ago
You could do this with any terminal program. Your modem won't emit any noise until it hears a carrier tone, so you could just dial, pick up the extension, hang up the modem.
genewitch · 9h ago
click. click. click-click-click-click-click-click-click.

...

...

PROCTOR TEST SET PLEASE SELECT TEST

LINE TEST PRESS 2

COIN RETURN TEST PRESS 3

COIN READER TEST PRESS 4

TONE TEST PRESS 5

ADDITIONAL TESTS PRESS 6

|

this isn't the one i referenced, but proves my memory is functional https://youtu.be/uOO9dFiwzGk - actually it has references to what i typed

No comments yet

jcrawfordor · 4h ago
There's a few different reasons things are more complex, but one interesting wrench to throw in is that audio tones may not be the best way to send DTMF. Many digital telephone networks support out-of-band DTMF where the digits are sent as digital keypress events instead of actual tones (tones are usually still emitted to the user for comfort). There are a few potential benefits but mostly it improves reliability over iffy connections, reducing instances of one press being detected as two due a dropout in the middle, for example. I believe 3GPP has supported out-of-band DTMF for some time but it may not have been common, VoLTE encourages it much more. The other end is always going to have support for traditional in-band DTMF because they don't know what type of connection the caller has, so it's not a fatal problem, but less than ideal to use in-band DTMF when out-of-band DTMF is supported. This type of consideration is one of the reasons that the telephony part of phones is more complicated than you might think.
jeroenhd · 8h ago
If you are the dialer app, you could generate DTMF tones, yes.

If you want to do dialer things without being the dialer, then no. Android doesn't permit apps to access the audio streams of a call to non-dialer apps.

In this case, the solution was to use an accessibility service to perform accessibility tasks as an accessibility app. Quite appropriate, I think. Although it will fail if the dialer of your choice doesn't have a keypad with the exact right labels (or numbers? I don't know if phones in writing systems with alternative numbers still show Arabic numerals on the dialer).

EDM115 · 5h ago
indeed, non latin characters will probably fuck up my solution :(
cmrx64 · 10h ago
yes, the solution presented in the article ultimately ends up using the accessibility APIs to click buttons in the dialer, due to restrictions on non-default-call apps
EDM115 · 8h ago
well technically you can, and a quick google search leads to apps that do this. but when you aren't in speakerphone mode, well the sound isn't loud enough to be properly processed on the other end of the line
subarctic · 2h ago
DTMF = Dual-tone multi-frequency signaling, not to be confused with the song by Bad Bunny
jeffrallen · 7h ago
I was hoping this guy was going to go deep down under the JRE and find out how to do it with raw system calls.
EDM115 · 5h ago
it was a school project so I had not the time nor the expertise to do it
coolestguy · 4h ago
What's the feasibility of taking an existing default calling app & adding the real way to do DTMF, then making the user forced to use this app as the default calling app.

E.g. the calling app from AOSP, LineageOS or GrapheneOS