Air Actions
Overview
S Pen is connected to the device by BLE (Bluetooth Low Energy), and the connection is managed by the S Pen Framework.
BLE events are not directly sent to the app, but the S Pen Framework converts them to KeyEvents before sending them to app.
Therefore, apps can handle an S Pen event by recycling the existing KeyEvent-Callback without the need to add other interfaces.
The S Pen Remote Event handling and the process of sending the defined KeyEvent to the apps is outlined in the figure below.
Collecting S Pen Remote Events published by Apps
The KeyEvents received by the apps are defined in an .xml format and make them public, and the S Pen Framework collects and manages them.
Sending S Pen Remote Events to Apps
-
A BLE event is sent to the S Pen Framework.
-
S Pen Framework checks for the foreground app and looks for the KeyEvent that the app made public.
-
The found KeyEvent is sent to the app's KeyEvent-Callback.
-
The app performs the actions defined in the KeyEvent.
To facilitate the app functionality, the app must define the RemoteActions and follow the implementation process below.
- Specify the KeyEvent to be mapped to the S Pen Remote Event in a Manifest.
- Implement KeyEvent-Callback (if needed).
Implementation of RemoteActions
Specifying the KeyEvent to be Mapped to S Pen Remote Event in a Manifest
-
Check for the activity to handle the KeyEvent in a manifest file (AndroidManifest.xml).
-
Add
<intent-filter>
and<meta-data>
elements to that activity.
An .xml resource file defining RemoteActions must be specified for<meta-data>
.
<manifest xmlns:android="http://schemas.android.com/apk/res/android
package="com.samsung.android.blesample ">
<application ... >
<activity android:name="SampleActivity" >
<intent-filter>
<action android:name="com.samsung.android.support.REMOTE_ACTION" />
</intent-filter>
<meta-data android:name="com.samsung.android.support.REMOTE_ACTION"
android:resource="@xml/remote_action_sample"/>
</activity>
...
</application>
</manifest>
Only 1 RemoteAction per app is allowed at the moment. If you define RemoteActions to several activities, all other except one may be ignored.
-
Create an .xml file under res/xml/.
(Name the file with the same name as the resource specified in Step 2.)
The XML has a root element of
, and may include several elements. In addition, each contains information about id, label, priority, trigger_key, etc.
Structure of the XML file
<?xml version="1.0" encoding="utf-9">
<remote-actions version="float"
enable_key="string">
<action
id="string"
label="@string/resource_name"
priority="int"
trigger_key="string"
repeatable=["true" | "false"]
repeatable_interval=["short" | "medium" | "long" | "int"]>
<preference name="gesture" value=["click", "double_click", "swipe_left",
"swipe_right", "swipe_up", "swipe_down", "circle_ccw", "circle_cw"]/>
<preference name="button_only" value=["true" | "false"]/>
<preference name="motion_only" value=["true" | "false"]/>
</action>
</remote-actions>
<remote-actions>
syntax:
<remote-actions version="float">
...
</remote-actions>
can contain:
<action>
description:
This element contains one or more action elements
attribute:
-
version
- Mandatory
- Latest version is 1.2
-
actionset_label
- Optional
- It is the title of App Action Card to be displayed on the S Pen Remote Setting Screen. If it's not specified, then the app name is used by default.
- Only String Resource ID within the app package is allowed.
-
enable_key
- Optional
- It is the value that is set to a default ON in the Air Actions setting of your app.
- The value differs for each app, and it needs to be issued by a Samsung internal.
<action>
syntax:
<action id="string"
label="@string/resource_name"
priority="int"
trigger_key="string"
repeatable=["true" | "false"]
repeatable_interval=["short" | "medium" | "long" | "int"]>
. . .
</action>
contained in:
<remote-actions>
can contain:
<preference>
description:
Defines the key events mapped to the S Pen gesture and the information to be displayed on the Air actions settings screen.
attribute:
-
id
- Mandatory
- It requires an action-specific unique ID.
- Duplicate specification of the same ID is not allowed.
- Only alphabet, numeric, or underscore are allowed.
-
label
- Mandatory
- Label of Action to be displayed on the S Pen Remote Setting Screen.
- Only String Resource ID within the app package is allowed.
-
priority
-
Mandatory
-
Duplicate specification of the same priority is not allowed.
-
The smaller the number, the higher the priority (1: highest priority).
-
Version 1.0
- Based on the priority, 1 is mapped to a single click gesture and 2 is mapped to a double click gesture. 3 and afterward are registered to the App action list as candidate action.
-
Version 1.2
- The position of this action is determined in the App action list. The default gesture is determined by the preferece Tag.
-
-
trigger_key
-
Mandatory
-
Define the KeyEvent to be received by the app.
-
Use the symbolic name of the keycode defined in Android KeyEvent.java, but exclude the
"KEYCODE_" part
Example: KEYCODE_PAGE_UP → trigger_key="PAGE_UP"
-
You can define a KeyShortcut by using "+" as a delimiter.
Example 1: Combination of KEYCODE_CTRL_LEFT and KEYCODE_N
→ trigger_key="CTRL_LEFT+N"
Example 2: Combination of KEYCODE_CTRL_LEFT, KEYCODE_SHIFT_LEFT, and KEYCODE_Z
→ trigger_key="CTRL_LEFT+SHIFT_LEFT+Z"
-
-
repeatable
- Optional
- Set to true when this action is repeatable.
- Version 1.2
-
repeatable_interval
-
Optional (Mandatory if repeatable attribute exist)
-
Can be short, medium, long or int type:
- short : 300ms
- medium : 500ms
- long : 1000ms
- int type : 50~3000
-
Version 1.2
-
<preference>
Optional
Version 1.2
syntax:
<preference name="gesture" value=["click", "double_click", "swipe_left", "swipe_right",
"swipe_up", "swipe_down", "circle_ccw", "circle_cw"]/>
<preference name="button_only" value=["true" | "false"]/>
<preference name="motion_only" value=["true" | "false"]/>
contained in:
<action>
description:
Determines the default gesture to be mapped and checks whether this action is a button press or motion gesture
attribute:
-
name
Should be set to "gesture", "button_only", "motion_only"
- "gesture": Set the type of gesture you want to set as default
- "button_only" : Provide the action only for button press
- "motion_only" : Provide the action only for motion related gestures
-
value
-
if name="gesture", any or all of the following strings are valid values for this attribute.
Multiple values are separated by '|' - for example, " click| swipe_down| swipe_down ".
value Gesture type Description “click” Button Single click “double_click” Button Double click “swipe_left” Motion Swipe left ← “swipe_right” Motion Swipe right → “swipe_up” Motion Swipe up ↑ “swipe_down” Motion Swipe down ↓ “circle_ccw” Motion Circle Counter-clock-wise “circle_cw” Motion Circle Clock-wise Note :If the
tag with name “gesture” does not exist, the is not set as default action. If name="button_only" or "motion_only", then "true" or "false" is allowed as value.
-
| **button\_only** | **false or not exist** | true |
| **motion\_only** | ^^ | ^^ |
-------------|---------------|---------------
| **false or not exist** | This action can be set on any action. | This action can only be set for button press (single or double click). |
| **true** | This action can only be set for motion gestures (e.g. swipe\_left or circle\_cw). | action will be ignored. |
<div class="alert alert-info" role="alert"><strong>Note</strong> : <p>If this configuration contradicts with value of “gesture”, this action will be ignored.
For example, in case that “swipe_left” is set as value of “gesture” but “button_only” is true, configuration is contradictory.
Implementation of KeyEvent-Callback
Implement KeyEvent-Callback to the activity to which RemoteActions have been declared. Since it is the same as handling an Android KeyEvent, only the simple examples of the implementation are introduced here.
Please refer to the Android developers website for detailed guidelines. It is recommended to handle the sent KeyEvent at onKeyDown.
Example :
-
Page Down key: Scroll ScrollView as much as +500 in Y direction
-
Page Up key: Scroll ScrollView as much as -500 in Y direction
public class SampleActivity extends Activity {
private ScrollView mScrollView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample_activity1_layout);
mScrollView = (ScrollView) findViewById(R.id.scroll_view);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
mScrollView.smoothScrollBy(0, 500);
} else if (keyCode == KeyEvent.KEYCODE_PAGE_UP) {
mScrollView.smoothScrollBy(0, -500);
}
return super.onKeyDown(keyCode, event);
}
}