前言
前几天在做跳转到系统应用通知页的时候,用到了Intent的多种用法,故现在来总结一下。
1.Intent简介
Intent可以启动Activity,Service或者配合广播使用。在SDK中给出了Intent作用的表现形式为:
· 通过
Context.startActivity()
或者
Activity.startActivityForResult()
启动一个Activity;
Context.startActivity()
或者
Activity.startActivityForResult()
启动一个Activity;
·
通过
Context.startService()
启动一个服务,或者通过
Context.bindService()
和后台服务交互;
·
通过广播方法发给broadcast receivers
2.Intent的参数
a.Component
目标组件的名字。Intent可通过构造,
setClass()
,
setClassName()
,
setComponent()
来启动,其中
setClassName()
内部也是调用的
setComponent()
。在显式跳转中可能会用到。
setClass()
,
setClassName()
,
setComponent()
来启动,其中
setClassName()
内部也是调用的
setComponent()
。在显式跳转中可能会用到。
b.Action
应用于隐式跳转。
是一个可以指明目标组件行为的字符串。action很大程度上决定了category和data中应传入的信息;您也可以在自己的应用程序组件中指定action,以便让其他应用程序启动自己的组件。对应action中字符串,不建议使用硬编码的形式,而应在所属组件的类中设置为常量。也可以自定义Action:
是一个可以指明目标组件行为的字符串。action很大程度上决定了category和data中应传入的信息;您也可以在自己的应用程序组件中指定action,以便让其他应用程序启动自己的组件。对应action中字符串,不建议使用硬编码的形式,而应在所属组件的类中设置为常量。也可以自定义Action:
<intent-filter>
<action
android:name
=
“自定义Action”
/>
<category
android:name
=
“android.intent.category.DEFAULT”
/>
</intent-filter>
c.data
data属性解析:android:scheme、android:host、android:port、android:path、android:mimeType
data的前四个属性构成了URI的组成部分,mimeType设置了数据的类型。
android:scheme 匹配url中的前缀,除了“http”、“https”、“tel”…之外,我们可以定义自己的前缀
android:host 匹配url中的主机名部分,如“google.com”,如果定义为“*”则表示任意主机名
android:port 匹配url中的端口
android:path 匹配url中的路径
mimeType则是data的类型,如
”image/png”、”image/jpeg”等
您可以调用
setData()
方法设置URI,调用
setType()
方法设置MIME类型,或调用
setDataAndType()
方法同时设置URI和MIME类型。
请注意:如果您需要同时设置URI和MIME类型,只能调用
setDataAndType()
方法,而不能分别调用
setData()
和
setType()
,因为调用setData()时会首先将
setType()
中的内容置空,反之亦然
d.category
是一个字符串,表示目标组件的附加信息,大部分intent不需要category。
系统在使用隐式Intent的时候,会自动帮我们添加上“android.intent.category.default”
e.Extras
Intent可以携带信息,通过键值对的方式进行存储,
可以使用
putExtra()
方法将键值对信息传入,也可以将键值对信息放在Bundle对象中,再通过将Bundle对象传入
putExtra()
中。
可以使用
putExtra()
方法将键值对信息传入,也可以将键值对信息放在Bundle对象中,再通过将Bundle对象传入
putExtra()
中。
f.Flags
flag可以指导系统以何种方式启动一个activity、是否将启动的activity放在该应用的任务栈中,等等。
3.intent的启动方式
a.显式跳转
显式跳转没有什么可说的,指的是在Intent内部直接声明要启动的目标所对应的class。
b.隐式跳转
需要参考intent的action,category和data属性。
需优先考虑action是否匹配
intent filter可定义零到多个action标签:
<intent-filter> <action android:name=
“android.intent.action.EDIT”
/> <action android:name=
“android.intent.action.VIEW”
/>
…
</intent-filter>
intent需要匹配上其中一个action标签。如果intent-filter中没有action标签,则intent无需action就能匹配。
再看category:
intent filter可定义零到多个category标签:
<intent-filter> <category android:name=
“android.intent.category.DEFAULT”
/> <category android:name=
“android.intent.category.BROWSABLE”
/>
…
</intent-filter>
intent中的定义的每一个category都需要匹配上intent-filter中的category标签,反之不成立(intent-filter中的category标签可能比intent中的定义的category多)。所以无论intent-filter中是否定义了category标签,未添加category的intent总能匹配上该intent-filter。
请注意:通过
startActivity()
或
startActivityForResult()
方法隐式启动的intent中,将自动被添加一个CATEGORY_DEFAULT的category,所以若您希望自己的activity能够被隐式启动,则需要在intent-filter中添加一个android.intent.category.DEFAULT的category标签。
再看data:
对data的uri来说,可以分成四个部分
scheme, host, port 和 path,每一部分在data标签中都不是必须定义的,但存在一个线性依赖:scheme未定义,忽略host;host未定义,忽略port;port未定义,忽略path。
scheme, host, port 和 path,每一部分在data标签中都不是必须定义的,但存在一个线性依赖:scheme未定义,忽略host;host未定义,忽略port;port未定义,忽略path。
在intent中添加的data只需要匹配一部分intent-filter中的data(URI匹配):
* 若filter只定义了scheme,则intent的data定义的URI中只要包含了相同的scheme,就能匹配;
* 若filter只定义了scheme和host,则intent的data定义的URI中只要包含了相同的scheme和host,就能匹配;
* 若filter只定义了scheme、host和port,则intent的data定义的URI中只要包含了相同的scheme、host和port,就能匹配
对data的
mimeType来说,有如下四种情况。
mimeType来说,有如下四种情况。
1.如果intent-filter中未指定data,则未添加data的intent可以匹配;
2.如果intent-filter中指定了URI,但未指定mimeType,则按照上一段的规则匹配(intent中也应未指定mimeType);
3.如果intent-filter中指定了mimeType,而未指定URI,则可以匹配intent中指定了相同mimeType,而未指定URI的组件;
4.如果intent-filter中同时指定了mimeType和URI,则 mimeType匹配上intent-filter中的一个即可匹配,URI匹配规则同上。
最后再上一段跳转到应用通知开启界面的代码:
Intent intent =
new
Intent();
try
{
if
(Build.VERSION.
SDK_INT
>= Build.VERSION_CODES.
LOLLIPOP
) {
intent.setAction(
“android.settings.APP_NOTIFICATION_SETTINGS”
);
intent.putExtra(
“android.provider.extra.APP_PACKAGE”
, getPackageName());
intent.putExtra(
“app_package”
, getPackageName());
intent.putExtra(
“app_uid”
, getApplicationInfo().
uid
);
if
(!PackageManagerUtils.
isIntentAvailable
(getContext(), intent)) {
intent.setAction(Settings.
ACTION_APPLICATION_DETAILS_SETTINGS
);
intent.setData(Uri.
fromParts
(
“package”
, getPackageName(),
null
));
}
}
else
{
intent.setAction(Settings.
ACTION_APPLICATION_DETAILS_SETTINGS
);
intent.setData(Uri.
fromParts
(
“package”
, getPackageName(),
null
));
}
intent.setFlags(Intent.
FLAG_ACTIVITY_NEW_TASK
);
startActivity(intent);
}
catch
(Exception e) {
e.printStackTrace();
}
SDK大于21,可进入到应用通知开关页面,小于21只能进入应用详情页面
版权声明:本文为weixin_41003506原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。