简体   繁体   English

javamail 将 gmail 消息标记为已读

[英]javamail mark gmail message as read

Note: added after answer: Thanks.. Yeah I had tried the Flag.SEEN to true and saveChanges.. I also had read getContent marks it read.注意:在回答后添加:谢谢.. 是的,我曾尝试将 Flag.SEEN 设置为 true 和 saveChanges.. 我还阅读了它读取的 getContent 标记。 I tried using it in the for statement that loops through the messages.我尝试在循环消息的 for 语句中使用它。 But I got the messages again from the folder anyways in the next loop.但无论如何,在下一个循环中,我还是从文件夹中再次收到了消息。 I was assuming the folder was live, so grabbing the content, then grabbing the messages again from the folder with the filter to not get any seen should work, but I was still getting the same message.我假设该文件夹是活动的,所以抓取内容,然后使用过滤器再次从文件夹中抓取消息以不被看到应该可以工作,但我仍然收到相同的消息。 I could try closing the folder and reopen as a test to see if it's marked.我可以尝试关闭文件夹并重新打开以测试它是否已标记。 Also if I go over to my client and click the message, then my code stops seeing it even in the loop, so I was hoping to do the same in the code.此外,如果我将 go 转到我的客户端并单击该消息,那么我的代码即使在循环中也不会看到它,所以我希望在代码中做同样的事情。

original: I'm using javamail to get email from a gmail account, it's working great, when I get the message I'd like to mark it as read, can anyone give me some direction?原文:我正在使用 javamail 从 gmail 帐户获取 email,效果很好,当我收到消息时,我想将其标记为已读,谁能给我一些指导? Here is my current code:这是我当前的代码:

    Properties props = System.getProperties();
    props.setProperty("mail.store.protocol", "imaps");
    try {
        Session session = Session.getDefaultInstance(props, null);
        Store store = session.getStore("imaps");

        store.connect("imap.gmail.com", eUserName, ePassWord);
        // Get folder
        Folder folder = store.getFolder("INBOX");
        if (folder == null || !folder.exists()) {
            return null;
        }
        folder.open(Folder.READ_ONLY);

        // Only pull unread
        FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
        Message messages[]; // = folder.search(ft);

        for(int x = 0; x < timeOutInSeconds; x++) {
            log.reportMessage("looking for emails");
            try {
                folder.getMessages();
                messages = folder.search(ft);

                if (messages.length > 0) {
                    for (Message message : messages) {
                        //log.reportMessage("found message: should not see again, marking read");
                        // want to mark as read

                    }
                }
                Thread.sleep(1000);
            }
            catch(Exception ex) {

            }
        }

        // Close connection
        folder.close(false);
        store.close();
        return null;

    }
    catch (NoSuchProviderException ex) {

        return null;
    }
    catch (MessagingException ex) {

        return null;
    }


}

First of all, you can't mark a message as read if you are using a POP3 server - the POP3 protocol doesn't support that.首先,如果您使用的是 POP3 服务器,则无法将消息标记为已读 - POP3 协议不支持。 However, the IMAP v4 protocol does.但是,IMAP v4 协议确实如此。

You might think the way to do this is to get the message, set the Flags.Flag.SEEN flag to true, and then call message.saveChanges() .您可能认为这样做的方法是获取消息,将Flags.Flag.SEEN标志设置为 true,然后调用message.saveChanges() Oddly, this is not the case.奇怪的是,事实并非如此。

Instead, the JavaMail API Design Specification, Chapter 4, section "The Flags Class" states that the SEEN flag is implicitly set when the contents of a message are retrieved.相反,JavaMail API 设计规范的第 4 章“标志类”部分指出在检索消息内容时隐式设置SEEN标志。 So, to mark a message as read, you can use the following code:因此,要将消息标记为已读,您可以使用以下代码:

myImapFolder.open(Folder.READ_WRITE);
myImapFolder.getMessage(myMsgID).getContent();
myImapFolder.close(false);

Or another way is to use the MimeMessage copy constructor, ie:或者另一种方法是使用 MimeMessage 复制构造函数,即:

MimeMessage source = (MimeMessage) folder.getMessage(1)
MimeMessage copy = new MimeMessage(source);

When you construct the copy, the seen flag is implicitly set for the message referred to by source.当您构造副本时,已为源引用的消息隐式设置了 seen 标志。

One liner that will do it WITHOUT downloading the entire message:一种无需下载整个消息即可完成的班轮:

single message:单个消息:

folder.setFlags(new Message[] {message}, new Flags(Flags.Flag.SEEN), true);

all messages:所有消息:

folder.setFlags(messages, new Flags(Flags.Flag.SEEN), true);

Other methods of calling getContent() or creating a copy with new MimeMessage(original) cause the client to download the entire message, and creates a huge performance hit.调用getContent()或使用new MimeMessage(original)创建副本的其他方法会导致客户端下载整个消息,并造成巨大的性能损失。

Note that the inbox must be opened for READ_WRITE:请注意,必须为 READ_WRITE 打开收件箱:

folder.open(Folder.READ_WRITE);

Well this post is old but the easiest solution hasn´t been posted yet.好吧,这篇文章很旧,但尚未发布最简单的解决方案。

You are accessing the Message.您正在访问消息。 message.setFlag(Flag.SEEN, true); message.setFlag(Flag.SEEN, true);

for (Message message : messages) {
                    message.setFlag(Flags.Flag.SEEN,true);
                }

and change the below line更改以下行

folder.open(Folder.READ_ONLY);

to this对此

folder.open(Folder.READ_WRITE);

You may also consider having a public static int max_message_number , and storing in it the message[i].getMessageNumber();您也可以考虑拥有一个public static int max_message_number ,并在其中存储message[i].getMessageNumber(); as soon as you read a message.只要你读到一条消息。 Then before reading any message just check if the max_message_number < message[i].getmessageNumber() .然后在阅读任何消息之前检查是否max_message_number < message[i].getmessageNumber() If true then don't print this message (as it has been already read)如果为真,则不要打印此消息(因为它已被阅读)

If you are using a for loop to read or check a mail one by one, the code can be as follows to mark a gmail message as read:如果您使用 for 循环逐个阅读或查看邮件,可以使用如下代码将 Gmail 邮件标记为已读:

    Message[] unreadMessages = inbox.search(new FlagTerm(new Flags(Flag.SEEN), false));
            for (int q = 0; q < unreadMessages.length; q++) {

              unreadMessages[q].setFlag(Flag.SEEN, true);

            }

What this code does is that it makes it unread one by one.这段代码的作用是让它一一未读。

And also folder/inbox needs to be READ_WRITE, instead of READ_ONLY:而且文件夹/收件箱需要是 READ_WRITE,而不是 READ_ONLY:

folder.open(Folder.READ_WRITE);

message.setFlag( Flag.SEEN,true ) 给出“找不到符号” message.setFlag( Flags.Flag.SEEN,true ) 似乎不错。

The easiest way to do that is set the folder to be read or written into or from.最简单的方法是设置要读取或写入的文件夹。 Means like this...意思是这样...

    Folder inbox = null;
    inbox.open(Folder.READ_WRITE);      

the Folder class should be imported.文件夹类应该被导入。

You can also try你也可以试试

head over to the gmail settings > Forwarding and POP/IMAP转到 Gmail 设置 > 转发和 POP/IMAP

from the dropdown of When messages are accessed with POP select mark Gmail's copy as read and save the changes使用 POP 访问邮件时的下拉菜单中选择将 Gmail 的副本标记为已读并保存更改

To mark the mail as read, you just have to call the mailmessage.getContent() method.要将邮件标记为已读,您只需调用 mailmessage.getContent() 方法。 Whether you use IMAP or POP, calling that method on a specific mail mark it as Read无论您使用 IMAP 还是 POP,在特定邮件上调用该方法将其标记为已读

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM