Android Gmail

The Android Gmail app starting in versions 2.3.6 (Froyo/Gingerbread) and 4.0.5 (Honeycomb/ICS) includes a new Content Provider API that third party developers can use to retrieve label information like name and unread count, and stay updated as that information changes. For example, an app or widget could display the unread count of a specific account's inbox.

Before using the Labels API, be sure your code first checks if the user's version of the Gmail app supports these new queries. We've provided a handy GmailContract.canReadLabels(Context) method to help determine this.

To use the Labels API, an app must first find the email address of a valid Gmail account to query for label information. With the GET_ACCOUNTS permission, the AccountManager can return this information:

// Get the account list, and pick the first one
final String ACCOUNT_TYPE_GOOGLE = "com.google";
final String[] FEATURES_MAIL = {
        "service_mail"
};
AccountManager.get(this).getAccountsByTypeAndFeatures(ACCOUNT_TYPE_GOOGLE, FEATURES_MAIL,
        new AccountManagerCallback() {
            @Override
            public void run(AccountManagerFuture future) {
                Account[] accounts = null;
                try {
                    accounts = future.getResult();
                    if (accounts != null && accounts.length > 0) {
                        String selectedAccount = accounts[0].name;
                        queryLabels(selectedAccount);
                    }

                } catch (OperationCanceledException oce) {
                    // TODO: handle exception
                } catch (IOException ioe) {
                    // TODO: handle exception
                } catch (AuthenticatorException ae) {
                    // TODO: handle exception
                }
            }
        }, null /* handler */);

With an email address selected, you can then obtain a ContentProvider URI to query against. We've provided a simple class called GmailContract.java to construct the URI and define the columns returned.

An app can query this URI directly (or better yet: use a CursorLoader) to obtain a Cursor with information for all labels on an account:

Cursor labelsCursor = getContentResolver().query(GmailContract.Labels.getLabelsUri(selectedAccount), null, null, null, null);

With the data in this cursor, you can then persist the URI value in the GmailContract.Labels.URI column to query and watch for changes on a single label.

The NAME value for pre-defined labels can vary by locale, so don't use GmailContract.Labels.NAME. Instead, you can programmatically identify pre-defined labels like Inbox, Sent or Drafts using the String value in the GmailContract.Labels.CANONICAL_NAME column:

// loop through the cursor and find the Inbox
if (labelsCursor != null) {
    final String inboxCanonicalName = GmailContract.Labels.LabelCanonicalName.CANONICAL_NAME_INBOX;
    final int canonicalNameIndex = labelsCursor.getColumnIndexOrThrow(GmailContract.Labels.CANONICAL_NAME);
    while (labelsCursor.moveToNext()) {
        if (inboxCanonicalName.equals(labelsCursor.getString(canonicalNameIndex))) {
            // this row corresponds to the Inbox
        }
    }
}

To see an example of this API in action, check out the sample app.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.