Android發(fā)送Intent

2018-08-02 18:35 更新

編寫:kesenhoo - 原文:http://developer.android.com/training/basics/intents/sending.html

Android中最重要的特征之一就是可以利用一個(gè)帶有actionintent使當(dāng)前app能夠跳轉(zhuǎn)到其他app。例如:如果我們的app有一個(gè)地址想要顯示在地圖上,我們并不需要在app里面創(chuàng)建一個(gè)activity用來顯示地圖,而是使用Intent來發(fā)出查看地址的請(qǐng)求。Android系統(tǒng)則會(huì)啟動(dòng)能夠顯示地圖的程序來呈現(xiàn)該地址。

正如在1.1章節(jié):建立你的第一個(gè)App(Building Your First App)中所說的,我們必須使用intent來在同一個(gè)app的兩個(gè)activity之間進(jìn)行切換。通常是定義一個(gè)顯式(explicit)的intent,它指定了需要啟動(dòng)組件的類名。然而,當(dāng)想要喚起不同的app來執(zhí)行某個(gè)動(dòng)作(比如查看地圖),則必須使用隱式(implicit)的intent。

本課會(huì)介紹如何為特殊的動(dòng)作創(chuàng)建一個(gè)implicit intent,并使用它來啟動(dòng)另一個(gè)app去執(zhí)行intent中的action。

建立隱式的Intent

Implicit intents并不聲明要啟動(dòng)組件的具體類名,而是聲明一個(gè)需要執(zhí)行的action。這個(gè)action指定了我們想做的事情,例如查看,編輯,發(fā)送或者是獲取一些東西。Intents通常會(huì)在發(fā)送action的同時(shí)附帶一些數(shù)據(jù),例如你想要查看的地址或者是你想要發(fā)送的郵件信息。數(shù)據(jù)的具體類型取決于我們想要?jiǎng)?chuàng)建的Intent,比如Uri或其他規(guī)定的數(shù)據(jù)類型,或者甚至也可能根本不需要數(shù)據(jù)。

如果數(shù)據(jù)是一個(gè)Uri,會(huì)有一個(gè)簡(jiǎn)單的Intent() constructor 用于定義action與data。

例如,下面是一個(gè)帶有指定電話號(hào)碼的intent。

Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

當(dāng)app通過執(zhí)行startActivity()啟動(dòng)這個(gè)intent時(shí),Phone app會(huì)使用之前的電話號(hào)碼來?yè)艹鲞@個(gè)電話。

下面是一些其他intent的例子:

  • 查看地圖:
// Map point based on address
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
// Or map point based on latitude/longitude
// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
  • 查看網(wǎng)頁(yè):
Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

至于另外一些需要extra數(shù)據(jù)的implicit intent,我們可以使用 putExtra() 方法來添加那些數(shù)據(jù)。 默認(rèn)的,系統(tǒng)會(huì)根據(jù)Uri數(shù)據(jù)類型來決定需要哪些合適的MIME type。如果我們沒有在intent中包含一個(gè)Uri, 則通常需要使用 setType() 方法來指定intent附帶的數(shù)據(jù)類型。設(shè)置MIME type 是為了指定應(yīng)該接受這個(gè)intent的activity。例如:

  • 發(fā)送一個(gè)帶附件的email:
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// The intent does not have a URI, so declare the "text/plain" MIME type
emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
// You can also attach multiple items by passing an ArrayList of Uris
  • 創(chuàng)建一個(gè)日歷事件:
Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
calendarIntent.putExtra(Events.TITLE, "Ninja class");
calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");

Note: 這個(gè)intent for Calendar的例子只使用于>=API Level 14。

Note: 請(qǐng)盡可能的將Intent定義的更加確切。例如,如果想要使用ACTION_VIEW 的intent來顯示一張圖片,則還應(yīng)該指定 MIME type 為image/*.這樣能夠阻止其他能夠 "查看" 其他數(shù)據(jù)類型的app(比如一個(gè)地圖app) 被這個(gè)intent叫起。

驗(yàn)證是否有App去接收這個(gè)Intent

盡管Android系統(tǒng)會(huì)確保每一個(gè)確定的intent會(huì)被系統(tǒng)內(nèi)置的app(such as the Phone, Email, or Calendar app)之一接收,但是我們還是應(yīng)該在觸發(fā)一個(gè)intent之前做驗(yàn)證是否有App接受這個(gè)intent的步驟。

Caution: 如果觸發(fā)了一個(gè)intent,而且沒有任何一個(gè)app會(huì)去接收這個(gè)intent,則app會(huì)crash。

為了驗(yàn)證是否有合適的activity會(huì)響應(yīng)這個(gè)intent,需要執(zhí)行queryIntentActivities() 來獲取到能夠接收這個(gè)intent的所有activity的list。若返回的List非空,那么我們才可以安全的使用這個(gè)intent。例如:

PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;

如果isIntentSafetrue, 那么至少有一個(gè)app可以響應(yīng)這個(gè)intent。false則說明沒有app可以handle這個(gè)intent。

Note:我們必須在第一次使用之前做這個(gè)檢查,若是不可行,則應(yīng)該關(guān)閉這個(gè)功能。如果知道某個(gè)確切的app能夠handle這個(gè)intent,我們也可以向用戶提供下載該app的鏈接。(see how to link to your product on Google Play).

使用Intent啟動(dòng)Activity

當(dāng)創(chuàng)建好了intent并且設(shè)置好了extra數(shù)據(jù)后,通過執(zhí)行startActivity() 將intent發(fā)送到系統(tǒng)。若系統(tǒng)確定了多個(gè)activity可以handle這個(gè)intent,它會(huì)顯示出一個(gè)dialog,讓用戶選擇啟動(dòng)哪個(gè)app。如果系統(tǒng)發(fā)現(xiàn)只有一個(gè)app可以handle這個(gè)intent,則系統(tǒng)將直接啟動(dòng)該app。

startActivity(intent);

intents-choice.png

下面是一個(gè)演示了如何創(chuàng)建一個(gè)intent來查看地圖的完整例子,首先驗(yàn)證有app可以handle這個(gè)intent,然后啟動(dòng)它。

// Build the intent
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

// Verify it resolves
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
boolean isIntentSafe = activities.size() > 0;

// Start an activity if it's safe
if (isIntentSafe) {
    startActivity(mapIntent);
}

顯示分享App的選擇界面

請(qǐng)注意,當(dāng)以startActivity()的形式傳遞一個(gè)intent,并且有多個(gè)app可以handle時(shí),用戶可以在彈出dialog的時(shí)候選擇默認(rèn)啟動(dòng)的app(通過勾選dialog下面的選擇框,如上圖所示)。該功能對(duì)于用戶有特殊偏好的時(shí)候非常有用(例如用戶總是喜歡啟動(dòng)某個(gè)app來查看網(wǎng)頁(yè),總是喜歡啟動(dòng)某個(gè)camera來拍照)。

然而,如果用戶希望每次都彈出選擇界面,而且每次都不確定會(huì)選擇哪個(gè)app啟動(dòng),例如分享功能,用戶選擇分享到哪個(gè)app都是不確定的,這個(gè)時(shí)候,需要強(qiáng)制彈出選擇的對(duì)話框。(這種情況下用戶不能選擇默認(rèn)啟動(dòng)的app)。

intent-chooser.png

為了顯示chooser, 需要使用createChooser()來創(chuàng)建Intent

Intent intent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text. This says something like "Share this photo with"
String title = getResources().getText(R.string.chooser_title);
// Create and start the chooser
Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);

這樣就列出了可以響應(yīng)createChooser()中Intent的app,并且指定了標(biāo)題。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)