Android官方开发文档Training系列课程中文版:与其它APP交互之将用户带到其它的APP
原文地址:http://android.xsoftlab.net/training/basics/intents/index.html
導言
一個Android APP應用通常會有若干個Activity。每一個Activity所展示的用戶界面用于允許用戶執行特定的任務(比如瀏覽地圖或者是拍照)。為了把用戶從一個activity帶到另一個activity,APP必須使用一個Intent對象定義APP的意圖是想要做什么事情,系統會使用這個Intent對象來識別并啟動合適的APP組件。使用意圖事件允許你的APP啟動另一個程序中的Activity。
一個Intent可以明確的啟動一個具體的組件(一個具體的Activity實例)或者模糊的啟動任何組件,不過這個組件需要有能力處理預期的行為(比如拍照)>
這節課展示了如何使用Intent與其它APP執行一些基礎交互,比如啟動另一個APP,從另一個APP接收結果,或者使你的APP可以響應其它APP的請求。
將用戶帶到另一個Activity
Android主要特征之一就是一個APP有能力帶領用戶到另一個APP。舉個例子,如果你的APP有一條商業地址,并且你想在地圖上將這個地址展示出來,你不需要不得不在APP內創建一個可以展示地圖的Activity。相反,你可以使用Intent創建一個請求,來請求展示這個地址。Android系統然后會啟動一個有能力在地圖上展示地址的APP。
就像第一節課所描述的,Building Your First App,你必須使用Intent來引導APP中的兩個activity。你通常對這樣的情況使用顯式意圖,意圖中明確定義了你想啟動的組件的類名。然而,當你想要通過其它不知類名的APP執行這個行為的時候,比如查看地圖,這時,你就必須使用隱式意圖了。
這節課展示了如何對特定的行為創建隱式意圖,以及如何使用它來啟動另一個APP中可以執行這個行為的Activity。
構建一個隱式意圖
隱式意圖不會聲明將要啟動的組件的類名,不過相反的,它會聲明要執行的行為。這個行為指明了你將要做的事情,比如查看、編輯、發送或者獲取一些東西。Intent經常還會包含一些與行為有關的數據,比如你想瀏覽的地址,或者你想發送的email消息。依賴于你想創建的intent,這里的數據可能是一個Uri,一種其它的數據類型,或者intent一點數據都不需要。
如果你的數據是一個Uri,這里有一個簡單的Intent類的構造方法,你可以使用這個構造行為和數據。
舉個例子,這里展示了如何使用Uri創建一個Intent來撥打電話,并且在Uri中指明了電話號碼:
Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);當你的APP通過startActivity()調用了這個intent,電話APP會撥打剛才給定的電話號碼。
這里有一些其他意圖以及它們的行為和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);瀏覽一個Web頁面:
Uri webpage = Uri.parse("http://www.android.com"); Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);其它的隱式意圖要求附加數據,附加數據提供了不同的數據類型,比如一個字符串,你可以各種的putExtra()方法添加一個或者多個額外的數據。
默認情況下,系統確定要求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:這里的日歷事件僅僅支持API 14及以上的版本
Note:盡可能的明確Intent是非常重要的。舉個例子,如果你希望使用ACTION_VIEW意圖來展示一張圖片,你應該指定MIME類型為’image/*’。這可以預防由intent引起的APP查看其它類型的數據(比如地圖APP)。
確認有APP可以接收Intent
盡管Android平臺保證intent可以被內置的應用(比如電話、郵件或者日歷)解析,但是你還是應該在啟動一個intent之前執行驗證這一步。
警告:如果你啟動了一個intent,但是沒有APP可以處理該intent,你的APP就會崩潰。
為了驗證系統中有Activity可以響應Intent的請求,需要調用queryIntentActivities()方法來獲取有能力處理Intent的activity列表。如果返回的列表不是空的,那么你就可以安全的使用intent了:
PackageManager packageManager = getPackageManager(); List activities = packageManager.queryIntentActivities(intent,PackageManager.MATCH_DEFAULT_ONLY); boolean isIntentSafe = activities.size() > 0;如果isIntentSafe的值為true,那么至少有一個APP可以響應intent。如果為false,那么沒有任何APP可以處理intent。
Note:當在activity第一次啟動的情況下,你應該執行這項檢查。如果你知道指定的APP可以處理這個Intent,你也可以提供一個連接以供用戶去下載這個APP(有關請看link to your product on Google Play).
使用Intent啟動一個Activity
上圖中:當多個APP可以處理intent的時候,選擇對話框會顯示出來。
曾經你創建了Intent,并且設置了附加信息,調用startActivity()將intent發送給系統。如果系統識別了多個activity可以處理這個intent,它會顯示一個對話框來讓用戶選擇要使用哪個APP,就像上圖所示。如果只有一個activity可以處理,那么系統會立即啟動它。
startActivity(intent);這里有個完整的例子來展示如何創建一個intent來瀏覽地圖,驗證存在可以處理intent的APP,然后啟動它:
// 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選擇器
上圖中:一個選擇器對話框。
注意當你在啟動Activity的時候有多個APP可以響應Intent,那么用戶可以選擇默認情況下要啟動哪個APP。這非常好,在每一次要執行相同動作的時候,比如打開一個Web頁面(用戶可能只喜歡一個web瀏覽器)或者拍照。
然而,在這種情況下,可能用戶需要每次都需要選擇不同的APP,比如分享這個行為,這種情況下用戶可能要分享到多個APP上,你應該明確顯示一個選擇器對話框,這個選擇器對話框會每次出現在用戶選擇的時候(這種情況下沒有默認選擇選項)。
如果要顯示選擇器對話框,需要使用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 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); }這樣就會顯示一個選擇器對話框了,這個對話框會像上圖顯示的那樣,將符合條件的APP顯示出來,并且支持自定義的標題文本。
總結
以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:与其它APP交互之将用户带到其它的APP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记:《突破现实的困境:趋势、禀赋与企业
- 下一篇: 数码摄影(扫街)