android_Intent

Intent

    Intent是抽象的數據結構,包含了一系列描述某個操作的數據,使得程序在運行時可以在程序中不同組件間通信或啓動

不同的應用程序。可以通過startActivity(Intent)啓動一個Activity, sendBroadcast(Intent) 發送廣播發送給感興

趣的BroadcastReceiver組件, startService(Intent)啓動service,bindService(Intent, ServiceConnection, int)綁定服務。

IntentFilter

Intent Filter顧名思義就是Intent的過濾器,組件通過定義Intent Filter可以決定哪些隱式Intent可以和該組件進行通訊。

關於隱式Intent的定義後面會進行介紹,Intent Filter對顯式的Intent不起作用。

Action

Action就是個String類型的字符串,在隱式Intent中用來和filter進行匹配的關鍵指標,如ACTION_VIEW,ACTION_EDIT等,Intent內置了很多Action常量

,我們也可以自定義私有Action方便自己進行匹配。

Data爲Uri類型的數據,若mType爲空通過對mData的解析可以得到數據的類型。

Component表示組件信息,包含context和目標組件的class信息,設置了即爲顯示Intent。

Category作爲決定哪個組件處理Intent的附屬信息,一個Intent可以添加或刪除多個Category存儲在mCategories。

Flag用於標記如何啓動一個活動,是NEW_TASK還是其他等等,以及啓動後怎麼對待這個活動。

Extras爲附加信息,會傳遞給目標組件,比如發送郵件,Extras可以存儲郵件收件人地址、內容、主題、附件等信息。

因爲Intent Filter和Intent的匹配只有三個字段起作用,所以Intent Filter只包含Actions、Datas、Categorys三個屬性(實際源碼中會將Data劃分爲多個部分),

屬性的意義和Intent相同。不同的是Intent Filter可以包含多個Action、多個Data、多個Category,而Intent除Category可以有多個外,只能有一個Action


Intent類型

對於一個定義好的Intent,Android如何判斷和哪個目標組件通訊呢。Intent分爲隱式(implicit)Intent和顯式(explicit)Intent。

顯式Intent通常用於在程序內部組件間通信,已經明確的定義目標組件的信息,所以不需要系統決策哪個目標組件處理Intent,如下

Intent intent = new Intent(DemoList.this, GoogleMapDemo.class);

startActivity(intent);

其中DemoList和GoogleMapDemo都是用戶自定義的組件,

隱式Intent不指明目標組件的class,只定義希望的Action及Data等相關信息,由系統決定使用哪個目標組件。如發送短信

Uri uri = Uri.parse("smsto:15800000000");

Intent i = new Intent(Intent.ACTION_SENDTO, uri);

i.putExtra("sms_body", "The SMS text");

startActivity(i);

Intent和IntentFilter匹配規則

Android系統通過對Intent和目標組件在AndroidManifest文件中定義的<intent-filter>(也可以在程序中定義Intent Filter)進行匹配決定和哪個目標組件通訊。

如果某組件未定義<intent-filter>則只能通過顯式的Intent進行通信。Intent的三個屬性用於對目標組件選取的決策,分別是Action、Data(Uri和Data Type)、Category

。匹配規則如下

a. Intent定義的Action必須包含在<intent-filter>的Action列表中,若隱式Intent未定義Action系統會報錯。由此可知一個<intent-filter>至少包含一個Action。

b. 未定義Uri和Type的Intent僅可以通過不包含包含Uri和Type的filter;包含了Uri,不包含Type的Intent僅可以通過包含匹配Uri不包含Type的filter;包含了Type不

包含Uri的Intent僅可以通過包含了相同Type不包含Uri的filter;同時包含了Uri和Type的Intent僅可以通過相同Type匹配Uri(或不包含Uri但Intent Uri爲content:或file:)

的filter。

c. Intent若定義了Category(可多個),則所有Category必需包含在<intent-filter>的Category列表中。若Intent未定義Category,則<intent-filter>是否定義Category

不影響。

PS:<intent-filter>必須包含<category android:name="android.intent.category.DEFAULT" />才能通過startActivity啓動,所以Activity的<intent-filter>至少包含一

個category,Service和BroadcastReceiver不必。

目標組件必須包含同時滿足以上規則的<intent-filter>才能進行匹配。若有多個目標組件同時可以匹配,則系統會提示用戶進行選擇,若沒有目標組件可以匹配系統會進行提示。

eg:

a. 發送短信

Uri uri = Uri.parse("smsto:15800000000");

Intent i = new Intent(Intent.ACTION_SENDTO, uri);

i.putExtra("sms_body", "The SMS text");

startActivity(i);

b. 打電話

Uri dial = Uri.parse("tel:15800000000");

Intent i = new Intent(Intent.ACTION_DIAL, dial);//"android.intent.action.CALL"

startActivity(i);

c. 發送郵件

Uri email = Uri.parse("mailto:[email protected];[email protected]");

Intent i = new Intent(Intent.ACTION_SENDTO, email);

startActivity(i);

Intent i = new Intent(Intent.ACTION_SEND);

String[] tos = {"[email protected]"};

String[] ccs = {"[email protected]"};

i.putExtra(Intent.EXTRA_EMAIL, tos);

i.putExtra(Intent.EXTRA_CC, ccs);

i.putExtra(Intent.EXTRA_SUBJECT, "主題");

i.putExtra(Intent.EXTRA_TEXT, "正文");

i.setType("message/rfc822");

startActivity(i);

d. 拍照

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String folderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "AndroidDemo" + File.separator;

String filePath = folderPath + System.currentTimeMillis() + ".jpg";

new File(folderPath).mkdirs();

File camerFile = new File(filePath);

i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(camerFile));

startActivityForResult(i, 1);

e. 瀏覽網頁

Uri web = Uri.parse("http://www.google.com"); 

Intent i  = new Intent(Intent.ACTION_VIEW, web); 

startActivity(i);

f. 查看聯繫人

Intent i = new Intent();

i.setAction(Intent.ACTION_GET_CONTENT);

i.setType("vnd.android.cursor.item/phone");

startActivityForResult(i, 1);

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