2011-01-27 2 views
2

SMSBackup이라고하는 작은 응용 프로그램으로 안드로이드 전화에서 백업되는 통화 로그 메시지를 프로그래밍 방식으로 검색하려고합니다 (권장).Gmail과 함께 Javamail에서 IMAP Query Terms를 사용할 수 있습니까?

내가 원하는 일은 특정 날짜의 통화 기록을 검색 할 수 있습니다. 나는 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. 전체 통화 기록, 즉 내 편지함의 "통화 기록"폴더의 전체 내용을 다시 가져옵니다.

무엇이 누락 되었습니까?

답변

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은 논리적으로 모든 메시지를 일치시킬 수없는이 쿼리에 놀라게 나타납니다. (SENTON에 매핑하는) SentDateTerm.EQ를 사용하여 하나의 용어로 논리를 전환 시도하고 작동합니다 :

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

완벽하게 일했다! 감사 – user592699