Android中最重要的功能之一就是可以利用一個帶有action的"intent"使得當前app能夠跳轉到其他的app。例如:如果你的app擁有一個地址想要顯示在地圖上,你並不需要在你的app裏面創建一個activity用來顯示地圖。你只需要使用Intent來發出查看地址的請求。Android系統則會啓動能夠顯示地圖的程序來呈現那個地址。
正如在第0章:Building Your First App中所說的,你必須使用intent來在同一個app的兩個activity之間進行切換。在那種情況下通常是定義一個顯示(explicit)的intent,它指定了需要叫起組件。然而,當你想要叫起不同的app來執行那個動作,則必須使用隱式(implicit)的intent。
這節課會介紹如何爲特殊的動作創建一個implicit intent,並使用它來啓動另外一個app去執行intent中的action。
Build an Implicit Intent [建立一個隱式的Intent]
Implicit intents並不會聲明需要啓動的組件的類名,它使用的是聲明一個需要執行的動作。這個action指定了你想做的事情,例如查看,編輯,發送或者是獲取什麼。Intents通常會在發送action的同時附帶一些數據,例如你想要查看的地址或者是你想要發送的郵件信息。依賴於你想要創建的Intent,這些數據需要是Uri
,
或者是其他規定的數據類型。如果你的數據是一個Uri
,
會有一個簡單的 Intent()
constructor
用來定義action與data。
例如,下面是一個帶有指定電話號碼的intent。
Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
當你的app通過執行startActivity()
來啓動這個intent時,Phone
app會使用之前的電話號碼來撥出這個電話。
下面是一些其他intent的例子:
View a map:
// 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);View a web page:
Uri webpage = Uri.parse("http://www.android.com"); Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);另外一些需要"extra"數據的implicit intent。你可以使用
putExtra()
方法來添加那些數據。
默認的,系統會根據Uri數據類型來決定需要哪些合適的MIME
type。如果你沒有在intent中包含一個Uri
,
則通常需要使用 setType()
方法來指定intent附帶的數據類型。設置MIME
type 是爲了指定哪些activity可以應該接受這個intent。
例如:
Send an email with an attachment:
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[] {"[email protected]"}); // 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 UrisCreate a calendar event:
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: 這個intent for Calendar的例子只使用於>=API Level 14。
Note: 請儘可能的定義你的intent更加確切。例如,如果你想要使用ACTION_VIEW
的intent來顯示一張圖片,你還應該指定
MIME type 爲 image/*
.這樣能夠阻止其他能夠 "查看" 其他數據類型的app(like
a map app) 被這個intent叫起。
Verify There is an App to Receive the Intent [驗證是否有App去接收這個Intent]
儘管Android系統會確保每一個確定的intent會被系統內置的app(such as the Phone, Email, or Calendar app)之一接收,但是你還是應該在觸發一個intent之前做驗證是否有App接受這個intent的步驟。
Caution: 如果你觸發了一個intent,而且沒有任何一個app會去接收這個intent,那麼你的app會crash。
爲了驗證是否有合適的activity會響應這個intent,需要執行 queryIntentActivities()
來獲取到能夠接收這個intent的所有activity的list。如果返回的List非
空,那麼你纔可以安全的使用這個intent。例如:
PackageManager packageManager = getPackageManager()
;
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
如果 isIntentSafe
是 true
,
那麼至少有一個app可以響應這個intent。如果是 false
則說明沒有app可以handle這個intent。
Note: 你必須在第一次使用之前做這個檢查,若是不可行,則應該關閉這個功能。如果你知道某個確切的app能夠handle這個intent,你也應該提供給用戶去下載這個app的鏈接。(see
how to link to
your product on Google Play).
Start an Activity with the Intent [使用Intent來啓動Activity]
當你創建好了intent並且設置好了extra數據,通過執行startActivity()
來發送到系統。如果系統確定有多個activity可以handle這個intent,它會顯示出一個dialog,讓用戶選擇啓動哪個app。如果系統發現只有一個app可以handle這個intent,那麼就會直接啓動這個app。
startActivity(intent);
下面是一個完整的例子,演示瞭如何創建一個intent來查看地圖,驗證有app可以handle這個intent,然後啓動它。
// 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);
}
Show an App Chooser [顯示一個App選擇界面]
請注意,當你發送一個intent,有多個app可以handle的情況,用戶可以在彈出dialog的時候,選擇默認啓動的app(通過勾選dialog下面的選擇框,如上圖所示)。這個功能對於用戶有特殊偏好的時候非常有用(例如用戶總是喜歡啓動某個app來查看網頁,總是喜歡啓動某個camera來拍照)。
然而,如果用戶希望每次都彈出選擇界面,而且每次都不確定會選擇哪個app啓動,例如分享功能,用戶選擇分享到哪個app都是不確定的,這個時候,需要強制彈出選擇的對話框。(這種情況下用戶不能選擇默認啓動的app)。
爲了顯示chooser, 需要使用createChooser()
來創建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);
學習自:http://developer.android.com/training/basics/intents/sending.html,歡迎交流!~
轉載請註明出自:http://blog.csdn.net/kesenhoo,謝謝!