向另一個(gè)應(yīng)用發(fā)送數(shù)據(jù)
Android 最重要的功能之一是應(yīng)用能夠基于它要執(zhí)行的“操作”向另一個(gè)應(yīng)用發(fā)送數(shù)據(jù)冤灾。 例如只恨,如果您的應(yīng)用有您要在地圖上顯示的公司地址滤钱,您無(wú)需在顯示地圖的應(yīng)用中構(gòu)建 Activity幢踏。 而是可以創(chuàng)建使用 Intent 查看地址的請(qǐng)求。Android 系統(tǒng)之后啟動(dòng)可以在地圖上顯示該地址的應(yīng)用玻褪。
您必須使用 Intent 在自己應(yīng)用中的 Activity 之間進(jìn)行導(dǎo)航。 您通常使用顯式 Intent 執(zhí)行此操作公荧,該 Intent 定義您希望啟動(dòng)的組件的確切類(lèi)名稱(chēng)带射。 但是,當(dāng)您希望另一應(yīng)用執(zhí)行操作時(shí)循狰,比如“查看地圖”窟社,您必須使用隱式 Intent。
本博文向您展示如何針對(duì)特定操作創(chuàng)建隱式 Intent绪钥,以及如何使用該 Intent 啟動(dòng)在另一個(gè)應(yīng)用中執(zhí)行操作的 Activity灿里。
構(gòu)建隱式 Intent
隱式 Intent 不聲明要啟動(dòng)的組件的類(lèi)名稱(chēng),而是聲明要執(zhí)行的操作程腹。 該操作指定您要執(zhí)行的操作匣吊,比如查看、編輯寸潦、發(fā)送或 獲取 某項(xiàng)色鸳。 Intent 通常還包含與操作關(guān)聯(lián)的數(shù)據(jù),比如您要查看的地址或您要發(fā)送的電子郵件消息见转。根據(jù)要?jiǎng)?chuàng)建的 Intent命雀,數(shù)據(jù)可能是 Uri、多種其他數(shù)據(jù)類(lèi)型之一斩箫,或 Intent 可能根本就不需要數(shù)據(jù)吏砂。
如果您的數(shù)據(jù)是 Uri撵儿,您可以使用一個(gè)簡(jiǎn)單的 Intent() 構(gòu)造函數(shù)來(lái)定義操作和數(shù)據(jù)。
例如狐血,此處顯示如何使用指定電話(huà)號(hào)碼的 Uri 數(shù)據(jù)創(chuàng)建發(fā)起電話(huà)呼叫的 Intent:
Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
當(dāng)您的應(yīng)用通過(guò)調(diào)用 startActivity() 調(diào)用此 Intent 時(shí)统倒,“電話(huà)”應(yīng)用會(huì)發(fā)起向指定電話(huà)號(hào)碼的呼叫。
這里有一些其他 Intent 及其操作和 Uri 數(shù)據(jù)對(duì):
查看地圖:
// 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);
其他類(lèi)型的隱式 Intent 需要提供不同數(shù)據(jù)類(lèi)型(比如氛雪,字符串)的“額外”數(shù)據(jù)房匆。 您可以使用各種 putExtra() 方法添加一條或多條 extra 數(shù)據(jù)。
默認(rèn)情況下报亩,系統(tǒng)基于所包含的 Uri 數(shù)據(jù)確定 Intent 需要的相應(yīng) MIME 類(lèi)型浴鸿。如果您未在 Intent 中包含 Uri,您通常應(yīng)使用 setType() 指定與 Intent 關(guān)聯(lián)的數(shù)據(jù)的類(lèi)型弦追。 設(shè)置 MIME 類(lèi)型可進(jìn)一步指定哪些類(lèi)型的 Activity 應(yīng)接收 Intent岳链。
此處有更多添加額外數(shù)據(jù)以指定所需操作的 Intent:
發(fā)送帶附件的電子郵件:
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)建日歷事件:
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");
注:只有 API 級(jí)別 14 或更高級(jí)別支持此日歷事件 Intent。
注:盡可能具體地定義您的 Intent 非常重要劲件。例如掸哑,如果您想要使用 ACTION_VIEW Intent 顯示圖像,您應(yīng)指定 MIME 類(lèi)型 image/*零远。這可防止可“查看”數(shù)據(jù)的其他類(lèi)型的應(yīng)用(比如地圖應(yīng)用)被 Intent 觸發(fā)苗分。
驗(yàn)證是否存在接收 Intent 的應(yīng)用
盡管 Android 平臺(tái)保證某些 Intent 可以分解為內(nèi)置應(yīng)用之一(比如,“電話(huà)”牵辣、“電子郵件”或“日歷”應(yīng)用)摔癣,您應(yīng)在調(diào)用 Intent 之前始終包含確認(rèn)步驟。
注意:如果您調(diào)用了 Intent纬向,但設(shè)備上沒(méi)有可用于處理 Intent 的應(yīng)用择浊,您的應(yīng)用將崩潰。
要確認(rèn)是否存在可響應(yīng) Intent 的可用 Activity逾条,請(qǐng)調(diào)用 queryIntentActivities() 來(lái)獲取能夠處理您的 Intent 的 Activity 列表琢岩。如果返回的 List 不為空,您可以安全地使用該 Intent师脂。例如:
PackageManager packageManager = [getPackageManager()](https://developer.android.google.cn/reference/android/content/Context.html#getPackageManager())
;List activities = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);boolean isIntentSafe = activities.size() > 0;
如果 isIntentSafe 是 true担孔,則至少有一個(gè)應(yīng)用將響應(yīng)該 Intent。 如果它是 false危彩,則沒(méi)有任何應(yīng)用處理該 Intent攒磨。
注:在您需要在用戶(hù)嘗試使用它之前停用使用該 Intent 的功能時(shí),您應(yīng)在 Activity 初次啟動(dòng)時(shí)執(zhí)行此檢查汤徽。 如果您了解可處理 Intent 的特定應(yīng)用娩缰,您還可以為用戶(hù)提供下載該應(yīng)用的鏈接(請(qǐng)參閱如何在 Google Play 鏈接到您的產(chǎn)品)
啟動(dòng)具有 Intent 的 Activity
一旦您已創(chuàng)建您的 Intent 并設(shè)置 extra 信息,調(diào)用 startActivity() 將其發(fā)送給系統(tǒng)谒府。如果系統(tǒng)識(shí)別可處理 Intent 的多個(gè) Activity拼坎,它會(huì)為用戶(hù)顯示對(duì)話(huà)框供其選擇要使用的應(yīng)用浮毯,如圖 1 所示。如果只有一個(gè) Activity 處理 Intent泰鸡,系統(tǒng)會(huì)立即將其啟動(dòng)债蓝。
startActivity(intent);
此處顯示完整的示例:如何創(chuàng)建查看地圖的 Intent,驗(yàn)證是否存在處理 Intent 的應(yīng)用盛龄,然后啟動(dòng)它:
// Build the intentUri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);// Verify it resolvesPackageManager packageManager = [getPackageManager()](https://developer.android.google.cn/reference/android/content/Context.html#getPackageManager())
;List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);boolean isIntentSafe = activities.size() > 0;// Start an activity if it's safeif (isIntentSafe) { startActivity(mapIntent);}
顯示應(yīng)用選擇器
注意饰迹,當(dāng)您通過(guò)將您的 Intent 傳遞至 startActivity() 而啟動(dòng) Activity 時(shí),有多個(gè)應(yīng)用響應(yīng) Intent余舶,用戶(hù)可以選擇默認(rèn)使用哪個(gè)應(yīng)用(通過(guò)選中對(duì)話(huà)框底部的復(fù)選框啊鸭;見(jiàn)圖 1)。當(dāng)執(zhí)行用戶(hù)通常希望每次使用相同應(yīng)用進(jìn)行的操作時(shí)匿值,比如當(dāng)打開(kāi)網(wǎng)頁(yè)(用戶(hù)可能只使用一個(gè)網(wǎng)絡(luò)瀏覽器)或拍照(用戶(hù)可能習(xí)慣使用一個(gè)相機(jī))時(shí)赠制,這非常有用。
但是挟憔,如果要執(zhí)行的操作可由多個(gè)應(yīng)用處理并且用戶(hù)可能 習(xí)慣于每次選擇不同的應(yīng)用 — 比如“共享”操作钟些, 用戶(hù)有多個(gè)應(yīng)用分享項(xiàng)目 — 您應(yīng)明確顯示選擇器對(duì)話(huà)框, 如圖 2 所示绊谭。選擇器對(duì)話(huà)框 強(qiáng)制用戶(hù)選擇用于每次操作的 應(yīng)用(用戶(hù)不能對(duì)此操作選擇默認(rèn)的應(yīng)用)政恍。
要顯示選擇器,請(qǐng)使用 createChooser() 創(chuàng)建Intent 并將其傳遞給 startActivity()龙誊。例如:
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().getString(R.string.chooser_title);
// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);
// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
這將顯示一個(gè)對(duì)話(huà)框抚垃,其中包含響應(yīng)傳遞給 createChooser() 方法的 Intent 的應(yīng)用列表,并且將提供的文本用作對(duì)話(huà)框標(biāo)題趟大。