FrankenKeys can dictate with the aerial off. Airplane mode, microphone key, talk. That is true, and it is also the sentence most likely to be read as more than it says, so this post follows the audio from your mouth to the text field and names every process it passes through.
The keyboard never touches audio
FrankenKeys does not record. It holds the RECORD_AUDIO permission because Android requires the calling app to hold it before a speech recogniser will listen on its behalf, but the capture happens inside the recogniser service, which is a separate app in a separate process. What comes back to the keyboard is text: partial results while you speak, a final result when you pause, and a ranked list of alternatives for each segment so you can tap a word and pick the other reading.
No audio buffer ever exists in the FrankenKeys process. There is nothing to store and, with no network permission, nothing it could be sent with.
Android 12 and later: on-device or nothing
On API 31 and up, Android has a factory method, SpeechRecognizer.createOnDeviceSpeechRecognizer, whose documentation says it returns "a new on-device SpeechRecognizer" and throws if isOnDeviceRecognitionAvailable is false. FrankenKeys calls that method and only that method. If the phone has no on-device recogniser, the microphone key reports "no offline recogniser" and does nothing. It never falls back to the ordinary recogniser on these versions, because the ordinary one may use the network and the point of the feature is that it does not.
Android 10 and 11: a preference, not a guarantee
FrankenKeys runs on Android 10 and up. On 10 and 11 the on-device factory does not exist, so the keyboard uses the standard recogniser and sets EXTRA_PREFER_OFFLINE. Android's own documentation for that flag ends with the sentence that matters: "Depending on the recognizer implementation, these values may have no effect."
So on those two versions, offline is a request the system's recogniser may honour or ignore, and if it ignores it, the audio may go to whichever service the recogniser vendor runs. That is the system's network, on the system's permission. FrankenKeys still holds no network permission on any version and cannot route anything itself. But I would rather write that sentence here than have you find it.
What the keyboard does with the text
Three things, all on the phone:
Continuous listening. A recogniser session ends when you pause, and it spends anywhere from a few hundred milliseconds to a few seconds finalising before the next session could start. Anything said in that gap was lost, which users describe as "it can't hear me while it's thinking". FrankenKeys closes the gap two ways: the pause that ends an utterance is yours to set and defaults to 2.5 seconds, and it runs two recogniser instances, starting the second the moment the first reports end of speech. If the platform refuses the overlap, it switches the trick off for the rest of the session and falls back to plain serial restarts, so no phone is worse off than the standard behaviour. On Android 13 and later, where the phone's recogniser supports it, the gap goes away entirely: dictation runs as one continuous session that hands back each phrase as it is recognised, and the keyboard only falls back to the overlap if that session misbehaves.
Spoken punctuation. "Period", "comma", "new paragraph" and the rest are handled by the keyboard's own rules after the text comes back.
Clean-up, with a leash. By default nothing reaches the field while you talk. When you tap send, the transcript is tidied on the phone and inserted in one edit you can undo. Every piece of that tidy-up is rejected if it moves the text by more than 35 percent of its length, grows it by more than 40 percent, changes a number or drops words you said, because a model asked to correct will happily rewrite, and nobody asked for that; a rejected piece gets the keyboard's plain rules tidy instead. Turn off Hold it until you send and the words land as you speak, and the clean-up is offered as a chip instead of applied.
What it cannot do
The system recogniser only knows the languages its vendor shipped models for on that phone. FrankenKeys tells it which of its thirty dictionary languages you are typing in, but it cannot conjure a Galician model onto a phone that does not have one. If the recogniser reports that the language is unavailable, dictation stops and the keyboard shows the error, rather than a different language being used silently.
Google's own keyboard, on most phones, gets a better recogniser than the one exposed to third parties, because they ship together. I am not going to claim parity on accuracy; I do not have a measurement and would not publish one from a single phone.
Documentation this post rests on
- developer.android.com,
SpeechRecognizer.createOnDeviceSpeechRecognizer: added in API level 31, throws whenisOnDeviceRecognitionAvailableis false. - developer.android.com,
RecognizerIntent.EXTRA_PREFER_OFFLINE: added in API level 23, "Depending on the recognizer implementation, these values may have no effect." - The FrankenKeys privacy policy at forgedev.studio/forgeboard/privacy, which states the same caveat.
The honest label for this feature is "on-device on Android 12 and up, requested on 10 and 11". That is what the voice page says, and it is what the Play description means by offline.