The Gmail app for Android includes a [content
provider](https://developer.android.com/guide/topics/providers/content-providers)
that third-party developers can use to retrieve label information, such
as 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.

> [!NOTE]
> **Note:** This content provider is supported in versions after 2.3.6 (Froyo/Gingerbread) and 4.0.5 (Honeycomb/ICS).

Before using this content provider, call the
[`GmailContract.canReadLabels(Context)`](https://developers.google.com/workspace/gmail/android/com/google/android/gm/contentprovider/GmailContract#canReadLabels(Context))
method to determine whether the user's version of the Gmail app
supports these queries.

## Find a valid Gmail account to query

An app must first find the email address of a valid Gmail account
to query for label information. With the
[`GET_ACCOUNTS`](https://developer.android.com/reference/android/Manifest.permission#GET_ACCOUNTS)
permission, the
[`AccountManager`](https://developer.android.com/reference/android/accounts/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 */);

## Query the content provider

With an email address selected, you can then obtain a
[`ContentProvider`](https://developer.android.com/guide/topics/providers/content-provider-basics)
URI to query against. We've provided a class called
[`GmailContract`](https://developers.google.com/workspace/gmail/android/com/google/android/gm/contentprovider/GmailContract)
to construct the URI and define the columns returned. An app can query this URI
directly.

With the data in the `Cursor`, you can persist the URI value in the
[`GmailContract.Labels.URI`](https://developers.google.com/workspace/gmail/android/com/google/android/gm/contentprovider/GmailContract.Labels#URI)
column to query and watch for changes on a single label.

The `NAME` value for predefined labels can vary by locale, so don't use
[`GmailContract.Labels.NAME`](https://developers.google.com/workspace/gmail/android/com/google/android/gm/contentprovider/GmailContract.Labels#NAME).
Instead, you can programmatically identify predefined labels such as Inbox,
Sent, or Drafts using the string value in the
[`GmailContract.Labels.CANONICAL_NAME`](https://developers.google.com/workspace/gmail/android/com/google/android/gm/contentprovider/GmailContract.Labels#CANONICAL_NAME)
column:

    // Query for all labels and find the Inbox.
    try (Cursor labelsCursor = getContentResolver().query(
            GmailContract.Labels.getLabelsUri(selectedAccount), null, null, null, null)) {
        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.
                }
            }
        }
    }

For more information, see [Content provider
basics](https://developer.android.com/guide/topics/providers/content-provider-basics).

## Review an example

To see an example of this content provider in action, [download a sample
app](https://developers.google.com/static/workspace/gmail/android/android-gmail-api-sample.tar.gz).