Intent以及IntentFilter

本文深入讲解Android中的Intent机制,探讨其在组件间通信中的作用,包括Intent的基本概念、显式与隐式Intent的区别、Intent的属性等内容。

Intent的概念:
Android中提供了Intent机制来协助应用间的交互与通讯,或者采用更准确的说法是,Intent不仅可用于应用程序之间,也可用于应用程序内部的activity, service和broadcast receiver之间的交互。Intent这个英语单词的本意是“目的、意向、意图”。
Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来响应。
activity、service和broadcast receiver之间是通过Intent进行通信的,而另外一个组件Content Provider本身就是一种通信机制,不需要通过Intent。

对于向这三种组件发送intent有不同的机制:
使用Context.startActivity() 或 Activity.startActivityForResult(),传入一个intent来启动一个activity。使用 Activity.setResult(),传入一个intent来从activity中返回结果。
将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service。将intent对象传给 Context.bindService()来绑定一个service。
将intent对象传给 Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则它们被传给 broadcast receiver。

意图中包含的属性:Component,Action,Category,Date,Type,Extra,Flag这7个属性。

   Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。

——显示意图和隐式意图的区别?
一、显式意图:明确指定Intent的目标组件。 一般用于同一应用程序之间的跳转。
1)Component :意图所要启动的组件
ComponentName有三种构造器:
(1)ComponentName(Context,Class)
(2)ComponentName(Context,String)
(3)ComponentName(String package,String clz)
其中用来表示类名的字符串必须使用全类名.
包名只是用来区分android应用程序的。
也可以启动不同android应用程序的activity
intent.setComponent(component);
也可以使用intent.setClass()
也可以使用new Intent(Context,Class)
缺点:不能调用其他应用中的Activity。(但是5.0的版本可以使用了)

二、隐式意图:没有明确指定组件名的Intent为隐式意图,

    Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。一般用于不同应用程序之间的跳转。
    Android系统使用IntentFilter来寻找与隐式相关的组件。
    举个例子,说白了意图就是启动一个组件的的完整的动作信息,就像打人,打就是Action动作,人就是Data内容,而Type就是类型,打什么人呢?打坏人,type就是坏指的类型,只有这些信息全了才能执行一个完整的意图

(1)Action 动作
Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的Activity 定义时,可以在其 节点指定一个 Action列表用于标识 Activity 所能接受的“动作”。
(2)Category 为Action增加额外的附加条件(用来表现动作的类别)
一般将action和category结合使用
注意:
Intent:只能包含一个Action,可以有多个Category
Activity:可以配置多种Action,可以配置多个Category,类别越多,动作越具体,意图越明确(类似于相亲时,给对方提了很多要求)。
问题:如果有两个Activity的action配置是相同的,由另外一个Activity启动该action会怎样?
当Intent匹配成功的组件有多个时,显示优先级高的组件,如果优先级相同,显示列表让用户自己选择,优先级从-1000至1000,并且其中一个必须为负的才有效
注意:
a)每一个通过 startActivity() 方法发出的隐式Intent都至少有一个 category,就是 “android.intent.category.DEFAULT”,所以只要是想接收一个隐式 Intent 的 Activity 都应该包括”android.intent.category.DEFAULT” category,不然将导致 Intent 匹配失败
b)一个至少应该包含一个,否则任何Intent请求都不能和该匹配。若Intent请求的Action和中的某一个匹配,那么该Intent就通过这条的动作测试。
c)如中没有包含任何Action类型,那么无论什么Intent请求都无法和这个匹配
e)当Intent请求中包含并所有的Category与组件中某个IntentFilter的完全匹配时,才会让该Intent请求通过测试

练习:测试系统的Action—Intent.ACTION_DIAL 用于打开系统的拨打电话的界面。
如:给某个人打电话:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);//打电话的动作
intent.setData(Uri.parse(“tel:123”));//具体的数据,打给123
startActivity(intent);
如:给10086发短信
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SENDTO);// 发送信息的动作
intent.putExtra(“sms_body”, “The SMS text”);
intent.setData(Uri.parse(“sms:10086”));// 具体的数据,发送给10086
startActivity(intent);

(3)Data 向Action属性提供操作的数据,Data属性接受一个Uri对象。
URI 通用资源标识符:在网络中或者本地如何找到一个唯一的资源的标识符
URL 统一资源定位符:把一个地址作为唯一的资源的标识符,
如:http://www.baidu.com(域名解析器解析域名会解析出ip地址和资源名)
网络资源:http://localhost:8080/Test/index.html
协议:规定传输数据的规则
URN 统一资源命名符:定义一个唯一的名字,比如说isbn号

android中一个Uri对象通常通过如下形式的字符串来表示:
scheme://host:port/path
协议://地址:端口号/资源路径
如:content://com.android.contacts/contacts/1
Activity配置时,使用设置其匹配的Data.
一般情况下Activty可以有多个action,多个category,但是只能有一个data.
并且配置data之前需要先有action.

<data android:scheme=""/>
scheme://...
<data android:scheme=""
      android:host=""/>
scheme://host...
<data android:scheme=""
      android:host=""
      android:port=""/>
scheme://host:port...
<data android:scheme=""
      android:host=""
      android:path=""/>
scheme://host/path
<data android:scheme=""
      android:host=""
      android:port=""
      android:path=""/>   
scheme://host:port/path

(4)Type 为Action属性提供操作的数据的数据类型,格式为xxx/xxx
Activity配置时,使用设置可以匹配的Type
请求的Intent必须设置Type,才能匹配到该Activity.

     MIME:全称Multipurpose Internet Mail Extensions,多功能Internet 邮件扩充服务。它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
    在Android中通过文件的MIME类型来判断有哪些应用程序可以处理这些文件,并使用其中的某一个应用程序(如果有多个可选的应用程序,则用户必须指定一个)处理之。

注意:
      1)Intent中不能单独设置Type,需要结合Action和Data一起使用
      2)默认Data与Type不可以同时使用,后设置的属性会覆盖前设置的属性
     可以使用setDataAndType()同时设置两个属性

(5) Extra
使用Bundle对象在Intent中以键值对的形式保存数据,
用来在多个组件之间传递数据
调用: putExtra(key,value)方法向Intent的默认bundle中添加数据
putExtras(Bundle)方法用来为Intent设置新的Bundle
getXXXExtra(key)方法获取数据,部分类型可以设置默认值
getExtras()方法获取Intent中的Bundle对象

(6)Flag 旗标
setFlag(),getFlag()

AndroidManifest.xml

  <activity android:name="com.xspacing.intent.SecondActivity" >
            <intent-filter>
                <action android:name="com.xspacing.intent.action.briup" />
                <action android:name="com.xspacing.intent.action.smile" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="com.xspacing.intent.category.briup" />

                <!-- host:ip地址     path:路径      port:端口号   scheme:协议   mimeType 数据 类型-->
                <data
                    android:host="127.0.0.1"   
                    android:path="/ss"
                    android:port="8080"
                    android:scheme="www"
                    android:mimeType="aa/bb" />
            </intent-filter>
        </activity>
        Intent intent = new Intent();
        intent.setAction("com.xspacing.intent.action.briup");
        intent.addCategory("com.xspacing.intent.category.briup");
        // intent.setAction("com.xspacing.intent.action.smile");
        // Type不能跟data分开设置,前一个会把后一个覆盖
        // intent.setType("aa/bb");
        // intent.setData(Uri.parse("www://127.0.0.1:8080/ss"));
        intent.setDataAndType(Uri.parse("www://127.0.0.1:8080/ss"), "aa/bb");
        startActivity(intent);
### IntentIntentFilterAndroid开发中的作用和使用方法 #### 1. Intent的作用 IntentAndroid用于描述一个操作的抽象描述,主要用于启动 Activity、Service 或发送广播。它通过封装组件名称、动作(action)、数据(data)、类别(category)、额外信息(extras)等属性来实现组件间的通信[^4]。 #### 2. IntentFilter的作用 IntentFilterAndroid用于过滤 Intent 的机制,通常定义在 AndroidManifest.xml 文件中或通过代码动态创建。它通过指定 action、data 和 category 来匹配特定的 Intent,从而决定某个组件是否可以响应该 Intent[^5]。 --- ### 使用方法 #### 2.1 Intent的创建与设置 Intent 可以通过以下方式创建并设置其属性: - **设置 Action**:通过 `setAction()` 方法指定 Intent 的动作。 - **设置 Data**:通过 `setData()` 或 `setDataAndType()` 方法指定 Intent 的数据及其 MIME 类型。 - **设置 Category**:通过 `addCategory()` 方法添加分类。 - **跳转**:通过 `startActivity()` 或 `startService()` 等方法启动目标组件。 示例代码如下: ```java // 创建 Intent Intent intent = new Intent(); // 设置 Action intent.setAction("android.intent.action.VIEW"); // 设置 Data 和 Type Uri uri = Uri.parse("http://www.example.com"); intent.setDataAndType(uri, "text/html"); // 添加 Category intent.addCategory("android.intent.category.DEFAULT"); // 启动 Activity startActivity(intent); ``` #### 2.2 IntentFilter的定义 IntentFilter 可以通过 XML 配置或 Java 代码动态创建。以下是两种方式的示例: - **XML 配置** 在 AndroidManifest.xml 中定义 IntentFilter: ```xml <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> ``` - **Java 代码** 在 Java 代码中动态创建 IntentFilter: ```java IntentFilter filter = new IntentFilter(); filter.addAction("android.intent.action.MAIN"); filter.addCategory("android.intent.category.LAUNCHER"); ``` --- ### 匹配规则 IntentIntentFilter 的匹配遵循以下规则: 1. **Action 匹配**:Intent 的 action 必须与 IntentFilter 中定义的一个 action 完全匹配[^1]。 2. **Data 匹配**:Intent 的 data 必须符合 IntentFilter 中定义的数据类型和 URI 格式[^2]。 3. **Category 匹配**:Intent 的所有 category 必须都能在 IntentFilter 中找到对应的 category[^3]。 例如,以下 IntentFilter 定义了一个支持图片类型的 Activity: ```xml <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> ``` 如果一个 Intent 的 action 为 `android.intent.action.VIEW`,category 为 `android.intent.category.DEFAULT`,data 为 `content://media/external/images/media/123`,则该 Intent 会匹配上述 IntentFilter[^2]。 --- ### 外部程序隐式启动 Activity 为了让外部程序能够隐式启动某个 Activity,必须将该 Activity 的 `exported` 属性设置为 `true`[^3]。例如: ```xml <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> ``` --- ### 示例总结 通过 IntentIntentFilterAndroid 应用可以实现组件间的灵活通信。Intent 负责描述操作,而 IntentFilter 负责筛选符合条件的 Intent。两者结合使用,可以实现显式调用和隐式调用的功能。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值