8

Please note there is a new way of doing this

I've been trying to get the number of unread gmail mails with no luck.

I've read Gmail.java and gmail4j both links taken out of this site from this question: Android - How can I find out how many unread email the user has?

But still after having read all of that and a couple of other sites that talked about this particular subject my question remains:

Q: How can I get the Gmail Unread Count?

Sorry if it seams a bit insistent but I clearly lack the knowledge to find this out on my own from the source.

PS: I would like to clarify that I want to do it without having to ask the user for credentials.

Just 2 add some colors to the question let me show you the looks of my app.

alt text

Please note there is a new way of doing this

Community
  • 1
  • 1
Lord Otori
  • 349
  • 1
  • 4
  • 17

5 Answers5

21

Here's some code snippet. Not sure it works and can't test it. But I hope it will help you to continue the investigation.

public static final class LabelColumns {
    public static final String CANONICAL_NAME = "canonicalName";
    public static final String NAME = "name";
    public static final String NUM_CONVERSATIONS = "numConversations";
    public static final String NUM_UNREAD_CONVERSATIONS = "numUnreadConversations";
}

public void queryLabels(){
    String account="email@company.com";
    Uri LABELS_URI = Uri.parse("content://gmail-ls/labels/");
    Uri ACCOUNT_URI = Uri.withAppendedPath(LABELS_URI, account);
    ContentResolver contentResolver=myActivity.getContentResolver();
    Cursor cursor = contentResolver.query(ACCOUNT_URI, null, null, null, null);

    //iterate over all labels in the account
    if (cursor.moveToFirst()) {
        int unreadColumn = cursor.getColumnIndex(LabelColumns.NUM_UNREAD_CONVERSATIONS);
        int nameColumn = cursor.getColumnIndex(LabelColumns.NAME);
        do {
            String name = cursor.getString(nameColumn);
            String unread = cursor.getString(unreadColumn);//here's the value you need
        } while (cursor.moveToNext());
    }
}

Requires permission

<uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/>
Fedor
  • 43,261
  • 10
  • 79
  • 89
  • That look to me like it's ok, but with that code I get this debug message: 06-14 17:37:03.451: DEBUG/Gmail(13764): MailProvider.query: content://gmail-ls/labels/------@gmail.com(null, null) please note that my email address is not ------@gmail.com but i've replaced it. Also to correctly query the permission "com.google.android.providers.gmail.permission.READ_GMAIL" is needed. – Lord Otori Jun 14 '10 at 20:40
  • Works great for me on 2.2. Returns the correct numbers of unread messages. The required permission is com.google.android.gm.permission.READ_GMAIL for me. All code was taken from Gmail.java so you may find more details there. – Fedor Jun 15 '10 at 12:00
  • I found a problem with that... I could not find a way to test this code on the 2.2 since I do not have a mobile runing that version of android. And the avd comes without GMAIL service... – Lord Otori Jun 16 '10 at 18:42
  • This answer came up for me in a search, but look at this link: http://stackoverflow.com/questions/6871200/securityexception-permission-denial-error . It doesn't reliably work anymore – Nanne Sep 20 '11 at 19:22
  • 5
    This only works in Android 2.2 or earlier, not in newer versions. – sabadow Dec 15 '11 at 11:13
  • Hi i need the above example.so if don't mind please give compleat code. – kiran May 16 '12 at 05:14
5

This is how I've seen it done in a simple widget for the awesome window manager (yes, that's its name :)). Original script is here: gmail.lua.

The basic concept is to just use the inbox feed and get all the mails (you'll get just the summaries, not the whole content) for the special 'unread' tag. The URL is https://mail.google.com/mail/feed/atom/unread, you just have to fetch it (after authentication, of course), and then parse it. You can either use some sort of XML parser or just a simple regexp (<fullcount>([%d]+)</fullcount>) - the number you are looking for is at the beginning, in the <fullcount> tag.

So, that's one way of doing it, quite simple and "dumb", but hey, it works :D It might not be the best solution, as it requires you to fetch the whole feed (depending on the number of your unread messages and the type/quality of connection, it might not be as fast as just fetching the number of unread messages), but as usual, real-life testing should clear that up :)

Igor Klimer
  • 15,321
  • 3
  • 47
  • 57
  • Thanks for taking the time to answer the Question but the thing is: I want to do this on Android (Title of the question) And I need to do this without having to use the user credentials. (Body of the question) Thanks :) – Lord Otori Jun 13 '10 at 16:14
  • Well, yes, I noticed it's for the Android, and from the question you linked it appeared that there's no "silver bullet"-type of solution. So I figured you might want to use a different approach, one that does not rely on Android's software, but is more generic. As you pointed out though, it has the downside that it needs to ask for user credentials. – Igor Klimer Jun 13 '10 at 18:39
1

There is new way how to do it. Old way doesn´t work anymore (21.01.2013). Check following link: Gmail Public Labels API

Michal
  • 2,071
  • 19
  • 30
  • Thank you for the update, I'm not going to change the selected answer because the answer was correct at the time. But I do thank you for your help. – Lord Otori Jan 22 '13 at 00:56
0
static final String AUTHORITY = "com.google.android.gm";
static final String BASE_URI_STRING = "content://" + AUTHORITY;
static final String LABELS_PARAM = "/labels";
static final String ACCOUNT_TYPE_GOOGLE = "com.google";

public static final String NUM_UNREAD_CONVERSATIONS = "numUnreadConversations";
public static final String CANONICAL_NAME = "canonicalName";

public static final String CANONICAL_NAME_INBOX_CATEGORY_PRIMARY = "^sq_ig_i_personal";
static String[] GMAIL_PROJECTION = {
    CANONICAL_NAME, NUM_UNREAD_CONVERSATIONS
    };

public static Uri getLabelsUri(String account) {
    return Uri.parse(BASE_URI_STRING + "/" + account + LABELS_PARAM);
}

static String[] getAllAccountNames(Context context) {
   final Account[] accounts = AccountManager.get(context).getAccountsByType(
           ACCOUNT_TYPE_GOOGLE);
   final String[] accountNames = new String[accounts.length];
   for (int i = 0; i < accounts.length; i++) {
       accountNames[i] = accounts[i].name;
   }
   return accountNames;
}


protected static int getGmail(Context context) {
    ContentResolver cr = context.getContentResolver();
    Cursor cursor =        cr.query(Launcher.getLabelsUri(BadgeUtils.getAllAccountNames(context)[0]),
            GMAIL_PROJECTION,
            null, null,
            null);

    if (cursor == null || cursor.isAfterLast()) {
        Log.d(TAG, "No Gmail inbox information found for account.");
        if (cursor != null) {
            cursor.close();
        }
        return 0;
    }

    int count = 0;

    while (cursor.moveToNext()) {
        if (CANONICAL_NAME_INBOX_CATEGORY_PRIMARY.equals(cursor.getString(cursor.getColumnIndex(CANONICAL_NAME)))) {
            count = cursor.getInt(cursor.getColumnIndex(NUM_UNREAD_CONVERSATIONS));;
            break;
        }
    }

    cursor.close();


    return count;
}

Hope above code helps. This should work on Android 2.2+.

Miran
  • 31
  • 4
0

Maybe you can use the Gmail ContentProvider, please see http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/provider/Gmail.java&q=Gmail.java&sa=N&cd=1&ct=rc

There is a method getNumUnreadConversations or you could use a Observer.

zehrer
  • 1,660
  • 1
  • 14
  • 19
  • Could you elaborate a bit more? as I said on the question: "I clearly lack the knowledge to find this on my own" I've tried to take that method out of the Gmail.java but I cant. Do I have to copy the whole code for this to work? – Lord Otori Jun 13 '10 at 16:09