Search code examples
androidjakarta-mailemail-client

Android email client app tracking unread gmail emails


So I've been using javamail API as part of my android app. After a login to a gmail account, the user can write new emails, check the inbox and sent mails. The emails are displayed in a listview with the help of an adapter class. (more accurately the sender, the subject and the sending date is displayed, and if the user clicks on the listview item, then the mail content will be displayed too on a new activity). All this is working well.

I would like to display unread emails differently (unread in the gmail client too), like set the textSyle bold if the mail is unread, but i'm having trouble adding this feature. I've been trying to check the flags of each fetched email message, but for some reason i dont see these flags in the variables.

My code snippet for fetching the mails (display is not here, that's in the adapter class):

protected ArrayList<Email_Message> doInBackground(Void... args) {
        try {
            Properties properties = new Properties();
            properties.put("mail.store.protocol", "imaps");

            Session emailSession = Session.getDefaultInstance(properties);
            Store store = emailSession.getStore("imaps");
            store.connect("imap.gmail.com", username, password);

            // create the folder object and open it
            Folder emailFolder = store.getFolder("INBOX");
            emailFolder.open(Folder.READ_WRITE);
            Flags flags2 = emailFolder.getPermanentFlags(); //has 2 weird user flags in it ($phishing, $notphising) and systemflags = -2147483061 ???

            Flags seen = new Flags(Flags.Flag.RECENT);
            FlagTerm unseenFlagTerm = new FlagTerm(seen, false);
            Message messages2[] = emailFolder.search(unseenFlagTerm); //this will net the same result as getMessages(), only here for testing

            int test = emailFolder.getUnreadMessageCount(); //as far as i can tell this is working (i have 5000+ emails and 37 them are unread somewhere) but when i get a new email and the number goes up by 1 (38), and if i run the code again, after i already fetched the mails once, it's gonna be 37 again, and the mail marked as read in my gmail webclient too

            // retrieve the messages from the folder in an array and print it
            Message[] messages = emailFolder.getMessages();
            int j = messages.length - 1;
            for (int i = j - startIndex; i > j - startIndex - offset && i > (-1); i--) { //startIndex and offset are for displaying only 10 messages at the start and loading another 10 if the user scrolls to bottom
                if (isCancelled()){
                    break;
                }
                Email_Message mailMessage = new Email_Message(); //my class for storing email messages
                mailMessage.messageType = 1;
                //some tricks to get the address in the right format
                Address[] email_address = messages[i].getFrom();
                String tempAddress = email_address[0].toString();
                tempAddress = MimeUtility.decodeText(tempAddress);
                //still tempering with address, not important
                if(tempAddress.contains("=?")){
                    String[] AddressParts = tempAddress.split("\\?=");
                    mailMessage.messageAddress = AddressParts[1].substring(2);
                }
                else {
                    mailMessage.messageAddress = tempAddress;
                }


                Flags flags = messages[i].getFlags(); //user_flags = null, system_flags = 32
                Flags.Flag[] systemflags = flags.getSystemFlags(); //has 1 item in it: bit = 32
                String str[]= flags.getUserFlags(); //empty, these are all true for all my mails, not just one
                mailMessage.messageDate = messages[i].getSentDate().toString();
                mailMessage.messageSubject = messages[i].getSubject();
                Object msgContent = messages[i].getContent();
                String content = ""; //getting the content of the mail with these multipart stuffs
                if (msgContent instanceof Multipart) { 

                    Multipart multipart = (Multipart) msgContent;

                    Log.e("BodyPart", "MultiPartCount: " + multipart.getCount());

                    for (int k = 0; k < multipart.getCount(); k++) {

                        BodyPart bodyPart = multipart.getBodyPart(k);

                        String disposition = bodyPart.getDisposition();

                        if (disposition != null && (disposition.equalsIgnoreCase("ATTACHMENT"))) {
                            DataHandler handler = bodyPart.getDataHandler();
                            content = handler.getName();
                        } else {
                            content = bodyPart.getContent().toString();
                        }
                    }
                } else
                    content = messages[i].getContent().toString();
                mailMessage.messageContent = content;
                EmailInbox.add(mailMessage);
            }
            // close the store and folder objects
            emailFolder.close(false);
            store.close();

        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return EmailInbox;
    }

I put some comments in the code to explain what i've found in the flags. What can I do to make this work? I already predict problems, like what happens after I read an unread mail in my app only, set its flag to seen, and when I start the activity again and fetch the mails, it's gonna be unread again, since I don't store them locally, but that's a problem after I managed to find a solution for this first.

Thanks for any help!


Solution

  • I'm not clear on how you're looking for the flags. Using messages[i].isSet(Flags.Flag.SEEN) will tell you if the SEEN flag has been set. Note that the SEEN flag will normally be set as soon as you access the content of the message, so you should not have to set it yourself.

    Hint: use the InternetAddress.toUnicodeString method, or get the name and address separately using the getPersonal and getAddress methods. This will avoid any need to decode them yourself.