Annotation Type AppIntent
Exposes a capability of your application to the system: Siri, Spotlight, the Shortcuts app, an Android launcher shortcut, a widget button, or a language model.
@AppIntent(value = "log_workout", title = "Log a workout",
description = "Records a completed workout",
phrases = {"Log a workout in ${applicationName}"},
headless = true, timeoutSeconds = 5)
public static IntentResult logWorkout(
@IntentParam(value = "kind", title = "What kind of workout?",
options = {"run", "ride", "swim"}) String kind,
@IntentParam(value = "minutes", title = "How many minutes?") int minutes) {
WorkoutStore.append(kind, minutes);
return IntentResult.spoken("Logged a " + minutes + " minute " + kind + ".");
}
The handler must be public static
This is not a style preference. The build generates a direct static call
to your method, and a direct call is the only form that survives the iOS
translator's dead-code elimination and Android's obfuscation -- a reflective
lookup would be stripped on iOS and renamed on Android, in both cases
silently. static also makes the contract visible: a handler can be asked to
run in a process that exists only to answer it, where no instance of yours
has been constructed and nothing is on screen.
The method returns com.codename1.intents.IntentResult, or void when it
has nothing to report. It may take com.codename1.intents.IntentContext as
its first parameter to see the deadline, the source and the cancellation
flag. Every other parameter must carry IntentParam.
At build time
The Codename One Maven plugin scans the project's compiled bytecode,
validates every @AppIntent, and generates both the reflection-free dispatch
table and the native declarations each platform compiles into the app. A
malformed declaration fails the build rather than going quiet on a device.
Phrases
Apple enforces three rules on a spoken phrase, all of them as build failures
that produce no App Intents metadata at all. The build checks them here
instead, so the message names your declaration rather than arriving as an
opaque failure from appintentsmetadataprocessor:
- Every phrase must contain
${applicationName}. - A phrase may reference at most one parameter. Write one phrase per parameter rather than combining them.
- A phrase parameter must be an
IntentEntitytype. A primitive cannot appear in a phrase, which is not much of a loss: leave it out and the platform still asks for it, using the title on itsIntentParam.
An intent that declares phrases must also be discoverable, since a phrase
is only reachable through an App Shortcut.
Phrases are ignored on platforms with no voice invocation, which today means Android.
-
Required Element Summary
Required Elements -
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionA longer explanation shown alongside the title.booleanTrue when the platform should confirm with the user before running this.booleanTrue when the platform may offer this intent before the user has ever run it.Exposure[]Which consumers this intent is offered to.booleanTrue when this intent may run without bringing the app to the foreground.A route template to open instead of answering in place, for example/orders/{orderId}, where each{name}names one of this intent's parameters.String[]Spoken phrases that invoke this intent.intHow long the handler may run before the framework reports a failure.
-
Element Details
-
value
String valueThe stable id, matching
[a-z][a-z0-9_]{2,63}. Required.It is stable in the strong sense: the system stores it in donated shortcuts and the user's own Shortcuts workflows, so renaming one breaks what people already built.
-
title
String titleThe human-readable name shown in the Shortcuts app. Required. -
description
-
phrases
String[] phrasesSpoken phrases that invoke this intent. Each must contain${applicationName}.- Default:
{}
-
headless
boolean headlessTrue when this intent may run without bringing the app to the foreground.
A headless handler must not touch
Form,Dialog, or anything else needing a window; see thecom.codename1.intentspackage documentation for the full contract.- Default:
false
-
discoverable
boolean discoverableTrue when the platform may offer this intent before the user has ever run it. False restricts it to appearing after a donation.- Default:
true
-
destructive
boolean destructiveTrue when the platform should confirm with the user before running this. Set it on anything that deletes, sends, or spends.
It also closes the paths that cannot confirm. A destructive intent is not published as an Android launcher shortcut, is refused when an unauthenticated caller asks for it, and is not donated -- each of those runs on a single tap with nothing in between. The capability stays fully available through the assistant and the Shortcuts app, which confirm first; what goes away is the one-tap route to it.
- Default:
false
-
opensRoute
String opensRouteA route template to open instead of answering in place, for example
/orders/{orderId}, where each{name}names one of this intent's parameters.The URL is resolved through the same
Routetable that handles deep links, so an intent and a link to the same screen cannot drift apart. A non-empty value is also what tells the platform to open the app.- Default:
""
-
exposure
Exposure[] exposureWhich consumers this intent is offered to. Defaults to the platform only; addExposure.MODELto also offer it to a language model throughcom.codename1.intents.Intents#asTools().- Default:
{ASSISTANT}
-
timeoutSeconds
int timeoutSecondsHow long the handler may run before the framework reports a failure.
The platform usually allows around twenty seconds. Do not use them: a spoken interaction that takes ten seconds has already failed as an interaction. Aim under two, and return
IntentResult.opens(...)for anything genuinely slower.- Default:
20
-