最近在考慮為已經有的一個應用程式增加一個使用者反饋的功能,使用者可以通過反饋功能將使用者的意見和建議、程式出現的問題以一種更符合使用者習慣的方式反饋回來。網上也有一些實現好的反饋程式的服務,包括bug的提交、程式的建議、程式使用中的問題,但是這樣的服務基本上不是完全開源和免費的,並且我對程式反饋的定位還是使用者可以把他的想法通過寫文字的方法發送回來就可以(不需要記錄崩潰時的系統狀況),所以還是決定在完全瞭解實現機制的基礎上來實現反饋功能。
採用發送郵件的方式不需要自己構建伺服器,同時也符合我對反饋的管理習慣,因此決定採用在通過在應用程式內發送郵件的方式來實現反饋功能。
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的應用程式內部發送郵件,其中有兩點可能的修改需要注意:
1.該回答使用的是Gmail賬戶作為發送郵件的賬戶,如果採用其它的賬戶需要對發送郵件伺服器和連接埠號碼進行單獨的設定。
對於126或者163郵箱而言,只需要將properties設定的部分修改為:
Properties props = "mail.transport.protocol", "smtp""mail.host""mail.smtp.auth", "true""mail.smtp.port", "25");
參考:http://www.cnblogs.com/peakzheng/archive/2012/02/04/2338671.html
2.需要將UI線程(主線程)中的發送郵件操作轉移到單獨的線程進行處理
Google在honeycomb的發布版之後就對主線程中的操作進行了更加嚴格的要求。為了保證使用者體驗,在主線程中不能網路資料轉送操作,因為在主線程中進行網路資料轉送可能會帶來主介面的長時間不響應使用者的點擊操作,從而帶來不好的使用者體驗(參考)。對於輕量級的網路操作,Android系統中,通常通過AsyncTask類來實現。
按說Android在高版本的系統中對應用程式在主介面訪問網路的操作都會提示android.os.NetworkOnMainThreadException錯誤,但是在使用Java Mail API進行應用程式內的郵件發送時,我遇到的情況是在2.3版本的模擬器上運行程式,接收方可以收到發送的郵件。同樣的代碼在在4.2.2版本的手機上卻無法成功發送郵件,在Eclipse下的logcat介面中沒有任何錯誤提示。stackoverflow上的回答http://stackoverflow.com/a/2033124/1767800後也有人給出了類似的評論。
但是,在將sender.sendMail()函數轉移到asyncTask類中之後,在4.2.2的手機中也可以成功發送郵件了。具體實現是:
1)建立一個繼承自AsyncTask的類
SendMailTask AsyncTask<URL, Integer, Long> .sender= totalSize = 0.sender.sendMail("This is Subject""This is Body""senderAddress""receiverAddress"
2)通過如下語句發送郵件
SendMailTask(sender).execute();
通過gmail接收的郵件如所示