標籤:
隱式Intent的使用
一、為什麼要用隱式Intent?
但如果想調用別的程式的組件時,且開發人員往往並不清楚別的應用程式的組件名稱,這時我們只能用隱式Intent,隱式Intent恰恰相反,它不會用組件名稱定義需要啟用的目標組件,而是Android系統輔助應用程式尋找與Intent請求意圖最匹配的組件。
二、Android系統怎麼找?
主要是通過Intent Filter來尋找與隱式Intent相關的對象。具體的選擇方法是:Android將Intent的請求內容<intent-filter>比較,Intent Filter中包含系統中所有可能的待選組件。如果<intent-filter>中某一組件匹配隱式Intent請求的內容,那麼Android就選擇該組件作為該隱式Intent的目標組件。
三、<intent-filter>的基本格式如下:
<!--1.這裡定義了目標活動(目標組件) -> .SecondActivity--><!--2.指明這個活動的【動作標識action為】:com.example.activity.ACTION_START--><!--3.指明這個活動的【類別標識category為】:android.intent.category.DEFAULT 與--><!--com.example.activity.CPJ_category1與com.example.activity.CPJ_category2--><activity android:name="com.example.activity.SecondActivity"><intent-filter><action android:name="com.example.activity.ACTION_START"/> <category android:name="android.intent.category.DEFAULT"/><category android:name="com.example.activity.CPJ_category1"/><category android:name="com.example.activity.CPJ_category2"/></intent-filter></activity><!--指定當前活動可以響應com.example.activity.ACTION_START這個action--><!--1.<category>標籤包含一些附加資訊,更精確指明當前的活動能夠響應的Intent中,還可能帶有的category--><!--2.只有action和category同時匹配才能響應Intnet--> <!--3.android.intent.category.DEFAULT是一種預設的category,在調用--><!--startActivity()時會自動把這個category添加到intent中--> <!--4.一個intent只能有一個action,但是可以有多個category--><!--5.一個intent-filter可以同時有多個個action-->
四、Intent的請求內容如何與<intent-filter>比較?
1.動作比較-<action/> (第一步)
如:
<intent-filter><actionandroid:name="com.example.project.SHOW_CURRENT" /><actionandroid:name="com.example.project.SHOW_RECENT" /><actionandroid:name="com.example.project.SHOW_PENDING" /></intent-filter>
1). 一條<intent-filter>元素至少應該包含一個<action>,否則任何Intent請求都不能和該<intent-filter>匹配。
2). 如果Intent請求的Action和<intent-filter>中個某一條<action>匹配,那麼該Intent就通過了這條<intent-filter>的動作比較。(第一步完成)
2.類別比較-<category/> (第二步)如:
<intent-filter><categoryandroid:name="android.Intent.Category.DEFAULT" /><categoryandroid:name="android.Intent.Category.BROWSABLE" /></intent-filter>
1). 只有當Intent請求中所有的Category與組件中某一個Intent-filter的<category>完全符合時,才會通過匹配成功。也就說某一個<intent-filter>中的category必須包含Intent中的所有category時,才算類別匹配成功。(第二步完成)
2). Intent-filter中多餘的<category>聲明並不會導致匹配失敗,也就是說<intent-filter>中的category可以存在多餘項;
3). <categoryandroid:name="android.Intent.Category.DEFAULT" />是一種預設的category,在調用startActivity()時會自動把這個category添加到intent中.
4). 每一個通過 startActivity()方法發出的隱式 Intent 都至少有一個 category,就是 "android.intent.category.DEFAULT",所以只要是想接收一個隱式Intent的Activity都應該包括
"android.intent.category.DEFAULT" category,不然將導致 Intent匹配失敗。
3.資料比較-<data/> (第三步) 如:
<intent-filter><data android:type="video/mpeg" android:scheme="http" . . . /><data android:type="audio/mpeg" android:scheme="http" . . . /></intent-filter>
1). <data>元素指定了希望接受的Intent請求的資料URI和資料類型,URI被分成三部分來進行匹配:scheme、authority和path。其中,用setData()設定的Intent請求的URI資料類型和scheme必須與Intent-filter中所指定的一致。若Intent-filter中還指定了authority或path,它們也需要相匹配才會通過測試。(第三步完成)
總:
只有第一步匹配成功,才會繼續匹配此<intent-filter>的category及第二步,第二步匹配完成,才會匹配第三步。當都匹配上時,就找到對應的包含它們的 <activity android:name=".SecondActivity">跳轉到對應的目標組件上。
五、Intent.Action(安卓系統內建動作)的常見用法:
1. Intent.ACTION_MAIN
String: android.intent.action.MAIN
作用:標識Activity為一個程式的開始(表明app首先執行的Activity)。比較常用。
Input: nothing
Output: nothing
例:
<!--android.intent.action.MAIN 決定應用程式最先啟動的Activity--><!--android.intent.category.LAUNCHER 決定應用程式是否顯示在程式列表裡--><activity android:name=".Main" android:label="@string/app_name"> <intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>
例:利用Intent實現返回系統的Home案頭
Intent intent = new Intent(); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME);startActivity(intent);
2. Intent.Action_CALL
Stirng: android.intent.action.CALL
作用:呼叫指定的電話號碼(直接撥打到電話)。
Input: 電話號碼。資料格式為:tel:+phone number
Output: Nothing
例:
Intent intent=new Intent(); intent.setAction(Intent.ACTION_CALL);//設定當前動作為撥打到電話 intent.setData(Uri.parse("tel:1320010001"));//設定要撥打的電話startActivity(intent);
在AndroidMainifest.xml檔案中,為當前程式設定撥打到電話許可權:
<uses-permission android:name="android.permission.CALL_PHONE"/>
3. Intent.Action.DIAL
String: action.intent.action.DIAL
作用:調用撥號面板(只是調用,並沒有開始打電話)
Input: 電話號碼。資料格式為:tel:+phone number
Output: Nothing
說明:開啟Android的撥號UI。如果沒有設定資料,則開啟一個空的UI;
例:
Intent intent = new Intent(); intent.setAction(Intent.ACTION_DIAL);//設定當前動作為調用撥號盤 intent.setData(Uri.parse("tel:1584014xxxx"));//設定準備要撥打的電話startActivity(intent);
(這裡通過一個例子來仔細示範撥打到電話的用法,包括:直接撥號、開啟撥號盤、使用者自訂撥號)
//Button的點擊事件-直接撥打到電話Button btn_call = (Button) findViewById(R.id.Call);btn_call.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setAction(Intent.ACTION_CALL);//設定當前動作為撥打到電話intent.setData(Uri.parse("tel:1584014xxxx"));//設定要撥打的電話startActivity(intent);}});//Button的點擊事件-直接撥打到電話Button btn_dial = (Button) findViewById(R.id.Dial);btn_dial.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setAction(Intent.ACTION_DIAL);//設定當前動作為調用撥號盤intent.setData(Uri.parse("tel:1584014xxxx"));//設定準備要撥打的電話startActivity(intent);}});//擷取使用者輸入電話號碼的EditTextfinal EditText edt_phoneNumber = (EditText) findViewById(R.id.phonebunber_id);//Button點擊事件-使用者自己撥號Button btn_userCall = (Button) findViewById(R.id.userCall);btn_userCall.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//先驗證使用者輸入電話的有效性(使用安卓內建的包來判斷電話的有效性)String phoneNumber = edt_phoneNumber.getText().toString();if(PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber)){Intent intentDial = new Intent(); intentDial.setAction(Intent.ACTION_CALL);//設定當前為使用者自訂撥號 intentDial.setData(Uri.parse("tel:"+ phoneNumber));startActivity(intentDial);//提示使用者電話輸入有誤} else {Toast.makeText(CallActivity.this, "你輸入的電話有誤,請重新輸入", Toast.LENGTH_SHORT).show();}}});
4. Intent.ACTION_VIEW
String:android.intent.action.VIEW
作用:用於顯示使用者的資料,比較通用,會根據使用者的資料類型開啟相應的Activity。
資料類型就是指:tel(開啟撥號Activity)、http(開啟瀏覽器Activity)、geo(開啟地圖定位Activity)等
說明:這裡示範幾個簡單的應用;
//Button的點擊事件-開啟地圖Button btn_geo = (Button) findViewById(R.id.geo);btn_geo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);//設定當前動作intent.setData(Uri.parse("geo:39.899533,116.036476"));//開啟地圖定位(直接開啟你手機上的地圖軟體)startActivity(intent);}});//Button的點擊事件-開啟瀏覽器Button btn_http = (Button) findViewById(R.id.http);btn_http.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);//設定當前動作intent.setData(Uri.parse("http://www.baidu.com"));//開啟瀏覽器並開啟百度startActivity(intent);}});//Button的點擊事件-開啟一張照片Button btn_image = (Button) findViewById(R.id.image);btn_image.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);//設定當前動作//你若不清楚你的儲存路勁,可以在DDMS下查看Uri uri = Uri.parse("file:///storage/sdcard1/DCIM/Camera/IMG_20150622_172748.jpg");intent.setDataAndType(uri, "image/*");startActivity(intent);}});//Button的點擊事件-開啟視頻Button btn_video = (Button) findViewById(R.id.video);btn_video.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);//設定當前動作Uri uri = Uri.parse("file:///storage/sdcard1/---");intent.setDataAndType(uri, "video/*");startActivity(intent);}}); //Button的註冊事件-查看通訊錄Button SeeContacts_BT = (Button) findViewById(R.id.SeeContacts);SeeContacts_BT.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse("content://contacts/people/1"));//查看通訊錄中的第一個連絡人startActivity(intent);}});
5. Intent.ACTION_SENDTO
String: android.intent.action.SENDTO
作用:傳送簡訊息
說明:這裡示範幾個簡單的應用;
例:
String number = numberET.getText().toString();// 獲得使用者輸入的號碼String message = messageET.getText().toString();// 獲得使用者輸入的簡訊if(PhoneNumberUtils.isGlobalPhoneNumber(number)) {Intent intent = new Intent();// 建立Intent對象intent.setData(Uri.parse("smsto:" + number)); // 設定要發送的號碼intent.putExtra("sms_body", message); // 設定要發送的資訊內容startActivity(intent);// 將Intent傳遞給Activity} else {Toast.makeText(SendToActivity.this, "你輸入的電話錯誤,請重新輸入!",Toast.LENGTH_SHORT).show();}
(安卓傳送簡訊的方式有2種:
第一種:就是上面寫的這個 -> 調起系統發簡訊功能;
也就說用這種方式,當你點擊發送按鈕時,並沒有立馬發出去,而是讓系統開啟了你手機上的內建的發簡訊的程式,
並將你輸入的電話號碼和簡訊內容寫在了上面,你在單擊手機內建的簡訊程式的發送按鈕,才能發出去,
就像前面的ACTION_DIAL,只是開啟了撥號盤,並沒有開始打電話;
第二種:利用SmsManager -> 調用系統簡訊介面直接傳送簡訊;
用這種方式時,當你點擊你寫的傳送簡訊按鈕,直接就發出去了,並不調用別的簡訊程式。
且這種方式可以監控發送狀態和對方接收狀態(具體的以後介紹))
6. Intent.ACTION_BATTERY_LOW
作用:顯示電量低的警告資訊
說明:因為這一塊用到廣播,所以具體的實現辦法在複習有關廣播的知識時寫
7. Intent.ACTION_EDIT
作用:編輯通訊錄中某條特定的連絡人資訊
例:
Intent intent = new Intent(); intent.setAction(Intent.ACTION_EDIT); intent.setData(Uri.parse("content://contacts/people/1"));//修改通訊錄中的第一個連絡人startActivity(intent);
(擷取通訊錄中的所有連絡人資訊還有別的辦法-用到了內容提供器,後面再說)
參考網址與資料:
1.http://blog.csdn.net/coder80/article/details/7879259
2.http://www.cnblogs.com/hanyonglu/archive/2012/03/26/2417278.html
3.《Android程式開發範例寶典》
隱式Intent的使用——Android學習筆記3