轉載:http://flysnow.iteye.com/blog/1128354
Android中我為什麼發不了郵件???我手機裡明明有郵件客戶端的,可我為什麼不能呼叫它傳送郵件???相信這是很多人會問的問題,手機裡有Email客戶端,可是偏偏在自己的應用裡呼叫不了,抑或是不知道怎麼呼叫,還有的是一直認為自己寫對了,可是偏偏不能呼叫,無奈之下只能卻網上找段程式碼貼上上,ok,可以了。。可是你知道別人的程式碼為什麼可以?你知道呼叫Email是怎麼工作的嗎?如果你又像給多人發郵件,還想傳送附件,怎麼做?又迷糊了吧?所以需要搞懂原理才能一通百通,舉一反三,而這就是這篇博文要寫的,也是你可以在這篇博文中學到的。
我們新建一個工程SendEmail,基於Android1.6實現。然後定義佈局檔案和程式碼如下:
Xml程式碼:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <Button
- android:id="@+id/send_btn"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Send Action"
- />
- </LinearLayout>
Java程式碼:
- /** 傳送郵件測試介面
- * */
- public class SendEmailActivity extends Activity implements View.OnClickListener{
- private Button mSendBtn;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mSendBtn=(Button)findViewById(R.id.send_btn);
- mSendBtn.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch(v.getId()){
- case R.id.send_btn:
- startSendEmailIntent();
- break;
- }
- }
- private void startSendEmailIntent(){
- Intent data=new Intent(Intent.ACTION_SENDTO);
- data.setData(Uri.parse("mailto:qq10000@qq.com"));
- data.putExtra(Intent.EXTRA_SUBJECT, "這是標題");
- data.putExtra(Intent.EXTRA_TEXT, "這是內容");
- startActivity(data);
- }
- }
這是我們執行應用,點選按鈕就會看到如下效果:
分析傳送程式碼
主要的傳送程式碼如下:
- Intent data=new Intent(Intent.ACTION_SENDTO);
- data.setData(Uri.parse("mailto:qq10000@qq.com"));
- data.putExtra(Intent.EXTRA_SUBJECT, "這是標題");
- data.putExtra(Intent.EXTRA_TEXT, "這是內容");
- startActivity(data);
- 首先構造一個Action為SENDTO的Action
- 其次建立一個Uri,他是一個mailto的郵件連結,也就是接收地址.
- 再通過Intent.EXTRA_SUBJECT和Intent.EXTRA_TEXT傳遞標題和文字的資料,記住,一定要使用這些常量,這是標準,否則Email客戶端不認識,那樣你傳遞的標題和文字就不起作用了。
- 然後就是startActivity進行開啟,系統會根據Intent自動匹配找到能處理這個intent的應用,如圖列表,有很多個,我們這裡選擇網易掌上郵,就開啟了一個郵件傳送介面,如我們所願,郵件地址、標題和內容都在了,很成功.
- intent中的資料傳遞是以Extra的方式進行put後傳遞的,然後在使用的時候getter取出使用。
傳送給多人以及抄送和密送
傳送給多人以及抄送和密送都很簡單,查詢Intent類中的Extra常量,傳送有這麼三個常量:Intent.EXTRA_EMAIL,Intent.EXTRA_CC,Intent.EXTRA_BCC。這三個分別用於傳遞“接受人地址列表”、“抄送人地址列表”和“密送人地址列表”,傳遞的都是String[]型別的Email地址,如果陣列中有多個地址,就可以傳送給多人。傳送的函式修改如下,我們看下效果:
- private void startSendEmailIntent(){
- Intent data=new Intent(Intent.ACTION_SENDTO);
- data.setData(Uri.parse("mailto:qq10000@qq.com"));
- data.putExtra(Intent.EXTRA_EMAIL, new String[]{"ls8707@163.com","ls8708@163.com"});
- data.putExtra(Intent.EXTRA_CC, new String[]{"ls8709@163.com"});
- data.putExtra(Intent.EXTRA_BCC, new String[]{"ls810@163.com"});
- data.putExtra(Intent.EXTRA_SUBJECT, "這是標題");
- data.putExtra(Intent.EXTRA_TEXT, "這是內容");
- startActivity(data);
- }
傳送附件
Email'客戶端的傳送Activity提供了兩個Intent Filter,一個用於傳送普通郵件,一個使用者傳送帶有附件的郵件。區分很很容易的,傳送普通郵件的那個Intent Filter配置的Action SENDTO,而帶有附件的郵件則是SEND,所以是2個不一樣,但是哪些比如附加“標題”,“內容”,“抄送”,“傳送多人”等等還是通用的。佈局檔案新增一個按鈕,用於傳送帶有附件的郵件,Activity程式碼也做修改。
- <Button
- android:id="@+id/send_to_btn"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="SendTo Action"/>
- /* * 傳送郵件測試介面
- * @author 飛雪無情 個人部落格:http://flysnow.iteye.com/
- * @since 2011-7-19
- */
- public class SendEmailActivity extends Activity implements View.OnClickListener{
- private Button mSendBtn;
- private Button mSendToBtn;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mSendBtn=(Button)findViewById(R.id.send_btn);
- mSendToBtn=(Button)findViewById(R.id.send_to_btn);
- mSendBtn.setOnClickListener(this);
- mSendToBtn.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch(v.getId()){
- case R.id.send_btn:
- startSendEmailIntent();
- break;
- case R.id.send_to_btn:
- startSendToEmailIntent();
- break;
- }
- }
- private void startSendEmailIntent(){
- Intent data=new Intent(Intent.ACTION_SENDTO);
- data.setData(Uri.parse("mailto:qq10000@qq.com"));
- data.putExtra(Intent.EXTRA_EMAIL, new String[]{"ls8707@163.com","ls8708@163.com"});
- data.putExtra(Intent.EXTRA_CC, new String[]{"ls8709@163.com"});
- data.putExtra(Intent.EXTRA_BCC, new String[]{"ls810@163.com"});
- data.putExtra(Intent.EXTRA_SUBJECT, "這是標題");
- data.putExtra(Intent.EXTRA_TEXT, "這是內容");
- startActivity(data);
- }
- private void startSendToEmailIntent(){
- Intent data=new Intent(Intent.ACTION_SEND);
- data.putExtra(Intent.EXTRA_EMAIL, new String[]{"ls8707@163.com"});
- data.putExtra(Intent.EXTRA_SUBJECT, "這是標題");
- data.putExtra(Intent.EXTRA_TEXT, "這是內容");
- data.putExtra(Intent.EXTRA_STREAM, Uri.parse(""));
- data.setType("text/plain");
- startActivity(data);
- }
- }
執行應用,我們看到效果圖裡最小面的附件標識,說明已經可以傳送附件了.
傳送附件最重要的就是Action必須為SEND,type一定要設定setType(""),還要為Intent.EXTRA_STREAM賦值,型別為Uri,一個附件的Uri。這樣才能傳送附件。
客戶端Email應用的傳送Activity配置
這是Android1.6自帶Email客戶端的配置,如下:
- <activity
- android:name=".activity.MessageCompose"
- android:label="@string/app_name"
- android:enabled="false"
- >
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <action android:name="android.intent.action.SENDTO" />
- <data android:scheme="mailto" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- </intent-filter>
- <intent-filter android:label="@string/app_name">
- <action android:name="android.intent.action.SEND" />
- <data android:mimeType="text/plain" />
- <data android:mimeType="image/*" />
- <data android:mimeType="video/*" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
從以上程式碼總結:
- 一個Activity定義了2個Intent Filter用於傳送不同型別郵件。
- SENDTO傳送普通郵件,SEND可以傳送普通和帶有附件的,不過最好主要用於傳送附件。
- 使用SENDTO時,必須為Intent設定Data,也就是Uri,內容為"mailto:emailaddr",否則不能匹配,因為有schema必須為mailto的限制
- 使用SEND時必須要設定type,也就是使用setType()方法,type只能為以前xml定義的4個。不過我測試了text/*也可以,其他的沒測試.
- 傳送附件只能使用SEND這個Action.
- void initFromIntent(Intent intent) {
- //提取接受人地址列表
- String[] extraStrings = intent.getStringArrayExtra(Intent.EXTRA_EMAIL);
- if (extraStrings != null) {
- addAddresses(mToView, extraStrings);
- }
- //提取抄送人地址列表
- extraStrings = intent.getStringArrayExtra(Intent.EXTRA_CC);
- if (extraStrings != null) {
- addAddresses(mCcView, extraStrings);
- }
- //提取密送人地址列表
- extraStrings = intent.getStringArrayExtra(Intent.EXTRA_BCC);
- if (extraStrings != null) {
- addAddresses(mBccView, extraStrings);
- }
- //提取標題
- String extraString = intent.getStringExtra(Intent.EXTRA_SUBJECT);
- if (extraString != null) {
- mSubjectView.setText(extraString);
- }
- //提取Uri中的接受人地址
- final Uri dataUri = intent.getData();
- if (dataUri != null) {
- if ("mailto".equals(dataUri.getScheme())) {
- initializeFromMailTo(dataUri.toString());
- } else {
- String toText = dataUri.getSchemeSpecificPart();
- if (toText != null) {
- addAddresses(mToView, toText.split(","));
- }
- }
- }
- //提取郵件內容
- CharSequence text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT);
- if (text != null) {
- mMessageContentView.setText(text);
- }
- //提取附件,可以看出Action必須是SEND.EXTRA_STREAM中有資料
- //type不能為null,這樣才能提取倒附件.
- if (Intent.ACTION_SEND.equals(intent.getAction()) && intent.hasExtra(Intent.EXTRA_STREAM)) {
- String type = intent.getType();
- Uri stream = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
- if (stream != null && type != null) {
- if (MimeUtility.mimeTypeMatches(type, Email.ACCEPTABLE_ATTACHMENT_SEND_TYPES)) {
- addAttachment(stream);
- }
- }
- }
- // Finally - expose fields that were filled in but are normally hidden, and set focus
- if (mCcView.length() > 0) {
- mCcView.setVisibility(View.VISIBLE);
- }
- if (mBccView.length() > 0) {
- mBccView.setVisibility(View.VISIBLE);
- }
- setNewMessageFocus();
- mDraftNeedsSaving = false;
- }