Actions for the Android SDK
Airship Actions provide a convenient way to automatically perform tasks by name in response to push notifications, Message Center App Page interactions, and JavaScript.
An action describes a function, which takes an optional argument and performs a predefined task, producing an optional result. Actions may restrict or vary the work they perform depending on the arguments they receive, which may include type introspection and runtime context.
The Airship SDK includes built-in actions for common tasks, and you can create custom actions to extend functionality.
For a complete list of available built-in actions, see the Actions User Guide.
Action Situations
Actions are triggered with extra context in the form of a Situation. The different situations allow actions to determine if they should run, and may perform different behavior depending on the situation.
| Description | Android |
|---|---|
| Action was invoked manually. | .SITUATION_MANUAL_INVOCATION |
| Action was invoked from a launched push notification. | .SITUATION_PUSH_OPENED |
| Action is triggered when a notification is opened. | .SITUATION_PUSH_OPENED |
| Action was invoked from JavaScript or a URL. | .SITUATION_WEB_VIEW_INVOCATION |
| Action was invoked from a foreground interactive notification button. | .SITUATION_FOREGROUND_NOTIFICATION_ACTION_BUTTON |
| Action was invoked from a background interactive notification button. | .SITUATION_BACKGROUND_NOTIFICATION_ACTION_BUTTON |
| Action was invoked from automation. | .SITUATION_AUTOMATION |
Action Registry
The action registry is the central place to register actions by name. Each entry in the registry contains an action, the names that the action is registered under, a predicate that allows filtering when an action should run, and allows specifying alternative actions for different situations.
Registering an action
Airship.actionRegistry.registerEntry(setOf("my_action_name", "my_alias")) {
ActionRegistry.Entry(action = CustomAction())
}Airship.getActionRegistry().registerEntry(Set.of("my_action_name", "my_alias"), () -> {
return new ActionRegistry.Entry(new CustomAction());
});Looking up an action entry
val entry = Airship.actionRegistry.getEntry("my_action_name")ActionRegistry.Entry entry = Airship.getActionRegistry().getEntry("my_action_name");Setting a predicate
// Predicate that will reject PUSH_RECEIVED, causing the action to never run during that situation.
val rejectPushReceivedPredicate: ActionPredicate = object : ActionPredicate {
override fun apply(arguments: ActionArguments): Boolean {
return SITUATION_PUSH_RECEIVED != arguments.situation
}
}
// Update the entry with a new predicate
Airship.actionRegistry.updateEntry("my_action_name", predicate = rejectPushReceivedPredicate)// Predicate that will reject PUSH_RECEIVED, causing the action to never run during that situation.
ActionPredicate rejectPushReceivedPredicate = new ActionPredicate() {
@Override
public boolean apply(ActionArguments arguments) {
return !(SITUATION_PUSH_RECEIVED.equals(arguments.getSituation()));
}
};
// Update the entry with a new predicate
Airship.getActionRegistry().updateEntry("my_action_name", null, Collections.emptyMap(), rejectPushReceivedPredicate);Triggering Actions
In addition to triggering actions from messages, you can trigger them programmatically.
Running Actions
// Running an action directly through the ActionRunRequest
ActionRunRequest.createRequest("actionName")
.setSituation(SITUATION_MANUAL_INVOCATION)
.setValue("actionValue")
.run()
// Running an action by registered name
ActionRunRequest.createRequest("my_action_name")
.setValue("actionValue")
.run()
// An optional callback when finished
ActionRunRequest.createRequest("my_action_name")
.setValue("actionValue")
.run { arguments, result ->
Logger.info("Action finished! Result: $result")
}
// Block until the action finishes
val result = ActionRunRequest.createRequest("my_action_name").runSync()// Running an action directly through the ActionRunRequest
ActionRunRequest.createRequest("actionName")
.setSituation(Situation.MANUAL_INVOCATION)
.setValue("actionValue")
.run();
// Running an action by registered name
ActionRunRequest.createRequest("my_action_name")
.setValue("actionValue")
.run();
// An optional callback when finished
ActionRunRequest.createRequest("my_action_name")
.setValue("actionValue")
.run(new ActionCompletionCallback() {
public void onFinish(ActionArguments arguments, ActionResult result) {
Logger.info("Action finished! Result: " + result);
}
});
// Block until the action finishes
ActionResult result = ActionRunRequest.createRequest("my_action_name").runSync();Custom Actions
The action framework supports any custom actions. Create an action by extending the Action base class on Android. After takeOff, register the action. The action can be triggered the same way as built-in actions.
Custom Action
class CustomAction : Action() {
override fun acceptsArguments(arguments: ActionArguments): Boolean {
if (!super.acceptsArguments(arguments)) {
return false
}
// Do any argument inspections. The action will stop
// execution if this method returns false.
return true
}
override fun perform(arguments: ActionArguments): ActionResult {
Log.i("CustomAction", "Action is performing!")
return ActionResult.newEmptyResult()
}
}public class CustomAction extends Action {
@Override
public boolean acceptsArguments(ActionArguments arguments) {
if (!super.acceptsArguments(arguments)) {
return false;
}
// Do any argument inspections. The action will stop
// execution if this method returns false.
return true;
}
@Override
public ActionResult perform(ActionArguments arguments) {
Log.i("CustomAction", "Action is performing!");
return ActionResult.newEmptyResult();
}
}On Android, custom actions may override the shouldRunOnMainThread() method to specify whether the action should
be run on the main tread, or on a background thread. Implementations should take care to avoid long-running tasks,
especially when running on the main thread.
Categories