傳送門 ☞ 輪子的專欄 ☞ 轉載請註明 ☞ http://blog.csdn.net/leverage_1229
html
一個Android應用程序一般有幾個activities。每一個act顯示一個用戶接口容許用戶執行一個指定的任務。用戶從一個act到另外一個act,你的App必須使用一個Intent對象來定義你App想作些什麼事。當你經過一個Intent調用startActivity()方法時,系統會使用Intent來鑑定和啓動合適的App組件。一個Intent能夠明確的啓動一個特定的組件(如一個特定的act實例)或隱式啓動任何能夠處理預約動做的組件,本章咱們將講述怎麼使用Intent來執行與其餘Apps的一些交互,例如啓動另外一個App,從那個App接收結果。並使你的應用程序可以響應來自其餘App的intents。java
Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);當你的app經過startActivity()調用intent時,電話app根據給定的電話號碼發起呼叫。
// 基於地址的地圖點 Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); // 或基於經緯度的地圖點 // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z參數表示縮放級別 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);其餘種類的隱式intents須要」extra」數據來提供不一樣的數據類型,如一個字符串。你能使用putExtra()方法來添加一個或更多extra 數據。默認的,系統經過基於Uri的intent來肯定適當的MIME(Multipurpose Internet Mail Extensions)類型。若是你在intent中不包含一個Uri,你應該使用setType()來指定intent相關聯的數據類型。設置MIME類型來進一步指定activities將要接收的intent類型。
Intent emailIntent = new Intent(Intent.ACTION_SEND); //沒有Uri的intent,因此須要聲明」text/plain」的MIME類型 emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // 收件人 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"));建立一個日曆事件:
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");注意: 對於日曆事件的intent只在API Level或更高版本下才支持。
PackageManager packageManager = getPackageManager(); List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); boolean isIntentSafe = activities.size() > 0;如isIntentSafe爲true,那麼表示至少有一個app能響應咱們的intent。若是false,表示沒有一個app能處理這個intent。
// 構建intent Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); // 驗證上面的mapIntent PackageManager packageManager = getPackageManager(); List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0); boolean isIntentSafe = activities.size() > 0; // 若是它是安全的就啓動這個activity if (isIntentSafe) { startActivity(mapIntent); }
Intent intent = new Intent(Intent.ACTION_SEND); ... // 用於標題的文本資源例如"Share this photo with" String title = getResources().getText(R.string.chooser_title); // 建立並啓動chooser Intent chooser = Intent.createChooser(intent, title); startActivity(chooser);
static final int PICK_CONTACT_REQUEST = 1; // request code ... private void pickContact() { Intent pickContactIntent = new Intent(Intent.ACTION_PICK, new Uri("content://contacts")); pickContactIntent.setType(Phone.CONTENT_TYPE); startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // 檢查響應的請求 if (requestCode == PICK_CONTACT_REQUEST) { // 確保請求是成功的 if (resultCode == RESULT_OK) { // Do something... } } }爲了成功地處理結果,你必須明白,intent結果的格式將是什麼。例如,People app(早些版本叫Contacts app)始終用content URI返回結果並識別被選擇的聯繫人,Camera app在返回一個Bitmap。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //檢查響應的請求 if (requestCode == PICK_CONTACT_REQUEST) { //確保請求是成功的 if (resultCode == RESULT_OK) { // 得到指向選定聯繫人的URI Uri contactUri = data.getData(); //咱們只須要號碼(NUMBER)列 String[] projection = {Phone.NUMBER}; // 在聯繫人中執行查詢,得到NUMBER column // 咱們不須要挑選或排序 // 提示: query()方法應該在單獨的線程執行,避免阻塞UI線程 // 考慮使用CursorLoader 執行查詢 Cursor cursor = getContentResolver() .query(contactUri, projection, null, null, null); cursor.moveToFirst(); // 從NUMBER column中檢索電話號碼 int column = cursor.getColumnIndex(Phone.NUMBER); String number = cursor.getString(column); // 使用電話號碼作些事情 } } }注意:Android 2.3 (API level 9)之前,在Contacts Provider執行一個查詢須要申明READ_CONTACTS權限,雖然在2.3開始有一個臨時的權限可讓你去讀取Contacts Provider,但依舊不能查詢。因此無論什麼版本咱們都申明READ_CONTACTS權限便可。
<activity android:name="ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter> </activity>每個傳入的intent只有一個動做和一種數據類型,但聲明多個<data>,<action>,<category>也是OK的,若是動做和數據類型相互排斥的話,你就應該分開它們。加入你的activity處理文本和圖像,而且使用ACTION_SEND和ACTION_SENDTO intents。這樣就是錯誤的,在這種狀況下你應該使用兩個<intent-filter>來分開它們。由於SENDTO必須使用Uri數據,而且須要sms和smsto的scheme。
<activity android:name="ShareActivity"> <!—爲發送文本過濾; 接收SENDTO action 使用 sms URI schemes --> <intent-filter> <action android:name="android.intent.action.SENDTO"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="sms" /> <data android:scheme="smsto" /> </intent-filter> <!—爲發送文本或圖像過濾; 接收SEND action和文本或者圖像數據 --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="image/*"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>爲了接收隱式的intents,咱們必須在<intent-filter>中定義CATEGORY_DEFAULT中,若是沒聲明,那麼你的activity不能解決處理隱式的intents。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //得到啓動activity的intent Intent intent = getIntent(); Uri data = intent.getData(); // 解決intent類型想作什麼 if (intent.getType().indexOf("image/") != -1) { //處理圖像數據 } else if (intent.getType().equals("text/plain")) { // 處理文本 } }
// 建立intent來傳遞某種結果數據 Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"); setResult(Activity.RESULT_OK, result); finish();咱們能夠只指定result code。一般是RESULT_OK或RESULT_CANCELED。你能夠添加額外的intent或者不添加。默認的result code是RESULT_CANCELED。因此若是用戶在你設置result以前執行Back鍵,那麼最初的activity收到的就是RESULT_CANCELED,這並非咱們預計的結果,這個細節請注意。