2012-10-30 19 views
31

Próbuję uzyskać dostępu do konta gmail i pobrać informacje o wszystkich nieprzeczytanych e-maili od tego.Odzyskiwanie wszystkie nieprzeczytane wiadomości e-mail przy użyciu JavaMail z protokołem POP3

Napisałem swój kod po poleceniu wielu linków. Daję kilka linków dla odniesienia.

Send & Receive emails through a GMail account using Java

Java Code to Receive Mail using JavaMailAPI

Aby przetestować mojego kodu, stworzyłem jednego konta Gmail. Otrzymałem 4 wiadomości z Gmaila. Uruchamiam moją aplikację po sprawdzeniu liczby wiadomości. To pokazało poprawny wynik. 4 nieprzeczytane wiadomości. Wyświetlane były wszystkie informacje (np. Data, nadawca, treść, temat itp.)

Następnie zalogowałem się na moje nowe konto, przeczytałem jeden z e-maili i ponownie uruchomiłem aplikację. Teraz liczba nieprzeczytanych wiadomości powinna wynosić 3, ale wyświetla "Liczba nieprzeczytanych wiadomości: 0"

Tutaj kopiuję kod.

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, "[email protected]", 
        "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(); 
    } 
} 

Szukałem na google, ale uważam, że należy użyć Flags.Flag.SEEN czytać nieprzeczytane wiadomości e-mail. Ale to nie pokazuje poprawnych wyników w moim przypadku.

Czy ktoś może wskazać, gdzie mogę popełnić jakiś błąd?

Jeśli potrzebujesz cały kod, mogę edytować mój post.

Uwaga: I edycja moje pytanie obejmować cały kod zamiast fragment miałem zamieszczonych wcześniej.

+1

Czy wiadomości 'Message Message [] nie powinny być' Message [] messages'? – berbt

+1

Właściwie oba są prawidłowe. Przeczytaj odpowiedzi powyżej [tutaj] (http://stackoverflow.com/a/1200681/1777090), aby uzyskać szczegółowe wyjaśnienie :) @berbt –

+3

Nowy kawałek nieoczekiwanej wiedzy. Dzięki za link! – berbt

Odpowiedz

12

Twój kod powinien zadziałać. Możesz także użyć metody Folder.getUnreadMessageCount(), jeśli chcesz tylko zliczenia.

JavaMail można tylko powiedzieć, co mówi, to Gmail. Może Gmail myśli, że wszystkie te wiadomości zostały przeczytane? Być może interfejs internetowy Gmaila oznacza, że ​​te wiadomości są czytane? Być może masz inną aplikację monitorującą folder dla nowych wiadomości?

Spróbuj przeczytać nieprzeczytane wiadomości z JavaMail i sprawdzić, czy zmiany policzyć.

Może okazać się użyteczne włączenie debugowania sesji, dzięki czemu można zobaczyć rzeczywiste odpowiedzi IMAP, które powraca Gmail; patrz JavaMail FAQ.

+0

Hej Bill, dzięki za pomoc. Nie chcę tylko liczby nieprzeczytanych e-maili. Potrzebuję wszystkich nieprzeczytanych e-maili. To tylko program demonstracyjny, ale nareszcie chcę pracować z załączaniem otrzymanych wiadomości e-mail w moim głównym projekcie. Próbowałem już używać metody getUnreadMessageCount() w mojej skrzynce odbiorczej. Ale zawsze zwraca -1. To też nie działa w moim przypadku. Zmienię moje pytanie i opublikuję tutaj cały mój kod. Bo myślę, że coś gdzieś idzie źle. –

+5

Witam, zorientowałem się, na czym polegał problem. Jak już powiedziałeś, próbowałem go debugować i zobaczyłem, że Gmail zwraca te wyniki. Zmieniłem ustawienia konta Gmail z zakładki Przekazywanie i POP/IMAP. Teraz działa poprawnie. Dzięki za pomoc. :) –

7

Zmiana inbox.open(Folder.READ_ONLY); na inbox.open(Folder.READ_WRITE); Zmieni to twoją pocztę jako przeczytaną w skrzynce odbiorczej.

+1

czy jesteś pewien, że działa to z pop3? w moim przypadku tak nie jest. –

+1

To działało dobrze dla mnie. Jakiej konfiguracji używałeś? – user1791574

1

Prawidłowe flaga do wykorzystania jest

Flags.Flag.RECENT 
+0

Pomimo tego, że JavaDoc dla [Folder # getNewMessageCount] (http://docs.oracle.com/javaee/5/api/javax/mail/Folder.html#getNewMessageCount()) mówi, że sprawdza flagę RECENT w celu zidentyfikowania nowe wiadomości, GMail faktycznie używa flagi SEEN do oznaczania przeczytanych wiadomości. – jFrenetic

1
Flags seen = new Flags(Flags.Flag.RECENT); 
FlagTerm unseenFlagTerm = new FlagTerm(seen, false); 
messages = inbox.search(unseenFlagTerm); 
6

Nie można pobrać nieprzeczytanych wiadomości za pomocą protokołu POP3. Od JavaMail API:

POP3 obsługuje żadnych stałych flagi (patrz Folder.getPermanentFlags()). W szczególności w flaga Flags.Flag.RECENT nigdy nie będzie ustawiona dla wiadomości POP3 . Od aplikacji zależy, które wiadomości w skrzynce pocztowej POP3 będą "nowe".

Można użyć protokołu IMAP i użyć postrzegane flagę tak:

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); 
} 

Inną rzeczą jest fakt, że nie obsługuje POP3 foldery. IMAP pobiera foldery, POP3 pobiera tylko skrzynkę odbiorczą. Więcej informacji pod adresem: How to retrieve gmail sub-folders/labels using POP3?