注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/basics/intents/sending.html
Android的一個最重的特性就是一個應用可以將用戶帶領到另一個應用的能力,這一切基于的是一個應用期望表現的“ 行為(action) ”。例如,如果你的應用有一個你期望顯示在地圖上的地址,你不需要在你的應用中構建一個顯示地圖的Activity,你只需要通過使用 Intent 來創建一個查勘地址的需求。之后Android系統會自動啟動一個可以在地圖上顯示地址的應用。
如同在第一節課 Building Your First App (博客鏈接: http://www.cnblogs.com/jdneo/p/3438954.html )所說的,你必須使用intents在你的應用的Activity之間轉換。一般你通過顯示intent來做這件事情,這將指明你希望啟動的組件的類名。然而,當你希望通過另一個應用執行一個行為,比如“查看地圖”,你就必須使用一個隱式的intent。
這節課將向你展示如何為一個特定的行為創建一個隱式intent,以及如何使用它啟動一個其它應用的Activity來執行這個行為。
?
一). 構建一個隱式的Intent
隱式Intent不聲明要啟動組件的類名,而是聲明一個要執行的行為。該行為指定了你希望做的事情,比如查看,編輯,發送或者獲取某些東西。Intents也經常包含與該行為有關的數據,比如你希望查看的地址,或者你希望發送的郵件內容。根據你希望創建intent,數據可以是一個 Uri ,也可以其他的數據類型,當然intent也可以不需要任何數據。
如果你的數據是一個
Uri
,有一個你可以使用的
Intent()
構造函數來定義行為和數據。
下述例子是如何使用 Uri 數據指定電話號碼來創建一個intent,從而初始化一個打電話行為
Uri number = Uri.parse("tel:5551234" ); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
當你的應用通過調用 startActivity() 行使了這個intent,撥號應用會根據給定的電話號碼初始化一個呼叫。
下面是一些其他intent的例子,以及它們所對應的行為和 Uri 數據對:
- 瀏覽地圖:
// 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);
- 瀏覽一個網頁:
Uri webpage = Uri.parse("http://www.android.com" ); Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
其它類型的隱式Intents需要“ extra ”數據來提供不同的數據類型,比如字符串。你通過使用不同的 putExtra() 方法來添加一個或多個“ extra ”數據。
默認的,系統會基于intent所包含的
Uri
數據,來指定它所需要的恰當MIME類型。如果你在intent中不包含一個
Uri
,你應該使用
setType()
來指定與該intent所關聯的數據類型。設置MIME類型會進一步特定什么類型的Activity將會接受這個intent。
下面是一些intent例子,它們通過添加額外的數據來定義希望的行為:
- 發送一個有附件的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
- 創建一個日歷事件:
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僅在API Level 14或更高的平臺上被支持。
Note:
將你的 Intent 定義的越明確越好!例如,如果你希望使用 ACTION_VIEW 的intent來展示一個圖片,你應該特定MIME類型為“ image/* ”。這將防止可以查看其他數據類型的應用(比如一個地圖閱覽器)被這個intent激活。
?
二). 確認有一個應用能接受此Intent
雖然Android平臺保證某個Intent將會由一個內置的應用所處理(比如:電話,電子郵件或者日歷等應用),但是你在激活一個intent前包含一個確認的步驟。
Caution:
如果你激活了一個在設備中沒有任何一個應用能夠處理該事務的intent,那么你的應用將會崩潰。
為了確認有一個應用能夠正確響應這個intent,調用
queryIntentActivities()
來得到一個能夠處理你的
Intent
的activity清單。如果返回的
List
不為空,你可以安全地使用這個intent。例如:
PackageManager packageManager = getPackageManager(); List <ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0 ); boolean isIntentSafe = activities.size() > 0;
如果 isIntentSafe為真,那就說明至少有一個應用能夠正確響應這個intent。如果為假,那就說明沒有任何應用能夠處理這個intent。
Note:
你應該在你的應用第一次啟動時執行這個檢查,這樣你就可以禁用使用該intent的功能特性,防止用戶嘗試去使用它。如果你知道某個特定的應用能夠處理這個intent,你也可以給用戶提供鏈接來讓用戶下載這個應用(可也查閱: link to your product on Google Play )
?
三). 通過Intent啟動一個Activity
一旦你創建了你的 Intent 并且設置了額外的信息,你可以調用 startActivity() 將它發送給系統。如果系統發現有不止一個acitivity可以處理這個intent,它會向用戶顯示一個對話框,讓用戶選擇要啟動哪一個應用,如圖1所示。如果只有一個應用能夠處理這個intent,那么系統會立即直接啟動它。
startActivity(intent);
圖1. 當有多個應用能夠處理該intent時,系統所顯示的選擇對話框
下面是一個完整的例子,它顯示了如何創建一個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); }
?
四). 顯示一個應用選擇器(App Chooser)
注意到當你將你的 Intent 傳遞給 startActivity() 來啟動一個Activity時,如果有多個應用可以正確響應這個intent,用戶可以選擇默認使用哪個程序(在對話框底部勾選復選框,見圖1)。當用戶每次都希望使用相同的應用來處理該事務時(比如打開一個網頁時,用戶可能會喜歡只用一個瀏覽器,或者拍攝一個照片,用戶可能只喜歡用一款相機應用),此時這么做是不錯的。
然而,如果這個intent行為可以被多個應用處理,同時,用戶每次可能期望使用不同的應用——比如“ 分享 ”這一行為,用戶可能有多個應用能夠分享某一個項目。此時你應該顯式地展現一個選擇應用的對話框,如圖2所示。這個對話框強制用戶在每次執行該操作時,選擇一個自己期望的應用來處理該事務(用戶不能選擇一個默認的應用來處理)。
圖2. 一個應用選擇器對話框
為了顯示一個選擇器,使用 createChooser() 來創建一個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 and start the chooser Intent chooser = Intent.createChooser(intent, title); startActivity(chooser);
這樣將會顯示一個對話框,里面顯示了能夠處理傳遞給 createChooser() 的intent的應用清單,對話框的標題是代碼中指定的文本。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
