os_intents_android
The Android implementation of os_intents.
This package is endorsed: depending on os_intents pulls it in automatically,
and you should not need to import it. It is documented here so that what runs on
the device is not a black box.
What is inside
OsIntentsBridge |
routes an invocation from a generated @AppFunction — or from a launcher shortcut's Intent — to Dart |
| headless engine | a second FlutterEngine in the app process, started from the entrypoint the generator emits |
| static store | SharedPreferences, read before anything starts, so Execution.static_ answers with no engine |
There is no isolate choice here the way there is on iOS: an
AppFunctionService never has an Activity, so every AppFunction invocation goes
through the headless engine. A shortcut, by contrast, starts an Activity, so it
lands on the UI isolate.
Two layers, and only one is headless
App shortcuts and Assistant capabilities are generated by plain
os_intents sync: a launcher entry per intent, plus a capability for each one
that names a built-in intent through androidCapability. They cost nothing, work
on the Android versions people actually run, and need one <meta-data> line in
the manifest.
AppFunctions is opt-in behind os_intents sync --android, because it forces
compileSdk 37, AGP 9.1.1 and Gradle 9.3.1 on your app for something only
Android 16+ can run.
The two are not interchangeable. A shortcuts.xml <intent> starts an Activity,
so on the shortcuts layer Execution.background still opens the app —
headless is exactly what the version chain buys. An intent with a required
parameter gets no launcher shortcut at all: a tap carries no values, so it would
appear and then fail on use.
What each layer costs, and the emulator image that will actually boot a check like this, is in docs/android.md.
Full picture: os_intents.