Most of the mail we get about Text Shortcuts is a variation on one sentence: it stopped working. No error, no change, no pattern the user can identify. It worked, and then it did not.
Nearly every time, the accessibility service is off.
The service turns off and nothing says so
An accessibility service runs because the user enabled it in system settings. It stops running for a range of reasons that have nothing to do with the user changing their mind:
A device migration or restore brings your app across without the grant. An app update can drop the service on some builds. A system permission review can revoke it. Some manufacturer battery policies stop it. And a system update can reset it.
There is no callback for any of this. onServiceConnected fires when you are connected; nothing fires when you are not, because your service is not running to receive it. From inside the app the state is invisible unless you go and look.
So the app looked fine. The phrase list was there, the editor worked, the shortcuts existed. Nothing typed anywhere expanded, and there was no explanation available anywhere in the interface.
The fix is small and should have been there from the start: the app reads whether its service is currently in the system's enabled list, checks on every launch and every return to the foreground, and shows the state prominently when it is off — with a link to the exact settings screen.
We also track whether the service has actually received any events recently. Enabled and functioning are different states, and on devices with aggressive process management a service can be listed as enabled and be receiving nothing. A long silence with the app in use is a signal, and we surface it rather than let the user conclude the app is broken.
The general shape, which we have now hit in more than one of our apps: if your app depends on a system grant that can be revoked without notice, checking that grant is part of your app's main screen, not part of onboarding.
Variables
The feature half of the release, and the one that changes how shortcuts get written.
A fixed phrase is only useful when the whole phrase is fixed. Most useful phrases are not: a support reply has a stable structure and a changing order number, a delivery note has a fixed address format and a changing entry instruction, a meeting response has a polite frame and a changing time.
Previously you either wrote a shortcut that was mostly right and edited it every time, or you did not make one. Editing an expansion every time is barely faster than typing it.
A variable is a marked gap in a phrase. On expansion, the cursor lands at the first gap, and moving to the next is one action. The stable text is written for you; the changing parts are where you type.
The design constraint we held to: a variable is a position, not a prompt. We considered a dialog that asks for each value before inserting, and rejected it — a dialog moves the work before the text exists, where you have the least context, and it makes expansion feel like filling in a form. Landing the cursor in the right place and getting out of the way is faster and lets you see the sentence while you complete it.
There are also a few automatic values — today's date, the current time — because those are genuinely fixed at the moment of expansion and typing them is pure overhead.
A caution that comes with the feature: if most of a phrase is variables, it is not a shortcut. It is a form, it will be slower than typing, and it will be harder to check before you send it.
Replacing text that already exists
The other new path works in the other direction. Rather than typing a trigger, you select text that is already on screen and apply a shortcut to it — reformat a rough note into a prepared structure, wrap something in a standard frame, convert a scribbled address into your usual format.
This uses the same underlying mechanism as trigger expansion and inherits its constraints: it needs the field to expose editable text and accept a set-text action, which not every app does. Where it does not work, nothing happens rather than something wrong.
Review the result before sending. That applies to every expansion and it applies more here, because you are transforming text you did not just write and are therefore less likely to reread.
Backing up a library of personal details
Phrase libraries accumulate. After a year of use, yours probably contains your address, your phone number, account details, work information, and several messages you would rather not have appear unexpectedly.
That makes backup both necessary — losing it on a device change is genuinely annoying — and something to be deliberate about.
Backup and restore through your own cloud storage is now available, and it is explicit: you choose when it happens and where the file goes. There is no automatic sync, nothing is uploaded on our side, and we operate no server that holds any of it. The file is yours, in your storage, and it is a readable copy of everything in the library.
Which means: treat the backup file the way you would treat a document containing your address and account details. Not a shared folder. Delete it after a restore. And before you back up, this is a good moment to look through the library for anything that should never have been saved — a password, an authentication code, anything a credential manager should be holding. A phrase library has none of a password manager's protections and an expansion can fire into a field you did not intend.
Onboarding, rewritten
The first run now spends more time on what the service does and less on what the app can do.
This is partly a fairness question. Accessibility access is one of the strongest grants on Android; the system's own dialog says so in strong terms, and a user who taps past it without understanding has not really consented to anything. The app should explain, in its own words, what it will read and what it will not, before the system asks.
It is also practical. The most common support question is a service that is off, and a user who understood what they enabled has a much better chance of recognising what has happened when it is disabled six months later.