Android 之Intent,Filter和IntentFilter

Android 之Intent,Filter和IntentFilter

Intent(意图)/Filter(过滤器)

Android意图(Intent)是一个要执行的操作的抽象描述。它可以通过 startActivity 来启动一个活动,broadcastIntent 来发送广播到任何对它感兴趣的广播接受器组件,startService(Intent) 或者bindService(Intent, ServiceConnection, int) 来与后台服务通讯。
意图本身(一个 Intent 对象)是一个被动的数据结构,保存着要执行操作的抽象描述。

接收意图(Intent)等方法
  1. Context.startActivity():意图传递给该方法,用于启动一个新的活动或者让已存在的活动做一些新的事情。
  2. Context.startService():意图传递给该方法,将初始化一个服务,或者新的信息到一个持续存在的服务。
  3. Context.sendBroadcast():意图传递给该方法,信息将传递到所有对此感兴趣的广播接收器。

意图对象
意图对象是一包的信息,用于组件接收到的意图就像 Android 系统接受到的信息。

意图对象包括如下的组件,具体取决于要通信或者执行什么。

动作(Action)

这是意图对象中必须的部分,被表现为一个字符串。在广播的意图中,动作一旦发生,将会被报告。动作将很大程度上决定意图的其他部分如何被组织。Intent 类定义了一系列动作常量对应不同的意图。这里是一份Android意图标准动作 列表。

意图对象中的动作可以通过 setAction() 方法来设置,通过 getAction() 方法来读取。

数据(Data)

添加数据规格到意图过滤器。这个规格可以只是一个数据类型(如元类型属性),一条 URI ,或者同时包括数据类型和 URI 。 URI 则由不同部分的属性来指定。

这些指定 URL 格式的属性是可选的,但是也相互独立 -

  • 如果意图过滤器没有指定模式,所有其他的 URI 属性将被忽略。
  • 如果没有为过滤器指定主机,端口属性和所有路径属性将被忽略。

setData() 方法只能以 URI 来指定数据,setType() 只能以元类型指定数据,setDataAndType() 可以同时指定 URI 和元类型。URI 通过 getData() 读取,类型通过 getType() 读取。

动作/数据组的一些实例

  • ACTION_VIEW content://contacts/people/1:显示ID为1的用户的信息。
  • ACTION_DIAL content://contacts/people/1:显示电话拨号器,并填充用户1的数据。
  • ACTION_VIEW tel:123:显示电话拨号器,并填充给定的号码。
  • ACTION_DIAL tel:123:显示电话拨号器,并填充给定的号码。
  • ACTION_EDIT content://contacts/people/1:编辑ID为1的用户信息。
  • ACTION_VIEW content://contacts/people/:显示用户列表,以便查看。
  • ACTION_SET_WALLPAPER:显示选择壁纸设置。
  • ACTION_SYNC:同步数据,默认的值为:android.intent.action.SYNC
  • ACTION_SYSTEM_TUTORIAL:开启平台定义的教程(默认教程或者启动教程)
  • ACTION_TIMEZONE_CHANGED:当时区被改变时通知
  • ACTION_UNINSTALL_PACKAGE:运行默认的卸载器

意图的类型

Android 支持两种类型的意图,显示意图,隐式意图。

显式意图

显式意图用于连接应用程序的内部世界,假设你需要连接一个活动到另外一个活动,我们可以通过显示意图,下图显示通过点击按钮连接第一个活动到第二个活动。
这些意图通过名称指定目标组件,一般用于应用程序内部信息 - 比如一个活动启动一个下属活动或者启动一个兄弟活动。举个例子:

// 通过指定类名的显式意图
Intent i = new Intent(FirstActivity.this, SecondAcitivity.class);

// 启动目标活动
startActivity(i);

隐式意图

这些意图没有为目标命名,组件名称的域为空。隐式意图经常用于激活其他应用程序的组件。举个例子:

Intent read1=new Intent();
read1.setAction(android.content.Intent.ACTION_VIEW);
read1.setData(ContactsContract.Contacts.CONTENT_URI);
startActivity(read1);

目标组件接收到意图,可以使用getExtras()方法来获取由源组件发送的附加数据。例如:

// 在代码中的合适位置获取包对象
Bundle extras = getIntent().getExtras();

// 通过键解压数据
String value1 = extras.getString("Key1");
String value2 = extras.getString("Key2");

IntentFilter

IntentFilter就是“意图过滤器”,主要用来过滤隐式意图。当用户进行一项操作的时候,Android系统会根据配置的 “意图过滤器” 来寻找可以响应该操作的组件,服务。

例子

Android系统就会通过设定好的意图过滤器,进行匹配测试,找到能够打开PDF文件的APP程序代码如下:

<activity android:name="com.example.testmain.ShowActivity" >
      <intent-filter>
            <action android:name="test.update.mydata" />
            <category android:name="my.test.show" />
            <data android:pathPattern=".*\\.jpg" android:scheme="http" />
      </intent-filter>
 </activity>
IntentFilter 如何过滤隐式意图

Android系统会根据我们配置的Intent Filter(意图过滤器),来进行匹配测试。匹配的时候,只会考虑三个方面:动作、数据(URI以及数据类型)和类别。也就是说Android系统会进行“动作测试”,“数据测试”,“类别测试”,来寻找可以响应隐式意图的组件或服务。

另外,当对其他App程序开放组件和服务的时候也需要配置Intent Filter(意图过滤器),一个Activity可以配置多个< intent-filter >。

动作测试:

对应中的标签;
(1) 如果标签中有多个,那么Intent请求的Action,只要匹配其中的一条就可以通过了这条的动作测试。

(2) 如果中没有包含任何,那么无论什么Intent请求都无法和这条匹配。

(2) 如果Intent请求中没有设定Action(动作),那么这个Intent请求就将顺利地通过的动作测试(前提是中必须包含有,否则与第二条冲突)。

类别测试:

对应< intent-filter>中的< category />标签;

Intent中的类别必须全部匹配< intent-filter>中的< category />,但是< intent-filter>中多余的< category />将不会导致匹配失败。

例如:Intent中有3个类别,而意图过滤器中定义了5个,如果Intent中的3个类别都与过滤器中的匹配,那么过滤器中的另外2个,将不会导致类别测试失败。

数据测试:

对应< intent-filter>中的< data>标签;

< data>元素指定了可以接受的Intent传过来的数据URI和数据类型,当一个意图对象中的URI被用来和一个过滤器中的URI比较时,比较的是URI的各个组成部分。

例如:

如果过滤器仅指定了一个scheme,所有该scheme的URIs都能够和这个过滤器相匹配;

如果过滤器指定了一个scheme、主机名但没有路经部分,所有具有相同scheme和主机名的URIs都可以和这个过滤器相匹配,而不管它们的路经;

如果过滤器指定了一个scheme、主机名和路经,只有具有相同scheme、主机名和路经的URIs才可以和这个过滤器相匹配。

当然,一个过滤器中的路径规格可以包含通配符,这样只需要部分匹配即可。

发布了87 篇原创文章 · 获赞 198 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/low666/article/details/104817624