S Pen Remote Support GuideSept 20, 2018

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.

Figure 1 Use Case Scenario Figure 1 Use Case Scenario

Therefore, apps can handle an S Pen event by recycling the existing KeyEvent-Callback without the need to add other interfaces.

Below is the S Pen Remote Event handling process, and the process of sending the S PenRemote Event-defined KeyEvent to apps are outlined in the figure below.

Collecting S Pen Remote Events published by Apps

Figure 2 S Pen Remote Events Collection Figure 2 S Pen Remote Events Collection

The apps define the KeyEvents to receive in .xml format and make them public, and the S Pen Framework collects and manages them.

Sending S Pen Remote Events to Apps

Figure 3 S Pen Remote Events Transmission Figure 3 S Pen Remote Events Transmission
  1. 1.

    A BLE event is sent to the S Pen Framework.

  2. 2.

    The S Pen Framework checks for the foreground app and looks for the KeyEvent that the app made is public.

  3. 3.

    The found KeyEvent is sent to the app's KeyEvent-Callback.

  4. 4.

    The app performs the actions defined in the KeyEvent.

To facilitate app functionality, the app must define RemoteActions and follow the implementation process below:

Note
  1. 1.

    Specify the KeyEvent to be mapped to the S Pen Remote Event in a Manifest.

  2. 2.

    Implement KeyEvent-Callback (if needed).

Implementation of RemoteActions

Specifying the KeyEvent to be Mapped to the S Pen Remote Event in a Manifest
  1. 1.

    Check for the activity to handle the KeyEvent in a manifest file (AndroidManifest.xml).

  2. 2.

    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>
    Note

    Only 1 RemoteAction per app is allowed at the moment. If you define RemoteActions to several activities, all other except one may be ignored.

  3. 3.

    Create an .xml file under res/xml/.

    (Name the file with the same name as the resource specified in Step 2.)

    Figure 4 Sample Resource Tree Figure 4 Sample Resource Tree

    XML has a root element of <remote-actions>, and may include several <action> elements. In addition, each <action> contains information about id, label, priority, trigger_key, etc.

    <?xml version="1.0" encoding="utf-8"?>
    
    <remote-actions version="1.0">
        <action
            id="page_down"
            label="@string/page_down"
            priority="1"
            trigger_key=" PAGE_DOWN ">
        <action>
        
    <action
            id="page_up"
            label="@string/ page_up"
            priority="2"
            trigger_key="PAGE_UP">
        </action>
    
    <action
            id="right"
            label="@string/start_activity"
            priority="3"
            trigger_key="CTRL+LEFT+N ">
        </action>
    </remote-actions>
    <remote-actions> element
    Attribute Value Mandatory Description
    version 1.0 0 Version info
    actionset_label String Resource Id x

    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.

    To specify it with different text rather than its app name, specify the String Resource ID within the package. (See Figure 5)

    Example: @string/my_title

    <action> element
    Attribute Value Mandatory Description
    id String 0

    ※  Duplicate specification of the same ID is not allowed.

    Requires an action-specific unique ID.

    label String Resource ID 0

    Label of Action to be displayed on the S Pen Remote Setting Screen.

    String Resource ID within the app package.

    Example: @string/page_up

    (See Figure 5)

    priority Integer
    (> 0)
    0

    ※  Duplicate specification of the same priority is not allowed.

    The smaller the number, the higher the priority
    (1: The highest priority)

    Based on the priority, Priority 1 is mapped to a single click, Priority 2 is mapped to a double-click, and Priority 3 and afterwards are registered to a customizable candidate list (See Figure 5).

    trigger_key String 0

    Define the KeyEvent to receive.

    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"

    Figure 5 Example of Setting Screen Display Figure 5 Example of Setting Screen Display

Implementation of KeyEvent-Callback

Implement the KeyEvent-Callback to the activity to which the 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.

  • Ctrl + N: Open SampleActivity2.

public class SampleActivity extends Activity {
    private ScrollView mScrollView;

    @Override
    protected void onCreate(@Nullable 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);
        } else if ((event.getMetaState() & KeyEvent.META_CTRL_ON) != 0
            && keyCode == KeyEvent.KEYCODE_N) {
            Intent intent = new Intent(this, SampleActivity2.class);
            startActivity(intent);
        }
        ...
        return super.onKeyDown(keyCode, event);
    }   
}
Note

Pay attention to cases when the child view consumes the KeyEvent.

For example, if the EditText is focused on a screen where the EditText co-exists, most KeyEvents will be consumed for text inputs or a cursor movement and they may not be sent to the Activities or Container Layouts.

On this screen, you must specify the key code or key combination that the child view cannot consume.