Get Your Android App Ready for Chromebooks

With the release of the new Google Pixelbook, the Google Play Store officially out of beta on Chrome OS, and the overall usage of Chromebooks on the rise, it’s time to start thinking about how your Android application will perform on Chrome OS.

Most Android applications are already available to Chromebook users and run without needing to change anything. However, there are a few areas that tend to require some attention and optimizations. We’re going to cover one of them in this post, input compatibility.

Input Compatibility

The most obvious difference when using your application on a Chromebook is that there is a keyboard, trackpad, and sometimes a stylus that comes with the device. Many (but not all) have a touch screen, so your app needs to understand these inputs. Users are going to expect certain applications to behave as they would on any other laptop when using a Chromebook so, as you test your app on Chrome OS, think of features you would want on this form factor.

First things first, you should make sure that you are not requiring a touch screen or multi-touch in your manifest if you want your app to be used on Chrome OS. The trackpad simulates a fake touch event, so if you are requiring a touchscreen, your application will not be available on some Chrome OS devices.

If you really believe that your application needs a real touch screen or multi touch than restrict based on these, but think about how you could provide a great experience with either a simulated touch gesture from the operating system or different ways of handling the same behavior. You can make sure your application will be available on all Chrome OS devices by not requiring a touchscreen and adding this to your manifest.

<uses-feature android:name="android.hardware.touchscreen"
android:required="false" />

Keyboard

Having a physical keyboard opens your application up to multiple navigation methods. As a user, I navigate through lists, forms, and navigation tabs using tab and the arrow keys. This experience gives your user a faster way of navigating through your app and getting to the information they want while not having to use a trackpad or touch screen, both of which may be uncomfortable for users. If you have made accessibility a top priority you are a long way ahead, as those efforts lend to creating a navigable UI by other means than just touch.

You can add navigation using the Tab key easily by using the android:nextFocusForward attribute in your layout files. Navigation using the arrow keys is also easy to add in your layout files using the android:nextFocusDown attribute (for the down arrow) and the respective attributes for each navigation arrow. See more on adding this functionality here.

Keyboard shortcuts are some of the best functionality that you can add for users with a keyboard as it brings convenience and a level of familiarity in using your application. Think about which shortcuts users will expect based on the nature of your application, such as save, print, copy, paste, undo, and redo. Most of these are easy to implement as there is an API for Ctrl based shortcuts, dispatchKeyShortcutEvent.

@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
if (event.hasModifiers(KeyEvent.META_CTRL_ON) &&
event.getKeyCode() == KeyEvent.KEYCODE_S) {
//save action
return true;
}
return super.dispatchKeyShortcutEvent(event);
}

If you are implementing a non Ctrl-based shortcut, you have to do a bit more work with using the dispatchKeyEvent API and keeping track of what keys are currently pressed. Remember that it’s a good idea to let your users know that shortcut functionality exists via tooltips or other UI elements.

Mouse and Trackpad

Many Chrome OS users will not be using a touch screen for the majority of their navigation through your app. Things like long-clicks or swiping become unintuitive, so make sure that your functionality isn’t locked to the touch interface.

The easiest way to handle the long click problem is with right-click support! Using the View.onContextClickListener gives you a simple way to detect right-click events.

rightClickItem.setOnContextClickListener(
new View.OnContextClickListener() {
@Override
public boolean onContextClick(View v) {
// right click action
return true;
}
});

Handling the lack of easy to use swipe functionality, I recommend providing a hover functionality that allows the user to perform the same act. A close button appearing on hover to delete or close an item helps make your interface much more usable with a mouse. You can use an onHoverListener to add this behavior. Make sure to have a visible change in the UI so the user knows they are in a hover state.

With a mouse, scrolling through views and lists is different. Make sure that your app scrolls correctly when using a mouse, and find places you may have to build scrolling functionality yourself. You can use a View.OnGenericMotionListener and detect if it’s a scroll event, and then perform whatever behavior you need in the method body.

scrollableView.setOnGenericMotionListener(
new View.OnGenericMotionListener() {
@Override
public boolean onGenericMotion(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_SCROLL) {
//scroll event
return true;
}
return false;
}
});

For other mouse compatibility strategies you should see the examples here.

By default your application should work on ChromeOS devices like it does on phones. A compatibility mode will help your application to use the widely used phone events instead of special events which are usually not handled by many applications. As an example — many applications are not testing for the mouse scroll wheel — but every application looks at touch scroll events. As such the compatibility mode would translate the scroll wheel event into a touch scroll event. If you want to take full advantage of these different events, you can let the system know this by declaring the following in your manifest:

<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />

Adding this signifies that you have optimized your app for PC devices that are typically used with keyboard, mouse, and a trackpad. It disables the compatibility mode and allows you to handle these distinct events.

Stylus

Some Chrome OS devices and phones ship with a stylus, so you may consider building support for this. Some applications are more prone to being used with a stylus, so take that into account when thinking in terms of your application. There are many stylus APIs that you can use to build more advanced support. Using the View.onTouchEvent() you are able to get a lot of information such as tilt and orientation, pressure, and if this touch is from a stylus, finger, or even a stylus eraser.

When a stylus is being used, Chrome OS tries to reject other touches such as a palm resting on the screen. There are sometimes touches that are reported to the application before Chrome OS recognizes them as a “palm” touch. An ACTION_CANCEL event will be sent to tell the app to get rid of these touches. To handle this, make sure to be continuously rendering the touch series to the display, but be ready to delete the line if this event comes through the system to your application. More information on this can be found here.

For note-taking applications, make sure to include a note-taking intent in your manifest. Chrome OS shows all applications that include this intent when the user requests a note app.

<intent-filter>
<action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Be on the lookout for updated stylus API’s taking advantage of the new awesome technology available on Chrome OS Devices!

More stylus support information, including how to test without a stylus device, can be found here.


With the Play Store coming to more and more Chrome OS devices, these input mediums and behaviors will start becoming more used and prominent. It’s important as a developer to understand how you can make your app even better on these new exciting form factors.

For more information, see Input compatibility for Chromebooks.