显式Intent定义:对于明确指出了目标组件名称的Intent,我们称之为显式Intent。显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,因此,显式Intent更多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。
隐式Intent定义:对于没有明确指出目标组件名称的Intent,则称之为隐式Intent。它不会用组件名称定义需要激活的目标组件,它更广泛地用于在不同应用程序之间传递消息.由于没有明确的目标组件名称,所以必须由Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。
隐式启动Intent:
Android系统寻找与Intent请求意图最匹配的组件具体的选择方法是:
Android将Intent的请求内容和一个叫做IntentFilter的过滤器比较,IntentFilter中包含系统中所有可能的待选组件.如果IntentFilter中某一组件匹配隐式Intent请求的内容,那么Android就选择该组件作为该隐式Intent的目标组件。
Android如何知道应用程序能够处理某种类型的Intent请求呢?这需要应用程序在Android-Manifest.xml中声明自己所含组件的过滤器(即可以匹配哪些Intent请求)。
一个没有声明Intent-Filter的组件只能响应指明自己名字的显式Intent请求,而无法响应隐式Intent请求。
一个声明了IntentFilter的组件既可以响应显式Intent请求,也可以响应隐式Intent请求。在通过和 IntentFilter比较来解析隐式Intent请求时,Android将以下三个因素作为选择的参考标准Action \Data\ Category,而Extra和Flag在解析收到Intent时是并不起作用的
Intent过滤器:
应用程序的组件为了告诉Android自己能响应、处理哪些隐式Intent请求,可以声明一个甚至多个Intent Filter。每个Intent Filter描述该组件所能响应Intent请求——组件希望接收什么类型的请求行为,什么类型的请求数据。
如何为组件声明自己的Intent Filter? 常见的方法是在AndroidManifest.xml文件中用属性<Intent-Filter>描述组件的Intent Filter。
隐式Intent和Intent Filter进行比较时的三要素是Intent的动作、数据以及类别。实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面的检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给目标组件。接下来我们讲解这三方面检查的具体规则。
Action测试:<intent-filter> <action android:name=”com.example.project.SHOW_CURRENT” /> <action android:name=”com.example.project.SHOW_RECENT” /> <action android:name=”com.example.project.SHOW_PENDING” /> </intent-filter>
一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和该<intent-filter>匹配。
如果Intent请求的Action和<intent-filter>中个某一条<action>匹配,那么该Intent就通过了这条<intent-filter>的动作测试。
如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。 (1) 如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent- filter>匹配; (2) 反之,如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个 Intent请求就将顺利地通过<intent-filter>的行为测试。
Category测试:<intent-filter > <category android:name=”android.Intent.Category.DEFAULT” /> <category android:name=”android.Intent.Category.BROWSABLE” /> </intent-filter>
只有当Intent请求中所有的Category与组件中某一个IntentFilter的<category>完全匹配时,才会让该 Intent请求通过测试.
IntentFilter中多余的<category>声明并不会导致匹配失败。
一个没有指定任何类别测试的 IntentFilter仅仅只会匹配没有设置类别的Intent请求。
Data测试:
<intent-filter> <data android:type=”video/mpeg” android:scheme=”http” . . /> <data android:type=”audio/mpeg” android:scheme=”http” . . /> </intent-filter>
<data>元素指定了希望接受的Intent请求的数据URI和数据类型,URI被分成三部分来进行匹配:scheme、authority和path。其中,用setData()设定的Inteat请求的URI数据类型和scheme必须与IntentFilter中所指定的一致。若IntentFilter中还指定了authority或path,它们也需要相匹配才会通过测试
演示一个例子,用Intent隐身启动activity,并显示Action和Category的值,这个例子用到了两个Activity,两个布局,要注意到是在AndroidMainFest里设置uses-permission
首先来看布局文件main.xml
View Code
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 >
7 <Button android:id="@+id/bt1"
8 android:layout_width="fill_parent"
9 android:layout_height="wrap_content"
10 android:text="intent隐身启动test"
11 />
12 </LinearLayout>
second.xml文件
View Code
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:orientation="vertical"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent">
7 <EditText android:id = "@+id/et1"
8 android:layout_width="fill_parent"
9 android:layout_height="wrap_content"/>
10 <EditText android:id ="@+id/et2"
11 android:layout_width="fill_parent"
12 android:layout_height="wrap_content"/>
13 </LinearLayout>
然后给大家看一下AndroidMainFest里的代码
View Code
1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="cn.shaoyangjiang.com"
4 android:versionCode="1"
5 android:versionName="1.0">
6 <uses-sdk android:minSdkVersion="8" />
7
8 <application android:icon="@drawable/icon" android:label="@string/app_name">
9 <activity android:name=".IntentFilterActivity"
10 android:label="@string/app_name">
11 <intent-filter>
12 <action android:name="android.intent.action.MAIN" />
13 <category android:name="android.intent.category.LAUNCHER" />
14 </intent-filter>
15 </activity>
16
17 <activity android:name=".Second"
18 android:label="@string/app_name">
19 <intent-filter>
20 <!-- 指定该Activity能响应action为指定字符串的Intent -->
21 <action android:name="cn.shaoyangjiang.cn.com" />
22 <!-- 指定该Activity能响应category为指定字符串的Intent -->
23 <category android:name="cn.shaoyangjiang.cn" />
24 <!-- 指定该Activity能响应category为android.intent.category.DEFAULT的Intent -->
25 <category android:name="android.intent.category.DEFAULT" />
26 </intent-filter>
27 </activity>
28 </application>
29 <uses-permission android:name="android.permission.READ_CONTACTS" />
30 <uses-permission android:name="android.permission.WRITE_CONTACTS" />
31 </manifest>
第三步:修改intentfilterActivity.java文件
View Code
1 package cn.shaoyangjiang.com;
2
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.os.Bundle;
6 import android.view.View;
7 import android.view.View.OnClickListener;
8 import android.widget.Button;
9
10 public class IntentFilterActivity extends Activity {
11 //定义一个Action常量
12 final static String shao = "cn.shaoyangjiang.cn.com";
13 //定义一个Category常量
14 final static String yang = "cn.shaoyangjiang.cn";
15 @Override
16 public void onCreate(Bundle savedInstanceState) {
17 super.onCreate(savedInstanceState);
18 setContentView(R.layout.main);
19 Button button1 = (Button)findViewById(R.id.bt1);
20 button1.setOnClickListener(new OnClickListener() {
21 @Override
22 public void onClick(View arg0) {
23 Intent intent = new Intent();
24 //设置Action属性
25 intent.setAction(shao);
26 //添加Category属性
27 intent.addCategory(yang);
28 startActivity(intent);
29 }
30 });
31 }
32 }
最后一部是second.java文件
View Code
1 package cn.shaoyangjiang.com;
2
3 import java.util.Set;
4 import android.app.Activity;
5 import android.os.Bundle;
6 import android.widget.EditText;
7
8 public class Second extends Activity{
9 @Override
10 protected void onCreate(Bundle savedInstanceState) {
11 super.onCreate(savedInstanceState);
12 setContentView(R.layout.second);
13 EditText editText1 =(EditText)findViewById(R.id.et1);
14 //获取该Activity对应的Intent的Action属性
15 String actionValue = getIntent().getAction();
16 //显示Action属性
17 editText1.setText("Action: "+actionValue);
18 EditText editText2 = (EditText)findViewById(R.id.et2);
19 //获取该Activity对应的Intent的Category属性
20 Set<String> cate= getIntent().getCategories();
21 //显示Action属性
22 editText2.setText("Categoties: "+cate);
23 }
24 }
效果图: