最近在考慮爲已經有的一個應用程序增長一個用戶反饋的功能,用戶能夠經過反饋功能將用戶的意見和建議、程序出現的問題以一種更符合用戶習慣的方式反饋回來。網上也有一些實現好的反饋程序的服務,包括bug的提交、程序的建議、程序使用中的問題,可是這樣的服務基本上不是徹底開源和免費的,而且我對程序反饋的定位仍是用戶能夠把他的想法經過寫文字的方法發送回來就能夠(不須要記錄崩潰時的系統情況),因此仍是決定在徹底瞭解實現機制的基礎上來實現反饋功能。html
採用發送郵件的方式不須要本身構建服務器,同時也符合我對反饋的管理習慣,所以決定採用在經過在應用程序內發送郵件的方式來實現反饋功能。java
stackoverflow上的回答http://stackoverflow.com/a/2033124/1767800基本給出了在Android中實如今應用程序內部發送郵件的方法,在閱讀該代碼的時候我一直在找smtp是如何認證的。後來發現該實現方法中GmailSender直接繼承了javax.mail.Authenticator類,實現了getPasswordAuthentication方法,而且經過Session.getDefaultInstance(props, this)(getDefaultInstance(Properties props, Authenticator authenticator)
)語句在創建session的同時將authenticator屬性寫入。android
爲了實如今Android的應用程序內部發送郵件,其中有兩點可能的修改須要注意:api
1.該回答使用的是Gmail帳戶做爲發送郵件的帳戶,若是採用其它的帳戶須要對發送郵件服務器和端口號進行單獨的設置。服務器
對於126或者163郵箱而言,只須要將properties設置的部分修改成:網絡
Properties props = new Properties(); props.setProperty("mail.transport.protocol", "smtp"); props.setProperty("mail.host", mailhost); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", "25");
參考:http://www.cnblogs.com/peakzheng/archive/2012/02/04/2338671.htmlsession
2.須要將UI線程(主線程)中的發送郵件操做轉移到單獨的線程進行處理oracle
Google在honeycomb的發佈版以後就對主線程中的操做進行了更加嚴格的要求。爲了保證用戶體驗,在主線程中不能網絡數據傳輸操做,由於在主線程中進行網絡數據傳輸可能會帶來主界面的長時間不響應用戶的點擊操做,從而帶來很差的用戶體驗(參考)。對於輕量級的網絡操做,Android系統中,一般經過AsyncTask類來實現。app
按說Android在高版本的系統中對應用程序在主界面訪問網絡的操做都會提示android.os.NetworkOnMainThreadException錯誤,可是在使用Java Mail API進行應用程序內的郵件發送時,我遇到的狀況是在2.3版本的模擬器上運行程序,接收方能夠收到發送的郵件。一樣的代碼在在4.2.2版本的手機上卻沒法成功發送郵件,在Eclipse下的logcat界面中沒有任何錯誤提示。stackoverflow上的回答http://stackoverflow.com/a/2033124/1767800後也有人給出了相似的評論。async
可是,在將sender.sendMail()函數轉移到asyncTask類中以後,在4.2.2的手機中也能夠成功發送郵件了。具體實現是:
1)新建一個繼承自AsyncTask的類
class SendMailTask extends AsyncTask<URL, Integer, Long> { MailSender sender; public SendMailTask(MailSender sender) { // TODO Auto-generated constructor stub this.sender=sender; } protected Long doInBackground(URL... urls) { long totalSize = 0; try { this.sender.sendMail("This is Subject", "This is Body", "senderAddress", "receiverAddress"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return totalSize; } protected void onProgressUpdate(Integer... progress) { } protected void onPostExecute(Long result) { } }
2)經過以下語句發送郵件
new SendMailTask(sender).execute();
經過gmail接收的郵件以下圖所示