【Android Training - 05】與其他Apps進行交互 [ Lesson 1 - 啓動到另外一個app ]

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 Uris
Create 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,謝謝!








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章