Converting Android Apps into Android Add-ons

This guide describes how to convert an existing Android app to an Android add-on. If you are building an Android add-on from scratch, build it as a stand-alone Android app first, then follow these steps to make it an Android add-on.

If you're new to Android app development you may want to begin by following the Android Developer tutorial for Building Your First Android App.

Modify your Android manifest

Exposing add-on functionality from an existing Android app is as easy as adding an <intent-filter> to your app's Android manifest. In your app's manifest file , find the activity you’d like to expose as an add-on and add an <intent-filter> tag indicating your app can handle add-on intents, as demonstrated in this example:

<activity
    android:name="com.example.YourActivityName"
    android:label="@string/activity_name" >
    <intent-filter
        android:label="@string/addon_name"
        android:icon="@drawable/addon_icon">
        <action android:name="com.google.android.apps.docs.editors.sheets.ADDON" />
    </intent-filter>
</activity>

Adding this intent-filter will cause your add-on to be shown in the add-ons Menu in the Google Sheets app. You should provide an icon and label to be shown in the add-ons menu by specifying android:label and android:icon attributes for your intent filter (see Providing Resources and Accessing Resources from XML ).

To have your add-on extend Google Docs instead of Sheets, simply change the value of the <action> tag in the above example from:

"com.google.android.apps.docs.editors.sheets.ADDON"

to

"com.google.android.apps.docs.editors.docs.ADDON"

If your activity can extend both Docs and Sheets, include both <action/> tags in the intent-filter. Your add-on can determine at runtime which editor triggered it using your activity's getCallingPackage() method.

For more background on the intent-based mechanisms Android apps use to communicate, see Intents and Intent Filters.

Provide a default launcher activity

Most Android apps define a default launcher activity in their manifest. This activity is the first one started when the app is launched from the device's Home screen, and serves as the main entry point to the app.

Always include a launcher activity, even if launching your Android add-on on its own isn't useful. This will handle cases when the add-on is launched directly, for example if a user taps the install notification.

If you do not provide a launcher activity, a user who launches your add-on directly will be taken to a basic screen stating Item not found, with a simple Retry button that will not give them access to your app or explain what is happening. This is a poor user experience you should avoid.

If you are extending an existing Android app to be an Android add-on, chances are you already have a launcher activity and will avoid this issue. If you don't, be sure to create one. If the add-on functionality needs context from the Docs or Sheets apps to function at all, make a simple launcher activity that explains this to the user and provides a button to close the app.

Set Android permissions

Android add-on apps must have the GET_ACCOUNTS Android permission. This is necessary to allow your app to receive the Google account associated with the active document.

To request this permission, place the following tag in the <manifest> section of your app’s Android manifest. Many existing apps already request this permission.

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

In addition, your add-on should also make use of runtime permissions when possible and follow the runtime permission best practices.

Modify your add-on activity

When a user selects your add-on from the Add-ons menu in a Google Apps editor, the activity specified in your manifest will be started. In your activity’s onCreate method you’ll want to grab the intent used to start your activity as this will contain:

  • The document ID of the Doc or Sheet currently open in the editor app
  • The session state of that Doc or Sheet (as an encoded String)
  • The account of the user calling the add-on

You can get this intent by calling your activity’s getIntent() method. The resulting activity will likely resemble this example:

import android.accounts.Account;
import android.app.Activity;

public class MyAddOnActivity extends Activity {
  // Your activity...

  String sessionState;
  String docId;
  Account account;

  @Override
  protected void onCreate(Bundle state) {
    super.onCreate(state);
    docId = getIntent().getStringExtra(
        "com.google.android.apps.docs.addons.DocumentId");
    sessionState = getIntent().getStringExtra(
        "com.google.android.apps.docs.addons.SessionState");
    account = (Account) getIntent().getParcelableExtra(
        "com.google.android.apps.docs.addons.Account");
    // Your activity’s initialization...
  }
}

When your activity is finished and is ready to return the user back to the Google editor, set the result code and call your activity's finish() method, like so:

setResult(Activity.RESULT_OK);
finish();

Use document context with the Execution API

Most Android add-ons will make use of Apps Script Execution API. When using the API, including the session state String ensures that Apps Script functions have the correct document context. This allows the API to call Apps Script methods that typically require the script to be container-bound to a particular Doc or Sheet, such as DocumentApp.getActiveDocument().

In order to ensure the Execution API has the correct context when called from an Android app, you just have to include the session state string when building the ExecutionRequest object:

    // Acquire the session state String from the calling Intent.
    sessionState = getIntent().getStringExtra(
        "com.google.android.apps.docs.addons.SessionState");
    ...
    // Construct the API request.
    ExecutionRequest request = new ExecutionRequest().
            .setFunction(functionName)
            .setSessionState(sessionState)
            .setParameters(params)   // Only needed if the function requires parameters
            .setDevMode(true);       // Optional

See the Apps Script Execution API Android Quickstart for an example of how to call an Apps Script function from an Android app using the API.

Create OAuth credentials

Android add-ons that make use of the Apps Script Execution API must to enable the API in the Cloud Platform project that the add-on is associated with. In addition, the add-on needs a valid Android OAuth credential, created using a SHA1 key. For debug builds, this process is described in Step 1 and Step 2 of the Execution API Android Quickstart.

Release builds that will be uploaded to the Google Play Store need to be properly Signed, using a keystore you create and a key specific to that app. Because they depend on a different keystore, release builds need their own OAuth credential. This is built using the same steps used to create the debug build credential, except that you can get the SHA1 key using:

$ keytool -exportcert -alias <key_alias> -keystore <path_to_keystore_file> -list -v

This command will ask you for the keystore password you set when you created the keystore (do not share this password with anyone).

Alternatively, you can also get the SHA1 keys for all your defined builds by running a signing report task from within Android Studio:

  1. Click Gradle on the right side of the IDE window.
  2. Navigate to MyApplication > Tasks > android and double-click signingReport.
  3. To view the report, click Gradle Console at the bottom of the IDE window.

A Cloud Platform project can support multiple Android OAuth credentials, so you can create as many as you need.

Run your unpublished add-on

Only add-ons approved through the curation process are normally visible in the editors’ menus. During development a not-yet-reviewed add-on can be treated as though it were approved by setting the app as the system debug app. Once you have an Android device in developer mode and attached to a development machine via USB, you can set your app as the debug app by running the Android Debug Bridge command:

$ adb shell am set-debug-app --persistent <YOUR_PACKAGE_NAME>

This will allow both debug and release builds of your add-on to run on your device.

The system debug app can be unset with:

$ adb shell am clear-debug-app

Send feedback about...

Apps Script
Apps Script