转载请注明链接: https://blog.csdn.net/feather_wch/article/details/50485409
IntentFilter
版本号: 2019/04/11-1(16:20)
文章目录
简介
1、IntentFilter是什么?有什么用?
- 用于过滤
Intent
,找到完全匹配IntentFilter的Intent- 利用IntentFilter能进行不同应用间的跳转和应用内页面的跳转
2、Activity可以有几个IntentFilter?
- 一个Activity可以有多个IntentFilter
3、具有多个IntentFilter的Activity如何匹配?
只要一个IntentFilter匹配即可
4、为什么允许一个Activity有多个IntentFilter?
可能会出现:一个app既可以用于打开pdf,又可以作为多媒体播放器进行视频播放。这就需要多个IntentFilter进行匹配。
匹配机制(18)
IntentFilter与Activity
1、Activity具有显式Intent和隐式Intent两种Intent
其中
隐式Intent
就需要借助IntentFilter
进行匹配。
显式Intent(Component)
2、显式Intent就是指直接指定需要打开的Activity所对应的类
- 有多种实现的方式
- 本质都是设置
Component
来指定目标
3、构造方法中设置Component
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
4、setComponent()方法:
// 写法1
ComponentName componentName = new ComponentName(MainActivity.this, SecondActivity.class);
// 写法2
componentName = new ComponentName(MainActivity.this, "com.iptvclient.android.cellc.SecondActivity");
// 写法3
componentName = new ComponentName(MainActivity.this.getPackageName(), "com.iptvclient.android.cellc.SecondActivity");
Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
5、setClass/setClassName
Intent intent = new Intent();
// 1. setClass
intent.setClass(MainActivity.this, SecondActivity.class);
// 2. setClassName1
intent.setClassName(MainActivity.this, "com.iptvclient.android.cellc.SecondActivity");
// 3. setClassName2
intent.setClassName(MainActivity.this.getPackageName(), "com.iptvclient.android.cellc.SecondActivity");
startActivity(intent);
隐式Intent
6、隐式Intent就是通过IntentFilter进行过滤匹配,找到符合要求的目标。
7、Activity的隐式Intent使用方法:
Intent intent = new Intent();
intent.setAction("com.example.action");
intent.addCategory("com.example.category");
intent.setData(Uri.parse("scheme://www.baidu.com"))
startActivity(intent);
8、Intent的隐式调用注意点
隐式调用
需要Intent
能够匹配目标组件的IntentFilter
中所设置的过滤信息IntentFilter
过滤信息有action
、category
、data
-三个类别完全匹配时才算匹配成功Activity
可以有多个intent-filter
,intent
只要匹配任何一组就算匹配成功。
<activity
android:name="com.zte.iptvclient.android.iptvclient.activity.InitActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:configChanges="orientation|locale|fontScale|keyboardHidden"
android:screenOrientation="unspecified"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="127.0.0.1"
android:scheme="zteottptcl2cc82f66de86" />
</intent-filter>
</activity>
9、隐式Intent提前检测能否找到合适的Activity,避免找不到抛出异常。
Intent intent = new Intent();
intent.setAction("com.example.action");
intent.addCategory("com.example.category");
intent.setData(Uri.parse("scheme://www.baidu.com"))
ComponentName componentName = intent.resolveActivity(getPackageManager());
if(componentName != null){
// 找到了目标Activity
startActivity(intent);
}
10、如何解决隐式Intent找不到目标Activity抛出异常的问题?
- 方法1: try-catch捕获异常
ActivityNotFoundException
- 方法2: 利用intent的resolveActivity()方法进行判断
11、隐式调用Activity
不存在时的处理办法
Intent
的resolveActivity()
:找不到匹配Activity
会返回null
PackageManager
的resolveActivity()
——返回最佳匹配的Activity
信息PackageManager
的queryIntentActivity()
会返回所有成功匹配的Activity
信息queryIntentActivity()
的第二个参数需要使用MATCH_DEFAULT_ONLY
标志位去仅仅匹配在catagory
中声明了android.intent.category.DEFAULT
的Activity
(这样只要有匹配的Activity,就会保证startActivity
一定成功。因为没有指明DEFAULT
的Activity
是不能接受隐式Intent
的)- 对于
Service
和BroadcastReceiver
,PackageManager
提供了类似方法去获取成功匹配的组件信息
12、Service
和BroadcastReceiver
中的Intent-filter
和Activity的设置方式相同,系统建议对于Service使用显式方式调用
action
1、Action是什么?
- 定义了
意图-Intent
的行为-action
- android中是一个字符串
- 可以自定义action也可以使用系统预定义的action
2、Action的作用是什么?
- 用于区分用户的不同行为
- 是要找到应用的入口-
android.intent.action.MAIN
- 还是要展示数据给用户-
android.intent.action.VIEW
- 是打电话-
android.intent.action.DIAL
- 还是直接发短信-
android.intent.action.SEND
3、Intent如何设置action?
setAction()
4、Intent中不显式设置Action时会出现什么结果?
- 会自动设置
Aciont为ACTION_VIEW
if (intent.mAction == null) {
// By default, if no action is specified, then use VIEW.
intent.mAction = ACTION_VIEW;
}
5、action的匹配规则
- action的匹配
需要字符串完全一样
,区分大小写
- 具有多个action时,只要一个匹配就算做匹配成功,如果
Intent中没有指定action则匹配失败
- 举例:Intent设置了action,该action只要能在intent-filter中找到任何一个符合的,就表示匹配成功。
6、activity的预定义Action
activity预定义了很多Action,常用的如下:
常量名称 | 常量值 | 意义 |
---|---|---|
ACTION_MAIN | android.intent.action.MAIN | 应用程序入口 |
ACTION_VIEW | android.intent.action.VIEW | 显示数据给用户 |
ACTION_ATTACH_DATA | android.intent.action.ATTACH_DATA | 指明附加信息给其他地方的一些数据 |
ACTION_EDIT | android.intent.action.EDIT | 显示可编辑的数据 |
ACTION_PICK | android.intent.action.PICK | 选择数据 |
ACTION_CHOOSER | android.intent.action.CHOOSER | 显示一个Activity选择器 |
ACTION_GET_CONTENT | android.intent.action.GET_CONTENT | 获得内容 |
ACTION_DIAL | android.intent.action.GET_CONTENT | 显示打电话面板 |
ACITON_CALL | android.intent.action.DIAL | 直接打电话 |
ACTION_SEND | android.intent.action.SEND | 直接发短信 |
ACTION_SENDTO | android.intent.action.SENDTO | 选择发短信 |
ACTION_ANSWER | android.intent.action.ANSWER | 应答电话 |
ACTION_INSERT | android.intent.action.INSERT | 插入数据 |
ACTION_DELETE | android.intent.action.DELETE | 删除数据 |
ACTION_RUN | android.intent.action.RUN | 运行数据 |
ACTION_SYNC | android.intent.action.SYNC | 同步数据 |
ACTION_PICK_ACTIVITY | android.intent.action.PICK_ACTIVITY | 选择Activity |
ACTION_SEARCH | android.intent.action.SEARCH | 搜索 |
ACTION_WEB_SEARCH | android.intent.action.WEB_SEARCH | Web搜索 |
ACTION_FACTORY_TEST | android.intent.action.FACTORY_TEST | 工厂测试入口点 |
7、broadcast的预定义Action
AndroidManifest中的
receiver
标签中使用
常量名称 | 意义 |
---|---|
ACTION_TIME_TICK | 系统时间每过一分钟发出的广播 |
ACTION_TIME_CHANGED | 系统时间通过设置发生了变化 |
ACTION_TIMEZONE_CHANGED | 时区改变 |
ACTION_BOOT_COMPLETED | 系统启动完毕 |
ACTION_PACKAGE_ADDED | 新的应用程序apk包安装完毕 |
ACTION_PACKAGE_CHANGED | 现有应用程序apk包改变 |
ACTION_PACKAGE_REMOVED | 现有应用程序apk包被删除 |
ACTION_UID_REMOVED | 用户id被删除 |
category
1、category是什么?
类型
,android中是一个字符串- 有系统预定义category和自定义的category
2、category的匹配规则
- intent有多个category,这些category都必须在intent-filter中找到一个相同的category
intent
中没有category
时, 系统会自动加上category:“android.intent.category.DEFAULT”
- 想要接收到
隐式调用
,需要在intent-filter中指定android.intent.category.DEFAULT
- 否则会因为Intent中的DEFAULT category在IntentFilter中匹配不到,导致失败。
3、为什么隐式调用找不到在AndroidManifest.xml中定义的Activity?
可能是intent-filter中没有指定
android.intent.category.DEFAULT
4、category的预定义常量
常量名称 | 意义 |
---|---|
CATEGORY_BROWSABLE | 目标Activity能通过在网页浏览器中点击链接而激活(比如,点击浏览器中的图片链接) |
CATEGORY_GADGET | 表示目标Activity可以被内嵌到其他Activity当中 |
CATEGORY_HOME | 目标Activity是HOME Activity,即手机开机启动后显示的Activity,或按下HOME键后显示的Activity |
CATEGORY_LAUNCHER | 表示目标Activity是应用程序中最优先被执行的Activity |
CATEGORY_PREFERENCE | 表示目标Activity是一个偏爱设置的Activity |
5、App的入口Activity需要设置的Intent-Filter
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER">
共同作用表示为一个
入口Activity
并且会出现在系统的应用列表中
data
10、data的组成
由两部分组成:MineType和URI
11、data的匹配规则
- 规则与
action
类似:如果定义了data
,则Intent
中必须定义可匹配的data
<data
android:mimeType="string"
android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"/>
12、data的组成部分
字段 | 意义 |
---|---|
MineType | MineType指的是媒体类型:例如imgage/jpeg,auto/mpeg4和viedo/*等,可以表示图片、文本、视频等不同的媒体格式 |
URl | 可配置更多信息,类似于url。 |
Scheme | URI的模式,如http、file、content。如果没有指定Scheme.那么整个URI无效。默认值为content 和 file。 |
Host | URI的主机名,如www.baidu.com |
Port | URI中的端口号,如80 |
path | 用来匹配完整的路径,如:http://example.com/blog/abc.html,这里将 path 设置为 /blog/abc.html 才能够进行匹配 |
pathPrefix | 用来匹配路径的开头部分,拿上面的 Uri 来说,这里将 pathPrefix 设置为 /blog 就能进行匹配了 |
pathPattern | 用表达式来匹配整个路径 |
13、匹配符号的讲解
*
用来匹配0次或更多,例如:a
可以匹配a、aa、aaa
.
可以匹配任意字符。例如:.
可以匹配a、b、c等等
- 例如:
.*html
可以匹配 “abchtml”、“chtml”,“html”,“sdf.html”
14、data的过滤实例:
<data android:mimeType="image/*" />
intent.setDataAndType(Uri.parse("file://abc"), "image/png");
1.
Intent
中mimeType
必须为image/*
才能匹配
2.data
中没有指定URI
, 因此默认为content和file
——如果使用Uri.parse("http://abc")
就会报错
3.必须调用setDataAndType()
才能同时设置两个值,如果分开使用setData()和setType()
会导致前者的值被清除
<data android:mimeType="video/mpeg" android:scheme="http" .../>
<data android:mimeType="audio/mpeg" android:scheme="http" .../>
intent.setDataAndType(Uri.parse("http://abc"), "video/mpeg");
or
intent.setDataAndType(Uri.parse("http://abc"), "audio/mpeg");
<data android:scheme="file" android:host="www.baidu.com"/>
等效于
<data android:scheme="file"/>
<data android:host="www.baidu.com"/>
scheme(3)
1、scheme是什么?
- android中的scheme是一种页面内跳转协议,
- 能够方便地跳转到其他页面
- 如:根据服务器返回的信息,跳转到目标页面。
- 如:可以通过通知消息栏,去点击跳转到需要的页面
- 可以通过H5跳转到需要的页面。
协议格式
2、scheme的协议格式
url = "http://www.orangecpp.com:80/tucao?id=hello&name=lily";
url = protocol + authority(host + port) + path + query
协议protocol= http
域名authority= www.orangecpp.com:80
页面path= /tucao
参数query= id=hello&name=lily
authority = host + port
主机host= www.orangecpp.com
端口port= 80
使用
3、scheme的使用必须要配置intent-filter, 才能从其他app跳转到我们的app
1- data中设置scheme
<intent-filter>
<!--协议部分,随便设置
xl://goods:8888/goodsDetail?goodsId=10011002
-->
<data android:scheme="xl"
android:host="goods"
android:path="/goodsDetail"
android:port="8888"/>
</intent-filter>
2-设置几项必须的action和category
<intent-filter>
<data xxx/>
<!--下面这几行也必须得设置-->
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
实例
别的程序打开网络pdf时能选择我们的app
1、匹配scheme为http并且以.pdf
结尾的路径,让别的程序打开网络pdf时,用户能选择我们的程序
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:scheme="http"
android:pathPattern=".*//.pdf">
</data>
</intent-filter>
用户分享信息我们的应用能出现在选择框中
2、别人分享信息,如何让我们的应用出现在选择框中?
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data mimeType="*/*" />
</intent-filter>
获取到服务器配置的路径,跳转到目标页面。
3、获取到服务器配置的路径,跳转到该路径所对应的Activity
1-获取到服务器返回的路径,进行跳转(下面的uri就是服务端返回的)
Intent intent = new Intent();
intent.setData(Uri.parse("router://www.feather.com:1314/group/login"));
startActivity(intent);
2-目标Activity的intent-filter(必须要有
VIEW
和DEFAULT
)
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:scheme="router"
android:host="www.feather.com"
android:port="1314"
android:path="/group/login"/>
</intent-filter>
点击网页链接跳转到目标页面
4、点击网页上面的链接跳转到目标页面
1-点击网页上面的
router://www.feather.com:1314/group/login
2-Activity的intent-filter需要额外配置上BROWSABLE
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="router"
android:host="www.feather.com"
android:port="1314"
android:path="/group/login"/>
拓展
action和category
1、action和category默认值的区别
- action如何没有显式设置,默认为
android.intent.action.VIEW
- category无论有没有设置,都会额外增加一个
android.intent.category.DEFAULT
2、action和category的区别和联系
action | category | |
---|---|---|
- action