2012-09-19 71 views
15

我需要通過我的應用程序發送電子郵件使用說javamail API(任何其他郵件服務(如果可用)也將這樣做)。問題是我不想問用戶他的usernamepassword的JavaMail API中的Android使用XOAUTH

1)是否有可能使用OAuth 2.0JavaMail API /任何其他郵件API

2)如何獲得OAuth令牌?

3)有沒有網上提供的示例代碼

在此先感謝。

PS:我從來沒有與郵件服務/ SMTP請求工作。

+0

Javamail中的SASL實現具有非Android依賴關係。看到這裏我的答案:http://stackoverflow.com/a/11830319/50913 – Malachi

+0

我得到該路障已經看到你的文章,你有聯繫......終於結束了做它使用的用戶憑據良好的老辦法。 – SKen

回答

27

我研究了一段日子,我發現,在此刻爲我工作的解決方案。 我從android AccountManager獲取oauth2標記,然後使用JavaMail通過SMTP發送電子郵件。這個想法是基於這裏的Java示例http://code.google.com/p/google-mail-oauth2-tools/wiki/JavaSampleCode,並在此的Java XOAUTH這裏例如http://google-mail-xoauth-tools.googlecode.com/svn/trunk/java/com/google/code/samples/xoauth/XoauthAuthenticator.java

有Android版的JavaMail沒有工作SASL實施和使用asmack沒有工作,所以我沒有使用SASL,我發出的命令就像在上面的Xoauth例子中一樣。

我從acount經理令牌這樣

AccountManager am = AccountManager.get(this); 
Account me = ...; //You need to get a google account on the device, it changes if you have more than one 
am.getAuthToken(me, "oauth2:https://mail.google.com/", null, this, new OnTokenAcquired(), null); 

private class OnTokenAcquired implements AccountManagerCallback<Bundle>{ 
    @Override 
    public void run(AccountManagerFuture<Bundle> result){ 
     try{ 
      Bundle bundle = result.getResult(); 
      token = bundle.getString(AccountManager.KEY_AUTHTOKEN); 

     } catch (Exception e){ 
      Log.d("test", e.getMessage()); 
     } 
    } 
} 

如果一切正常,你有令牌的令牌的oauth2。我使用令牌在此代碼

import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.security.Provider; 
import java.security.Security; 
import java.util.Properties; 

import javax.activation.DataHandler; 
import javax.activation.DataSource; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.URLName; 
import javax.mail.Message; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeMessage; 

import android.util.Log; 

import com.sun.mail.smtp.SMTPTransport; 
import com.sun.mail.util.BASE64EncoderStream; 

public class GMailOauthSender { 
private Session session; 


public SMTPTransport connectToSmtp(String host, int port, String userEmail, 
     String oauthToken, boolean debug) throws Exception { 

    Properties props = new Properties(); 
    props.put("mail.smtp.starttls.enable", "true"); 
    props.put("mail.smtp.starttls.required", "true"); 
    props.put("mail.smtp.sasl.enable", "false"); 
    session = Session.getInstance(props); 
    session.setDebug(debug); 


    final URLName unusedUrlName = null; 
    SMTPTransport transport = new SMTPTransport(session, unusedUrlName); 
    // If the password is non-null, SMTP tries to do AUTH LOGIN. 
    final String emptyPassword = null; 
    transport.connect(host, port, userEmail, emptyPassword); 

      byte[] response = String.format("user=%s\1auth=Bearer %s\1\1", userEmail, 
      oauthToken).getBytes(); 
    response = BASE64EncoderStream.encode(response); 

    transport.issueCommand("AUTH XOAUTH2 " + new String(response), 
      235); 

    return transport; 
} 

public synchronized void sendMail(String subject, String body, String user, 
     String oauthToken, String recipients) { 
    try { 

     SMTPTransport smtpTransport = connectToSmtp("smtp.gmail.com", 
       587, 
       user, 
       oauthToken, 
       true); 

     MimeMessage message = new MimeMessage(session); 
     DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain")); 
       message.setSender(new InternetAddress(user)); 
       message.setSubject(subject); 
       message.setDataHandler(handler); 
     if (recipients.indexOf(',') > 0) 
      message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients)); 
     else 
      message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients)); 
     smtpTransport.sendMessage(message, message.getAllRecipients()); 


    } catch (Exception e) { 
     Log.d("test", e.getMessage()); 
    } 

} 

我不是在這一切的專家,我沒有使用任何安全提供像上面的例子,不知道怎麼會影響這一點,但它的工作我。 希望這有助於和有人能告訴我,如果有什麼問題這也太:P 這是我第一次在這裏的回答很抱歉,如果我做錯了什麼!

行動,忘了我用一些其他文件:https://developers.google.com/google-apps/gmail/xoauth2_protocolhttp://developer.android.com/training/id-auth/authenticate.html

OPS了!您還需要清單中的這些權限

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> 
+1

感謝@alex我會嘗試這一點,並儘快給您 – SKen

+0

GAE:適用於與GAE + SMTP +的OAuth + Gmail發送電子郵件 - 需要啓用計費,但這是免費做的。 – eddyparkinson

+0

當sendMessage()被調用時,這個答案給了我一個NPE,任何想法? :) – whitfin