是否可以在GMail中使用Javamail中的IMAP查询条款?

时间:2011-01-27 18:44:42

标签: gmail imap javamail

我正在尝试通过一个名为SMSBackup的小应用程序(强烈推荐)以编程方式检索从我的Android手机备份的呼叫日志消息。

我想要做的是能够检索特定日期的通话记录。我使用JavaMail尝试了以下程序:

public List<CallLogEntry> getCallLog(String username, String password, Date date, TimeZone tz) {
    Store store = null;

    try {
        store = MailUtils.getGmailImapStore(username, password);
        Folder folder = store.getDefaultFolder();
        if (folder == null)
            throw new Exception("No default folder");
        Folder inboxfolder = folder.getFolder("Call log");
        if (inboxfolder == null)
            throw new Exception("No INBOX");
        inboxfolder.open(Folder.READ_ONLY);

        Date fromMidnight = new Date(TimeUtils.fromMidnight(date.getTime(), tz));
        Date toMidnight = new Date(TimeUtils.toMidnight(date.getTime(), 0, tz));

        SentDateTerm fromTerm = new SentDateTerm(SentDateTerm.GT, fromMidnight);
        SentDateTerm toTerm = new SentDateTerm(SentDateTerm.LT, toMidnight);

        AndTerm searchTerms = new AndTerm(fromTerm, toTerm);
        Message[] msgs = inboxfolder.search(searchTerms);

        FetchProfile fp = new FetchProfile();
        fp.add("Subject");
        fp.add("Content");
        fp.add("From");
        fp.add("SentDate");
        inboxfolder.fetch(msgs, fp);

        List<CallLogEntry> callLog = new ArrayList<CallLogEntry>();
        for (Message message : msgs) {
            CallLogEntry entry = new CallLogEntry();
            entry.subject = message.getSubject();
            entry.body = (String) message.getContent();
            callLog.add(entry);
        }

        inboxfolder.close(false);
        store.close();

        return callLog;
    } catch (NoSuchProviderException ex) {
        ex.printStackTrace();
    } catch (MessagingException ex) {
        ex.printStackTrace();
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        try {
            if (store != null)
                store.close();
        } catch (MessagingException ex) {
            ex.printStackTrace();
        }
    }
    return null;
}

我的两种实用工具方法(fromMidnight / toMidnight):

public static final long fromMidnight(long time, TimeZone tz) {
    Calendar c = Calendar.getInstance(tz);
    c.setTimeInMillis(time);
    c.set(Calendar.HOUR_OF_DAY, 0);
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.SECOND, 0);
    c.set(Calendar.MILLISECOND, 1);
    return c.getTimeInMillis();
}

public static final long toMidnight(long time, int nDays, TimeZone tz) {
    Calendar c = Calendar.getInstance(tz);
    c.setTimeInMillis(time + nDays*MILLIS_IN_DAY);
    c.set(Calendar.HOUR_OF_DAY, 23);
    c.set(Calendar.MINUTE, 59);
    c.set(Calendar.SECOND, 59);
    c.set(Calendar.MILLISECOND, 999);
    return c.getTimeInMillis();
}

然而,出于某种原因:

  1. 在最终执行时,大约需要3分钟才能完成
  2. 我正在收回整个通话记录,即我邮箱中“通话记录”文件夹的全部内容
  3. 我错过了什么?

1 个答案:

答案 0 :(得分:5)

您遗失的主要内容是the underlying IMAP SEARCH syntax supports only dates, not date-times。因此,您的查询将导致JavaMail发出命令:

A001 SEARCH SENTBEFORE 16-JAN-2011 SENTSINCE 16-JAN-2011 ALL

(在IMAPProtocol.issueSearch()中加一个断点来看这个。)

GMail似乎对此查询感到不满,这在逻辑上无法匹配任何消息。尝试使用SentDateTerm.EQ(映射到SENTON)将您的逻辑切换到单个术语,它应该有效:

    SentDateTerm term = new SentDateTerm(SentDateTerm.EQ, date.getTime());
    Message[] msgs = inboxfolder.search(term);