36

I am trying to access my gmail account and retrieve the information of all unread emails from that.

I have written my code after referring many links. I am giving a few links for reference.

Send & Receive emails through a GMail account using Java

Java Code to Receive Mail using JavaMailAPI

To test my code, I created one Gmail account. So I received 4 messages in that from Gmail. I run my application after checking number of mails. That showed correct result. 4 unread mails. All the infomation was being displayed (e.g. date, sender, content, subject, etc.)

Then I logged in to my new account, read one of the emails and rerun my application. Now the count of unread message should have been 3, but it displays "No. of Unread Messages : 0"

I am copying the code here.

public class MailReader

{

    Folder inbox;

    // Constructor of the calss.

    public MailReader() {
        System.out.println("Inside MailReader()...");
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";

        /* Set the mail properties */

        Properties props = System.getProperties();
        // Set manual Properties
        props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.pop3.socketFactory.fallback", "false");
        props.setProperty("mail.pop3.port", "995");
        props.setProperty("mail.pop3.socketFactory.port", "995");
        props.put("mail.pop3.host", "pop.gmail.com");

        try

        {

            /* Create the session and get the store for read the mail. */

            Session session = Session.getDefaultInstance(
                    System.getProperties(), null);

            Store store = session.getStore("pop3");

            store.connect("pop.gmail.com", 995, "abc@gmail.com",
                    "paasword");

            /* Mention the folder name which you want to read. */

            // inbox = store.getDefaultFolder();
            // inbox = inbox.getFolder("INBOX");
            inbox = store.getFolder("INBOX");

            /* Open the inbox using store. */

            inbox.open(Folder.READ_ONLY);

            /* Get the messages which is unread in the Inbox */

            Message messages[] = inbox.search(new FlagTerm(new Flags(
                    Flags.Flag.SEEN), false));
            System.out.println("No. of Unread Messages : " + messages.length);

            /* Use a suitable FetchProfile */
            FetchProfile fp = new FetchProfile();
            fp.add(FetchProfile.Item.ENVELOPE);

            fp.add(FetchProfile.Item.CONTENT_INFO);

            inbox.fetch(messages, fp);

            try

            {

                printAllMessages(messages);

                inbox.close(true);
                store.close();

            }

            catch (Exception ex)

            {
                System.out.println("Exception arise at the time of read mail");

                ex.printStackTrace();

            }

        }

        catch (MessagingException e)
        {
            System.out.println("Exception while connecting to server: "
                    + e.getLocalizedMessage());
            e.printStackTrace();
            System.exit(2);
        }

    }

    public void printAllMessages(Message[] msgs) throws Exception
    {
        for (int i = 0; i < msgs.length; i++)
        {

            System.out.println("MESSAGE #" + (i + 1) + ":");

            printEnvelope(msgs[i]);
        }

    }

    public void printEnvelope(Message message) throws Exception

    {

        Address[] a;

        // FROM

        if ((a = message.getFrom()) != null) {
            for (int j = 0; j < a.length; j++) {
                System.out.println("FROM: " + a[j].toString());
            }
        }
        // TO
        if ((a = message.getRecipients(Message.RecipientType.TO)) != null) {
            for (int j = 0; j < a.length; j++) {
                System.out.println("TO: " + a[j].toString());
            }
        }
        String subject = message.getSubject();

        Date receivedDate = message.getReceivedDate();
        Date sentDate = message.getSentDate(); // receivedDate is returning
                                                // null. So used getSentDate()

        String content = message.getContent().toString();
        System.out.println("Subject : " + subject);
        if (receivedDate != null) {
            System.out.println("Received Date : " + receivedDate.toString());
        }
        System.out.println("Sent Date : " + sentDate.toString());
        System.out.println("Content : " + content);

        getContent(message);

    }

    public void getContent(Message msg)

    {
        try {
            String contentType = msg.getContentType();
            System.out.println("Content Type : " + contentType);
            Multipart mp = (Multipart) msg.getContent();
            int count = mp.getCount();
            for (int i = 0; i < count; i++) {
                dumpPart(mp.getBodyPart(i));
            }
        } catch (Exception ex) {
            System.out.println("Exception arise at get Content");
            ex.printStackTrace();
        }
    }

    public void dumpPart(Part p) throws Exception {
        // Dump input stream ..
        InputStream is = p.getInputStream();
        // If "is" is not already buffered, wrap a BufferedInputStream
        // around it.
        if (!(is instanceof BufferedInputStream)) {
            is = new BufferedInputStream(is);
        }
        int c;
        System.out.println("Message : ");
        while ((c = is.read()) != -1) {
            System.out.write(c);
        }
    }

    public static void main(String args[]) {
        new MailReader();
    }
}

I searched on google, but I found that you should use Flags.Flag.SEEN to read unread emails. But thats not showing correct results in my case.

Can someone point out where I might be doing some mistake?

If you need whole code, I can edit my post.

Note: I edited my question to include whole code instead of snippet I had posted earlier.

Technotronic
  • 7,011
  • 3
  • 35
  • 51
MysticMagicϡ
  • 27,509
  • 15
  • 68
  • 114
  • 1
    Shouldn't `Message messages[]` be `Message[] messages`? – berbt Jun 23 '14 at 13:11
  • 2
    Actually both are valid. Read the answers over [here](http://stackoverflow.com/a/1200681/1777090) for detailed explanation :) @berbt – MysticMagicϡ Jun 23 '14 at 13:18
  • 3
    A new bit of unexpected knowledge. Thanks for the link! – berbt Jun 23 '14 at 15:07
  • Does it work for you now? For me, it returns "Exception while connecting to server: [AUTH] Web login required: https://support.google.com/mail/answer/78754" - and also I wonder how it can work if the FAQ says "The POP3 protocol doesn't provide support for any permanent flags so the RECENT flag is of no use. The com.sun.mail.pop3 package documentation discusses several strategies for dealing with this problem." for the question " How can I tell which messages are new with POP3?"... @Bill Shannon – Line May 15 '17 at 08:13
  • It worked for me after enabling unsecure applications in settings, and adding Session emailSession = Session.getDefaultInstance(properties, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(user, password); } }); – devssh May 30 '18 at 10:55
  • I got the messages, but my inbox has 900 unread messages and many more read messages. The Message[] length I got was only 331 messages, and I can't find other folders, what is wrong? – devssh May 30 '18 at 10:57

6 Answers6

14

Your code should work. You can also use the Folder.getUnreadMessageCount() method if all you want is the count.

JavaMail can only tell you what Gmail tells it. Perhaps Gmail thinks that all those messages have been read? Perhaps the Gmail web interface is marking those messages read? Perhaps you have another application monitoring the folder for new messages?

Try reading an unread message with JavaMail and see if the count changes.

You might find it useful to turn on session debugging so you can see the actual IMAP responses that Gmail is returning; see the JavaMail FAQ.

Bill Shannon
  • 27,854
  • 5
  • 34
  • 37
  • Hey Bill, thanks for help. I don't want just the number of unread emails. What I need is all unread emails. It is just a demo program, but at last I want to work with attachment of received email in my main project. I already tried using getUnreadMessageCount() method on my inbox. But it always returns -1. So that doesn't work in my case either. I will edit my question and post my whole code here. Because I think something is going wrong somewhere. – MysticMagicϡ Oct 31 '12 at 04:32
  • 5
    Hi, I figured out what the problem was.. As you said, I tried debugging it, and saw that Gmail was returning those results. I changed my settings of Gmail account from tab Forwarding and POP/IMAP. So now it is working properly. Thanks for help. :) – MysticMagicϡ Oct 31 '12 at 05:23
11

You cannot fetch unread messages with POP3. From JavaMail API:

POP3 supports no permanent flags (see Folder.getPermanentFlags()). In particular, the Flags.Flag.RECENT flag will never be set for POP3 messages. It's up to the application to determine which messages in a POP3 mailbox are "new".

You can use IMAP protocol and use the SEEN flag like this:

public Message[] fetchMessages(String host, String user, String password, boolean read) {
    Properties properties = new Properties();
    properties.put("mail.store.protocol", "imaps");

    Session emailSession = Session.getDefaultInstance(properties);
    Store store = emailSession.getStore();
    store.connect(host, user, password);

    Folder emailFolder = store.getFolder("INBOX");
    // use READ_ONLY if you don't wish the messages
    // to be marked as read after retrieving its content
    emailFolder.open(Folder.READ_WRITE);

    // search for all "unseen" messages
    Flags seen = new Flags(Flags.Flag.SEEN);
    FlagTerm unseenFlagTerm = new FlagTerm(seen, read);
    return emailFolder.search(unseenFlagTerm);
}

Another thing to notice is that POP3 doesn't handle folders. IMAP gets folders, POP3 only gets the Inbox. More info at: How to retrieve gmail sub-folders/labels using POP3?

Community
  • 1
  • 1
Technotronic
  • 7,011
  • 3
  • 35
  • 51
8

Change inbox.open(Folder.READ_ONLY); to inbox.open(Folder.READ_WRITE); It will change your mail as read in inbox.

erakitin
  • 10,743
  • 5
  • 40
  • 46
user1791574
  • 1,669
  • 2
  • 16
  • 29
4
Flags seen = new Flags(Flags.Flag.RECENT);
FlagTerm unseenFlagTerm = new FlagTerm(seen, false);
messages = inbox.search(unseenFlagTerm);
MysticMagicϡ
  • 27,509
  • 15
  • 68
  • 114
ibrahimKiraz
  • 391
  • 3
  • 13
  • 1
    This isn't correct. You can have recent emails that are also read. The correct way to retrieve UNREAD emails was provided by Technotronic. – hfontanez Sep 27 '19 at 21:24
1

The correct flag to use is

Flags.Flag.RECENT
MysticMagicϡ
  • 27,509
  • 15
  • 68
  • 114
  • Despite the fact, that JavaDoc for [Folder#getNewMessageCount](http://docs.oracle.com/javaee/5/api/javax/mail/Folder.html#getNewMessageCount()) says that it checks RECENT flag to identify new messages, GMail actually uses flag SEEN to mark read messages. – jFrenetic Aug 12 '14 at 17:34
-1

please use this method to get the unread mails

getNewMessageCount()

refer below link:

https://javamail.java.net/nonav/docs/api/com/sun/mail/imap/IMAPFolder.html

vidhyadhar
  • 60
  • 3