IntentFilter

转载请注明链接: https://blog.csdn.net/feather_wch/article/details/50485409

IntentFilter

版本号: 2019/04/11-1(16:20)


简介

1、IntentFilter是什么?有什么用?

  1. 用于过滤Intent,找到完全匹配IntentFilter的Intent
  2. 利用IntentFilter能进行不同应用间的跳转和应用内页面的跳转

2、Activity可以有几个IntentFilter?

  1. 一个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所对应的类

  1. 有多种实现的方式
  2. 本质都是设置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的隐式调用注意点

  1. 隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息
  2. IntentFilter过滤信息有actioncategorydata-三个类别完全匹配时才算匹配成功
  3. Activity可以有多个intent-filterintent只要匹配任何一组就算匹配成功。
<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. 方法1: try-catch捕获异常ActivityNotFoundException
  2. 方法2: 利用intent的resolveActivity()方法进行判断

11、隐式调用Activity不存在时的处理办法

  1. IntentresolveActivity():找不到匹配Activity会返回null
  2. PackageManagerresolveActivity()——返回最佳匹配的Activity信息
  3. PackageManagerqueryIntentActivity()会返回所有成功匹配的Activity信息
  4. queryIntentActivity()的第二个参数需要使用MATCH_DEFAULT_ONLY标志位去仅仅匹配在catagory中声明了android.intent.category.DEFAULTActivity(这样只要有匹配的Activity,就会保证startActivity一定成功。因为没有指明DEFAULTActivity是不能接受隐式Intent的)
  5. 对于ServiceBroadcastReceiver, PackageManager提供了类似方法去获取成功匹配的组件信息

12、ServiceBroadcastReceiver中的Intent-filter和Activity的设置方式相同,系统建议对于Service使用显式方式调用

action

1、Action是什么?

  1. 定义了意图-Intent行为-action
  2. android中是一个字符串
  3. 可以自定义action也可以使用系统预定义的action

2、Action的作用是什么?

  1. 用于区分用户的不同行为
    1. 是要找到应用的入口-android.intent.action.MAIN
    2. 还是要展示数据给用户-android.intent.action.VIEW
    3. 是打电话- android.intent.action.DIAL
    4. 还是直接发短信-android.intent.action.SEND

3、Intent如何设置action?

setAction()

4、Intent中不显式设置Action时会出现什么结果?

  1. 会自动设置Aciont为ACTION_VIEW
if (intent.mAction == null) {
    // By default, if no action is specified, then use VIEW.
    intent.mAction = ACTION_VIEW;
}

5、action的匹配规则

  1. action的匹配需要字符串完全一样, 区分大小写
  2. 具有多个action时,只要一个匹配就算做匹配成功,如果Intent中没有指定action则匹配失败
    • 举例:Intent设置了action,该action只要能在intent-filter中找到任何一个符合的,就表示匹配成功。

6、activity的预定义Action

activity预定义了很多Action,常用的如下:

常量名称常量值意义
ACTION_MAINandroid.intent.action.MAIN应用程序入口
ACTION_VIEWandroid.intent.action.VIEW显示数据给用户
ACTION_ATTACH_DATAandroid.intent.action.ATTACH_DATA指明附加信息给其他地方的一些数据
ACTION_EDITandroid.intent.action.EDIT显示可编辑的数据
ACTION_PICKandroid.intent.action.PICK选择数据
ACTION_CHOOSERandroid.intent.action.CHOOSER显示一个Activity选择器
ACTION_GET_CONTENTandroid.intent.action.GET_CONTENT获得内容
ACTION_DIALandroid.intent.action.GET_CONTENT显示打电话面板
ACITON_CALLandroid.intent.action.DIAL直接打电话
ACTION_SENDandroid.intent.action.SEND直接发短信
ACTION_SENDTOandroid.intent.action.SENDTO选择发短信
ACTION_ANSWERandroid.intent.action.ANSWER应答电话
ACTION_INSERTandroid.intent.action.INSERT插入数据
ACTION_DELETEandroid.intent.action.DELETE删除数据
ACTION_RUNandroid.intent.action.RUN运行数据
ACTION_SYNCandroid.intent.action.SYNC同步数据
ACTION_PICK_ACTIVITYandroid.intent.action.PICK_ACTIVITY选择Activity
ACTION_SEARCHandroid.intent.action.SEARCH搜索
ACTION_WEB_SEARCHandroid.intent.action.WEB_SEARCHWeb搜索
ACTION_FACTORY_TESTandroid.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是什么?

  1. 类型,android中是一个字符串
  2. 有系统预定义category和自定义的category

2、category的匹配规则

  1. intent有多个category,这些category都必须在intent-filter中找到一个相同的category
  2. intent中没有category时, 系统会自动加上category: “android.intent.category.DEFAULT”
  3. 想要接收到隐式调用,需要在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的匹配规则

  1. 规则与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的组成部分

字段意义
MineTypeMineType指的是媒体类型:例如imgage/jpeg,auto/mpeg4和viedo/*等,可以表示图片、文本、视频等不同的媒体格式
URl可配置更多信息,类似于url。
SchemeURI的模式,如http、file、content。如果没有指定Scheme.那么整个URI无效。默认值为content 和 file。
HostURI的主机名,如www.baidu.com
PortURI中的端口号,如80
path用来匹配完整的路径,如:http://example.com/blog/abc.html,这里将 path 设置为 /blog/abc.html 才能够进行匹配
pathPrefix用来匹配路径的开头部分,拿上面的 Uri 来说,这里将 pathPrefix 设置为 /blog 就能进行匹配了
pathPattern用表达式来匹配整个路径

13、匹配符号的讲解

  1. *用来匹配0次或更多,例如:a可以匹配a、aa、aaa
  2. .可以匹配任意字符。例如:.可以匹配a、b、c等等
  3. 例如:.*html可以匹配 “abchtml”、“chtml”,“html”,“sdf.html”

14、data的过滤实例:

<data android:mimeType="image/*" />
intent.setDataAndType(Uri.parse("file://abc"), "image/png");

1.IntentmimeType必须为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是什么?

  1. android中的scheme是一种页面内跳转协议,
  2. 能够方便地跳转到其他页面
  3. 如:根据服务器返回的信息,跳转到目标页面。
  4. 如:可以通过通知消息栏,去点击跳转到需要的页面
  5. 可以通过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(必须要有VIEWDEFAULT)

<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默认值的区别

  1. action如何没有显式设置,默认为android.intent.action.VIEW
  2. category无论有没有设置,都会额外增加一个android.intent.category.DEFAULT

2、action和category的区别和联系

actioncategory
  1. action

参考资料

  1. android-Scheme与网页跳转原生的三种方式
  2. [Intent,Action,大全
  3. android intent和intent action大全
  4. 【扩展资料】显式\隐式Intent跳转Activity\系统应用
  5. 【Android(一) activity、intent知识和总结】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值