S Pen Remote

Overview

S Pen connects via BLE (Bluetooth Low Energy) to a device and the S Pen Framework manages the connection.

BLE events are converted by the S Pen Framework into KeyEvents before sending to the app.

Figure 1 Use Case Scenario

Figure 1 Use Case Scenario

Apps are able to handle S Pen events by reusing existing KeyEvent-Callback without adding other interfaces.

Collecting and Sending S Pen Remote Events to Apps

The S Pen Framework collects and manages KeyEvents to be received by the app, and are defined in .xml format before making them public.

Below is the process of the S Pen Remote Event handling and sending S Pen Remote Event-defined KeyEvents to apps:

Figure 2 S Pen Remote Events Transmission

Figure 2 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 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.

Objective

Learn how to implement KeyEvent and Callbacks on your S Pen Remote.

Setup

The following tools are needed to implement Remote Actions in S Pen:

  • Java SE Development Kit 10 (JDK)

  • Android Studio / Eclipse IDE with Android Developer Tools

  • Samsung Note9 running at least Android 8.0 or higher

Initial Setup:

In Android Studio, click Open an existing Android Studio project.

Locate the Android Project from the directory and click OK.

Application Development

The app is required to define Remote Actions to facilitate app functionality, and follow the process below:

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

2. Implement KeyEvent-Callback (if needed).

1. Implementation of Remote Actions
  1. a) Check for the activity to handle the KeyEvent in a manifest file (AndroidManifest.xml).

  2. b) 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. c) Create an .xml file under res/xml/.

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

    Figure 3 Sample Resource Tree

    Figure 3 Sample Resource Tree

  4. d) Create the desired <action> elements in the XML file created as seen below.

    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>
    
    Figure 4 Example of Setting App Actions

    Figure 4 Example of Setting App Actions

2. Implementation of KeyEvent-Callback

Apply the KeyEvent-Callback to the activity where RemoteActions have been declared.

Please refer to the Android developers website for detailed guidelines. It is recommended to handle the sent KeyEvent at onKeyDown.

Add the following KeyEvent-Callback as seen below:

  1. 1. Page Down key: Scroll ScrollView as much as +500 in Y direction.

  2. 2. Page Up key: Scroll ScrollView as much as -500 in Y direction.

  3. 3. 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.