App Shortcuts API for Android

Provide quick access to the most used features of your app using the new App Shortcuts API for Android. Unlike many features found in the support library, this API is only available for devices running Android 7.1+ and will not appear on older devices. The good news is that shortcuts are quick to implement and users with compatible devices will appreciate the time savings. You can even pin shortcuts to the home screen making them even easier to use.

Shortcut API animation

Add a Static Shortcut

Step 1: Target Android API 25+

In order to test this feature out, you must be targeting API 25+ and running an emulator or device with Android 7.1 or higher.

Step 2: Update Your AndroidManifest.xml

Add the path to your XML definition for your shortcuts in your main activity.

<activity
    android:name="com.blackcj.fitdata.activity.MainActivity"
    android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <!-- App Shortcuts -->
    <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />
</activity>

Step 3: Create Your shorcuts.xml File

Add a resource folder for XML that targets API 25+ (xml-v25) inside your res folder. Add the corresponding label and icon files to your project. Update the package name to match your project.

<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
    <shortcut
        android:shortcutId="add_activity"
        android:icon="@drawable/add"
        android:enabled="true"
        android:shortcutShortLabel="@string/add_new_activity_short"
        android:shortcutLongLabel="@string/add_new_activity"
        >
        <intent
            android:action="com.blackcj.fitdata.ADD_ACTIVITY"
            android:targetPackage="com.blackcj.fitdata"
            android:targetClass="com.blackcj.fitdata.activity.MainActivity"
            />
    </shortcut>
</shortcuts>

Step 4: Update Your Main Activity

Check the intent in the onCreate function of your Main Activity. If it matches the intent of the shortcut, navigate to the corresponding area within your application.

public static final String ACTION_ADD_ACTIVITY = "com.blackcj.fitdata.ADD_ACTIVITY";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...

    if (ACTION_ADD_ACTIVITY.equals(getIntent().getAction())) {
        // Invoked via the manifest shortcut.
        AddEntryActivity.launch(MainActivity.this, 3);
    }
}

Summary:

This is a great new feature but will take time from both an OS adoption and user education perspective. If you’re running Android 7.1+ and app shortcuts don’t appear, make sure your default launcher supports this feature. In addition to static shortcuts, you can also create dynamic user selectable shortcuts using the ShortcutManager.

Additional Resources:

https://developer.android.com/guide/topics/ui/shortcuts.html

Building a Custom Android Keyboard

Problem

Google’s sample keyboard project is a little out of date. It’s a very helpful starting point but requires some minor changes to get it working as expected. On top of that, many of the common customizations are spread out across a wide array of stack overflow posts.

Solution

I’ve made some minor updates to Google’s base keyboard example and applied some of the common customizations to the keyboard. This only took a couple of hours to put together but required a number of different resources including blogs, documentation and Stackoverflow. This keyboard contains styling, predictive complete spell check and alternate keys. There is still a lot of room for improvement but this is a much better starting point.

Keyboard animation

Source Code

Overview

There are already resources that walk through aspects of the keyboard code in great detail. At a high level you have a class that extends Keyboard, a KeyboardView and a KeyboardService that extends InputMethodService. On top of that it’s really just adding your icons, layout and XML files. Most of the styling can be done in the input.xml file.

Popup Keyboard Layout:

When you add pop-up keys (alternate keys that appear on long press) you’re actually creating a new keyboard for the pop-up. It was a bit confusing at first but makes sense after you take a look at the code. The new keyboard is automatically created and displayed as a modal above your existing keyboard.

Popup Keyboard

Snipet from original keyboard XML template:

...
<Key android:codes="46,44" android:keyLabel=". ,"
     android:keyWidth="15%p" android:popupCharacters=".,?!#@" 
     android:popupKeyboard="@xml/keyboard_popup_template"/>
...

Popup keyboard XML template:

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="10%p"
    android:horizontalGap="0px"
    android:verticalGap="0px"
    android:keyHeight="56dp">
</Keyboard>

Popup keyboard layout file (set in the input.xml keyboard layout):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="@color/colorPrimaryDark">
    <android.inputmethodservice.KeyboardView
        android:id="@android:id/keyboardView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:keyPreviewLayout="@layout/preview"
        android:popupLayout="@layout/keyboard_popup_layout"
        android:keyBackground="@drawable/key_background"
        android:keyTextColor="#333"
        android:background="@color/colorPrimaryDark"
        android:keyTextSize="22sp"/>
    <ImageButton android:id="@android:id/closeButton"
        android:background="@android:color/transparent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:clickable="true"
        android:src="@drawable/ic_close_black" />
</LinearLayout>

Next Steps

The predictive text appears over the top of content on the screen. I’ve been reading that it’s easier to manage by including it in the keyboard layout instead of using the candidates view. This would give more control over the behavior and prevent content on the screen from being covered up. In addition to that, predictive text doesn’t work correctly if you hit backspace half way through a word. The text selection position should be updated to check for white space and more intelligently select the word. This implementation uses the dictionary which seemed like a reasonable predictive text option but it could be updated to include a app specific dictionary of words that builds up over time.

I’ve removed the preview text in this example (the semi-transparent pop-up that appears just above the letter as you type). The pop-up was animating around the screen and not behaving like the new Android material keyboard. It didn’t look easy to modify this in the KeyboardView, it would probably be better to write this logic from scratch if you need it.

Resources

Getting Started:
https://developer.android.com/guide/topics/text/creating-input-method.html
http://www.fampennings.nl/maarten/android/09keyboard/index.htm

Sample Code:
https://android.googlesource.com/platform/development/+/master/samples/SoftKeyboard/
https://github.com/blackcj/AndroidCustomKeyboard

Spell Checker:
https://android.googlesource.com/platform/development/+/master/samples/SpellChecker/HelloSpellChecker/src/com/example/android/hellospellchecker/HelloSpellCheckerActivity.java
https://developer.android.com/guide/topics/text/spell-checker-framework.html

Other:
https://github.com/zeuxisoo/android-emoji-keyboard
https://stackoverflow.com/questions/7752580/creating-a-softkeyboard-with-multiple-alternate-characters-per-key

Stackoverflow Posts:
https://stackoverflow.com/questions/30654687/how-can-i-show-the-candidates-view-under-the-android-soft-keyboard
https://stackoverflow.com/questions/18180136/how-to-change-background-color-or-theme-of-keys-dynamically-in-custom-keyboard-a
https://stackoverflow.com/questions/17714172/how-to-change-key-background-of-any-key-in-android-soft-keyboard
https://stackoverflow.com/questions/9996968/hide-android-keyboard-key-preview
https://stackoverflow.com/questions/2888896/add-words-to-androids-userdictionary

Getting Started with Bitrise.io

Problem:

Most automated build servers don’t play well with mobile apps. Even after considerable configuration they still require a lot of up work for each new app.

Solution:

A friend of mine recently introduced me to Bitrise.io, an automated build server specifically built for mobile (Android, iOS & Xamarin). I’m happy to say that I was up and running in less than 30 minutes. With set up complete, adding a second project took just minutes.

Why do you need a build server?

Build servers are very useful and help ensure the stability of your codebase. If you’re code doesn’t compile or you forgot to check in a necessary resource to version control, your build server will notify you that something is wrong. Build servers also allow you to automate builds for QA and will keep a record of release builds. Still not convinced? Check out this blog.

Adding Your First Android Project to Bitrise.io

You can easily hook Bitrise.io up to your existing GitHub or Bitbucket account. If you host your own Git server, setup is as simple as adding an SSH key to your authorized_keys file.

Repo Setup

After you’ve added the SSH key as a new line to your authorized_keys file, select the branch you want to use. Select a stable branch that builds successfully on your local machine.

Repo Setup

I ran into a hiccup at this point. The project I added was one that I created almost a year ago. The gradle wrapper was too old to work with Bitrise.io and the error was a bit cryptic.

* What went wrong:
A problem occurred evaluating project ':app'.
> Failed to apply plugin [id 'com.android.application']
   > Gradle version 2.2 is required. Current version is 2.10.
     If using the gradle wrapper, try editing the distributionUrl
     in /bitrise/src/gradle/wrapper/gradle-wrapper.properties to
     gradle-2.2-all.zip

I was using version 2.2.1 and the current version is 2.8 so I’m not sure what the numbers in the error actually represent. A quick Stack Overflow search yielded the following result.

The solution

Update your graddle-wrapper.properties file:

distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip

I also updated to gradle 1.5 in my build.gradle file for good measure:

classpath ‘com.android.tools.build:gradle:1.2.3′
classpath ‘com.android.tools.build:gradle:1.5.0′

After checking in the code, everything compiled successfully! My ScoreKeeper app for Android Wear is now set up on Bitrise.io.

Android News for June 2015

Android Design Support Library

The design support library makes it easy to use material design when building Android apps. The best part, it’s compatible all the way back to Android 2.1. This support library includes a better navigation drawer, collapsing navigation bars, snack bars and a number of other key components of material design. Combine this with a view pager, recycler view and the swipe to refresh library for a complete base application.

Google developer blog:
http://android-developers.blogspot.com/2015/05/android-design-support-library.html

Sample code:
https://github.com/blackcj/DesignSupportExample

Developing for Android: Technical Guide

Google released a collection of best practices and common pitfalls written by the Android framework and runtime teams. This is a must read for all Android developers. It’s only eight chapters long so you have no excuse not to read it.

https://medium.com/google-developers/developing-for-android-introduction-5345b451567c

Free Material Design Icons

Need icons for your Android, iOS or Web app? Google has provided a great collection of icons that are free to use:

https://google.github.io/material-design-icons/
https://www.google.com/design/icons/

Stay tuned for more Android news and examples.