Android中的Intent和Intent-filter總結
一.相關概念
(一)基本概念
Intent中文意思指”意圖”,按照Android的設計理念,Android使用Intent來封裝程式的”呼叫意圖”,不管啟動Activity、Service、BroadcastReceiver,Android都使用統一的Intent物件來封裝這一”啟動意圖”。此外,Intent也是應用程式元件之間通訊的重要媒介。在Android中指定的了具體是某個元件,那麼就是顯性意圖;如果只是提出要求沒有指定具體的某個人,在Android中即沒有指定某個具體的元件,那麼就是隱式意圖;所有Intent頁面跳轉的方式又分為顯示跳轉和隱式跳轉。
(二)Intent和三大元件
Android應用程式包含三種重要元件:Activity、Service、BroadcastReceiver,應用程式採用一致的方式啟動它們,都是依靠Intent來進行啟動的,Intent中封裝了程式要啟動的意圖。
下面是Intent啟動不同元件的部分方法:
Activity元件:
startActivity(Intent intent);startActivityForResult(Intent intent,int requestCode);
Service元件:
startService(Intent intent);bindService(Intent intent,ServiceConnection conn,int flags);
BroadcastReceiver元件:
sendBroadcast(Intent intent);sendOrderedBroadcast(Intent intent,String receiverPermission);
(三)Intent的屬性類別
Intent的屬性及intent-filter的配置相結合使用;Intent的屬性大致包含:Component,Action,Category,Data,Type,Extra,Flag這7種屬性,其中Component用於明確指定需要啟動的元件,而Extra則用於”攜帶”需要交換的資料。
關於Intent屬性的詳解,在簡單使用後再介紹。
二.Intent的使用
這裡的Intent使用,主要是使用它來執行頁面的跳轉功能。
如果Intent物件中包含了目標的class檔案,那麼就是顯示意圖的跳轉;如果Intent沒有包含目標的class檔案,就是隱式意圖跳轉,隱式意圖跳轉就涉及到比較多的Intent物件的屬性值的比較。
(一)Intent顯式跳轉頁面
其中實現跳轉的java程式碼非常簡單:
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
其中具體實現是通過Intent的屬性類Component來實現,不過Component類的方法都封裝在Intent的方法裡面了,不需要我們過多的去了解。
這如果要傳遞資料也可以通過Intent物件使用putExtra方法來傳遞資料。
這裡的目標檔案必須是要在AndroidManifest.xml裡面註冊。
(二)Intent隱式跳轉頁面
隱式意圖的跳轉是本文主要講解的內容,也是比較難理解的內容!
這裡先使用Intent的Action和Data屬性來跳轉頁面做示例(特別要注意的是這裡的Data不是Intent的資料,而是Action動作對應的資料):
1.佈局檔案activity.xml檔案設計
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="意圖Intent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="action"
android:text="action" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="actionUri"
android:text="actionUri" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="ToSecondActivity"
android:text="跳轉到第二個頁面" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="MyAction"
android:text="MyAction" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="actionMain"
android:text="返回桌面" />
</LinearLayout>12345678910111213141516171819202122232425262728293031323334353637383940414243
上面的xml佈局檔案設計有5個按鈕,具體功能開java程式碼,下面詳細解釋。
1
2.java檔案MainActivity.xml檔案的設計
package com.example.intent;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//開啟一個數據檢視,但是沒有要求,系統會預設讓你從多箇中選擇其中一個開啟
public void action(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
startActivity(intent);
}
//開啟一個數據檢視,有資料要求,系統幫你開啟一個瀏覽器,並連線到相關的頁面
public void actionUri(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
//使用顯示跳轉的方法跳轉到第二個頁面
public void ToSecondActivity(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
//這裡只用自己定義的Action字串來找到對應的頁面
public void MyAction(View v) {
Intent intent = new Intent("HelloWorld");//Action字串可以直接放在Intent的建構函式裡面,也可以單獨寫
// intent.setAction("HelloWorld");
intent.addCategory("android.intent.category.DEFAULT");//可以沒有
//但是自定義的Action的xml檔案裡面必須要有category元素,否則會報錯
startActivity(intent);
}
//開啟程式入口,特徵是桌面
public void actionMain(View v) {
try {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
} catch (Exception e) {
Toast.makeText(this, "找不到目標頁面", Toast.LENGTH_SHORT).show();
}
}
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
這要重點理解的程式碼,下面會詳細介紹。
3.java檔案SecondActivity.java檔案的設計
K
一個簡單Activity的設計,使用程式碼設計一個執行緒佈局並新增兩個文字,第二個文字新增的是跳轉後顯示的Intent屬性。
4.在AndroidManifest註冊一下SecondActivity.class檔案
<activity android:name=".SecondActivity" >
<intent-filter>
<action android:name="HelloWorld"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>123456
檔案中使用intent-filter(意圖過濾器),用來存放意圖的屬性
其中MainActivity.java檔案是要重點理解的;上面寫了五個按鈕對應的監聽方法。
執行程式後顯示的介面:
頁面顯示有五個按鈕,每個按鈕對應的是一個按鈕的監聽方法。下面分別介紹:
第一個按鈕使用的是隱式意圖跳轉頁面,Action屬性是系統的Action物件值,是指跳轉到一個View的檢視,這沒有指向具體目標。
點選這個按鈕會顯示多個View的檢視供你選擇,效果如圖:
可以點選對應的檢視按鈕,進入相關介面。
其中這裡的Action值是通過構造方法來傳進去的,也可以通過Intent物件進行設定。
第二個按鈕也是開啟一個檢視,但是這個檢視有動作對應的資料,所以它會直接開啟一個瀏覽器,來顯示你要開啟的網頁。
效果如圖:
對於常用的一些頁面跳轉的Action和它對應的Date是需要我們程式設計師花時間去記一下的。後面會有常用的Action和Data介紹。
第三個按鈕是顯示跳轉到另一個頁面,因為這個頁面是自定義的,所以需要在登錄檔AndroidManifest裡面中註冊。如果被顯式呼叫,只需要新增Activity的name屬性就可以了,不需要設定Activity的過濾器intent-filter也可以。
點選按鈕後顯示的結果:
這裡的Action物件的值和Category物件的值都是空的。因為前面的跳轉的Intent物件沒有這個值,所以它的物件是空的,對比下面一個按鈕就知道了。
第四個按鈕是隱式意圖跳轉去另一個頁面,使用的Action值也不是系統定義的,而是自己定義的一個字串。這裡是通過Action和Category的值來確定一個頁面。Category代表的是動作的類別的意思。
點選按鈕後顯示的結果:
可以考到頁面顯示了,Intent裡面包含的Action的值和Category的值。如果之前沒有傳進去就不會有。
第五個按鈕,也是隱式意圖跳轉的使用,這裡的Action值和Category值都是系統定義的都具有特定的含義,兩個結合使用就相對於使用了Home鍵直接顯示到桌面。
還有就是這個按鈕的方法裡面使用到了try catch方法,這是防止程式崩潰的方法,正確情況如果輸入的Action值或Category值沒有指向某一個或一些頁面,系統會直接崩潰,所有使用try catch是十分必要的。
意圖跳轉時使用try catch來防止出錯是非常必要的。
三.intent-filter詳細屬性的介紹
<intent-filter/>是每一個Activity對應的過濾器標籤節點。每一個過濾器裡面的元素可以有:
0個或多個<action.../>
0個或多個<category.../>
0個或1個<data.../>1234
(一)全部屬性的簡介
Intent通過下面的屬性來描述的某個意圖:
1. action(動作): 用來表示意圖的動作,如:檢視,發郵件,打電話
2. category(類別): 用來表示動作的類別。
3. data(資料): 表示與動作要操作的資料。如:檢視指定的聯絡人
4. type(資料型別): 對data型別的描述。
5. extras(附件資訊): 附件資訊。如:詳細資料,一個檔案,某事。
6. component(目標元件): 目標元件。
下面詳細介紹各個元件的使用
(一)component屬性
指定了component屬性的Intent(呼叫setComponent(ComponentName)或者
setClass(Context, Class),Class其實就是顯式呼叫需要的目標類的檔名。這個屬性用得比較少,最好不用。如果是顯示呼叫直接指定目標類的class檔名就可以使用了。
比如:
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);12
Intent在後臺已經幫我們實現了component屬性的設定,我們不需要很麻煩的再去實現它的過程。
(二)action動作屬性
動作很大程式上決定了Intent如何構建,特別是資料和附加資訊,就像一個方法名決定了引數和返回值一樣,所以應該儘可能明確地指定動作,並緊密關聯到其他的Intent欄位,如Category和Data。
常用動作
最常用的是Action_MAIN(作為初始的Activity啟動,沒有資料的輸入輸出)
1. ACTION_MAIN 作為一個主要的進入口,而並不期望去接受資料
2. ACTION_VIEW 向用戶去顯示資料
3. ACTION_ATTACH_DATA 別用於指定一些資料應該附屬於一些其他的地方,例如,圖片資料應該附
屬於聯絡人
4. ACTION_EDIT 訪問已給的資料,提供明確的可編輯
5. ACTION_GET_CONTENT 允許使用者選擇特殊種類的資料,並返回(特殊種類的資料:照一張相片或
錄一段音) ACTION_DIAL 撥打一個指定的號碼,顯示一個帶有號碼的使用者介面,允許
使用者去啟動呼叫
6. ACTION_CALL 根據指定的資料執行一次呼叫(有缺陷,使用ACTION_DIAL)
7. ACTION_SEND 傳遞資料,被傳送的資料沒有指定,接收的action請求使用者發資料
8. ACTION_SENDTO 傳送一條資訊到指定的某人
9. ACTION_ANSWER 處理一個打進電話呼叫
10. ACTION_INSERT 插入一條空專案到已給的容器
11. ACTION_DELETE 從容器中刪除已給的資料
12. ACTION_SEARCH 執行一次搜尋
13. ACTION_WEB_SEARCH 執行一次web搜尋
上面的動作都是Intent物件引用才有實際意義的。
setAction(String action) 用來設定Intent的動作,引數可以為常量
getAction() 方法用來獲取Intent動作名稱
上面的Action都是系統定義好的,具有一定意義的動作指向的動作。
Intent的Action物件其實就是一個字串常量,系統的Action物件是系統定義好的字串常量,我們也可以自己定義自己的Action作為字串常量。就像上面的例子使用到了自定義的Action字串物件。
(三)category類別屬性
Intent的action、category屬性都是普通的字串,其中action表示Intent需要完成的一個抽象”動作”,而category則為action新增額外的類別資訊,通常action和category一塊使用。
需要指出的是,一個Intent中只能包含一個action屬性,但可以包含多個category屬性。當程式建立Intent時,該Intent預設啟動常量值為andorid.intent.category.DEFAULT的元件。這裡的一個Intent中只能包含一個action屬性,並不是Activity中xml的設定規範,而是你要跳轉到的頁面去,你只能設定一個Action的值。
常用的Category:
1.CATEGORY_DEFAULT:Android系統中預設的執行方式,按照普通Activity的執行方式執行。
2.CATEGORY_HOME:設定該元件為Home Activity。
3.CATEGORY_PREFERENCE:設定該元件為Preference。
4.CATEGORY_LAUNCHER:設定為當前應用程式優先順序最高的Activity,通常與ACTION_MAIN配合使用。
5.CATEGORY_BROWSABLE:設定該元件可以使用瀏覽器啟動。
6.CATEGORY_GADGET:設定該元件可以內嵌到另外的Activity中。
上面的類別都是Intent物件引用才有實際意義的。
(四)data動作資料
Data資料用來向Action屬性提供動作的資料。這裡的Data不是Intent裡面的資料,而是指明動作的具體資料,比如說動作是打電話,那麼打給具體的某一個人,就用到了date裡面的資料來指定。同樣發郵件、或開啟具體的某一個網址也是通過Data資料。
Data屬性只接受Uri物件,Uri物件是統一資源識別符號。對應概念不用太多理解,只需知道里面某些具體值的表現形式就可以了。
Uri其實就是相當於一個網址,如圖所示:
網址只是Uri其中一種格式的字串,要使用它還要把它解析後轉化為Uri型別。
為Intent物件新增Data資料,程式碼:
intent.setData(Uri.parse(“http://www.baidu.com“));
這裡的Uri的有兩個沒顯示的屬性:port的值是8080,path的值是/index
通過下面三句程式碼就可以跳轉到百度主頁面:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);123
(五)type資料型別
與Data有關的,這個不是Intent的資料型別,是Intent的Action的Data資料的型別。
比如:
{“.mp3”, “audio/x-mpeg”},
{“.mp4”, “video/mp4”},
{“.gif”, “image/gif”},
{“.rmvb”, “audio/x-pn-realaudio”},
這裡只是做幾個簡單的示例介紹,如果是開啟gif格式的資料檔案,設定type=“image/gif”
(六)extras額外的資料資訊
Extras屬性主要用於傳遞目標元件所需要的額外的資料。這個資料是可以通過Intent來儲存的資料和Intent物件來獲取資料。
通過putExtras()方法設定。儲存資料
通過putExtras()方法設定。獲取資料
通常我們使用Intent來直接傳遞Bundle物件,但也可以傳遞其他系統內建的一些引數。
如果要傳遞是是物件,那麼物件必須實現序列化。
(七)intent-filter在AndroidManifest中
1.在裡可以有多個
,只需匹配其中一個即可。
語法:
<intent-filter>
<data android:host="string"
android:mimeType="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:port="string"
android:scheme="string" />
</intent-filter>123456789
也可以分開寫,如:
<data android:scheme="something" android:host="project.example.com" android:port="80"/>
等同於這樣寫:
<data android:scheme="something"/>
<data android:host="project.example.com"/>
<data android:port="80"/>
等同於Uri uri = Uri.parse("something://project.example.com:80");123456
Uri的格式:scheme://host:port/path or pathPrefix or pathPattern
如果scheme沒有指定,那其它的屬性均無效;
如果host沒有指定,那麼port,path,pathPrefix,pathPattern均無效;
如果在manifest裡這樣寫:
那麼Uri uri = Uri.parse(“something://project.example.com”); 才可以匹配
2.在裡可以有多個data或action ,只需匹配其中一個即可。
3.當匹配不上任何Activity的話,會發生異常,跳出對話方塊:很抱歉…某某應用程式意外停止,請重試。
4.上面所說的全部適用於Service和BroadcastReceiver。
(八)幾個簡單示例的程式碼
/**
* 跳轉到指定的網址頁面
*/
public void toView(View v) {
Intent intent = new Intent();
//設定Data資料
intent.setData(Uri.parse("http://www.baidu.com"));
//設定Action資料
intent.setAction(Intent.ACTION_VIEW);
//頁面跳轉
startActivity(intent);
}
/**
* 跳轉到編輯聯絡人的資訊
* 這裡聯絡人的姓名是:1
*/
public void toEdit(View v) {
Intent intent = new Intent();
//設定Data資料
intent.setData(Uri.parse("content://com.android.contacts/contacts/1"));
//設定Action資料
intent.setAction(Intent.ACTION_EDIT);
//頁面跳轉
try {
startActivity(intent);
} catch (Exception e) {
Toast.makeText(this, "找不到該聯絡人!", Toast.LENGTH_SHORT).show();
}
}
/**
* 跳轉到撥打電話的頁面
* Data可以設定電話號碼
*/
public void toDial(View v) {
Intent intent = new Intent();
//設定Data資料
intent.setData(Uri.parse("tel:13814236512"));
//設定Action資料
intent.setAction(Intent.ACTION_DIAL);
//頁面跳轉
startActivity(intent);
}1234567891011121314151617181920212223242526272829303132333435363738394041424344
三.下面是一些Intent物件的常量值
附部分Intent屬性值:
Action:
ACTION_MAIN:Android Application的入口,每個Android應用必須且只能包含一個此型別的Action宣告。
ACTION_VIEW:系統根據不同的Data型別,通過已註冊的對應Application顯示資料。
ACTION_EDIT:系統根據不同的Data型別,通過已註冊的對應Application編輯示資料。
ACTION_DIAL:系統默開啟撥號程式,如果Data中設定電話號碼,則撥號框中會顯示此號碼。
ACTION_CALL:直接呼叫Data中所帶的號碼。
ACTION_ANSWER:接聽來電。
ACTION_SEND:由使用者指定傳送方式進行資料傳送操作。
ACTION_SENDTO:系統根據不同的Data型別,通過已註冊的對應Application進行資料傳送操作。
ACTION_BOOT_COMPLETED:Android系統在啟動完畢後發出帶有此Action的廣播(Broadcast)。
ACTION_TIME_CHANGED:Android系統的時間發生改變後發出帶有此Action的廣播(Broadcast)。
ACTION_PACKAGE_ADDED:Android系統安裝了新的App之後發出帶有此Action的廣播(Broadcast)。
ACTION_PACKAGE_CHANGED:Android系統中已存在的App發生改變之後(如更新)發出帶有此Action的廣播(Broadcast)。
ACTION_PACKAGE_REMOVED:Android系統解除安裝App之後發出帶有此Action的廣播(Broadcast)。
Category:
CATEGORY_DEFAULT:Android系統中預設的執行方式,按照普通Activity的執行方式執行。
CATEGORY_HOME:設定該元件為Home Activity。
CATEGORY_PREFERENCE:設定該元件為Preference。
CATEGORY_LAUNCHER:設定為當前應用程式優先順序最高的Activity,通常與ACTION_MAIN配合使用。
CATEGORY_BROWSABLE:設定該元件可以使用瀏覽器啟動。
CATEGORY_GADGET:設定該元件可以內嵌到另外的Activity中。
Extras:
EXTRA_BCC:存放郵件密送人地址的字串陣列。
EXTRA_CC:存放郵件抄送人地址的字串陣列。
EXTRA_EMAIL:存放郵件地址的字串陣列。
EXTRA_SUBJECT:存放郵件主題字串。
EXTRA_TEXT:存放郵件內容。
EXTRA_KEY_EVENT:以KeyEvent物件方式存放觸發Intent的按鍵。
EXTRA_PHONE_NUMBER:存放呼叫ACTION_CALL時的電話號碼。
Data:
tel://:號碼資料格式,後跟電話號碼。
mailto://:郵件資料格式,後跟郵件收件人地址。
smsto://:短息資料格式,後跟簡訊接收號碼。
content://:內容資料格式,後跟需要讀取的內容。
file://:檔案資料格式,後跟檔案路徑。
market://search?q=pname:pkgname:市場資料格式,在Google Market裡搜尋包名為pkgname的應用。
geo://latitude, longitude:經緯資料格式,在地圖上顯示經緯度所指定的位置。
MimeType:
{“.3gp”, “video/3gpp”},
{“.apk”, “application/vnd.android.package-archive”},
{“.asf”, “video/x-ms-asf”},
{“.avi”, “video/x-msvideo”},
{“.bin”, “application/octet-stream”},
{“.bmp”, “image/bmp”},
{“.c”, “text/plain”},
{“.class”, “application/octet-stream”},
{“.conf”, “text/plain”},
{“.cpp”, “text/plain”},
{“.doc”, “application/msword”},
{“.docx”, “application/vnd.openxmlformats-officedocument.wordprocessingml.document”},
{“.xls”, “application/vnd.ms-excel”},
{“.xlsx”, “application/vnd.openxmlformats-officedocument.spreadsheetml.sheet”},
{“.exe”, “application/octet-stream”},
{“.gif”, “image/gif”},
{“.gtar”, “application/x-gtar”},
{“.gz”, “application/x-gzip”},
{“.h”, “text/plain”},
{“.htm”, “text/html”},
{“.html”, “text/html”},
{“.jar”, “application/Java-archive”},
{“.java”, “text/plain”},
{“.jpeg”, “image/jpeg”},
{“.jpg”, “image/jpeg”},
{“.js”, “application/x-JavaScript”},
{“.log”, “text/plain”},
{“.m3u”, “audio/x-mpegurl”},
{“.m4a”, “audio/mp4a-latm”},
{“.m4b”, “audio/mp4a-latm”},
{“.m4p”, “audio/mp4a-latm”},
{“.m4u”, “video/vnd.mpegurl”},
{“.m4v”, “video/x-m4v”},
{“.mov”, “video/quicktime”},
{“.mp2”, “audio/x-mpeg”},
{“.mp3”, “audio/x-mpeg”},
{“.mp4”, “video/mp4”},
{“.mpc”, “application/vnd.mpohun.certificate”},
{“.mpe”, “video/mpeg”},
{“.mpeg”, “video/mpeg”},
{“.mpg”, “video/mpeg”},
{“.mpg4”, “video/mp4”},
{“.mpga”, “audio/mpeg”},
{“.msg”, “application/vnd.ms-outlook”},
{“.ogg”, “audio/ogg”},
{“.pdf”, “application/pdf”},
{“.png”, “image/png”},
{“.pps”, “application/vnd.ms-powerpoint”},
{“.ppt”, “application/vnd.ms-powerpoint”},
{“.pptx”, “application/vnd.openxmlformats-officedocument.presentationml.presentation”},
{“.prop”, “text/plain”},
{“.rc”, “text/plain”},
{“.rmvb”, “audio/x-pn-realaudio”},
{“.rtf”, “application/rtf”},
{“.sh”, “text/plain”},
{“.tar”, “application/x-tar”},
{“.tgz”, “application/x-compressed”},
{“.txt”, “text/plain”},
{“.wav”, “audio/x-wav”},
{“.wma”, “audio/x-ms-wma”},
{“.wmv”, “audio/x-ms-wmv”},
{“.wps”, “application/vnd.ms-works”},
{“.xml”, “text/plain”},
{“.z”, “application/x-compress”},
{“.zip”, “application/x-zip-compressed”},
總結:
本文只要是對Intent知識中隱式Intent意圖的講解,其實這部分內容並不是很常用,也是比較難理解一些。
學習Intent只要學會下面幾個知識點就差不多了:
1.Intent顯式頁面跳轉的實現
2.Intent跳轉到撥打電話頁面,固定網頁上等基礎功能。
3.Intent學會使用資料的傳入和拿出。
其中資料的處理,之前有個例子,大家可以借鑑一下:
http://blog.csdn.net/wenzhi20102321/article/details/52750526