8.1、概述
通用资源标志符(Universal Resource Identifier, 简称"URI")
Uri代表要操作的数据,Android上可用的每种资源 (图像、视频片段、网页等) 都可以用Uri来表示。
从概念上来讲,URI包括URL。
Uri通常有三种形式
-
<scheme>://<authority><absolute path>?<query>#<fragment>
主要用于访问本地资源,scheme可用content,file替代
-
<scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
主要用于访问网络资源,scheme通常为http
-
<scheme>:<scheme-specific-part> #fragment
用于启动系统应用程序scheme主要有以下几种:
tel://电话服务 Intent.ACTION_DIAL smsto://短信服务 Intent.ACTION_SEND mailto://邮件服务 Intent.ACTION_SEND
8.2、data标签
语法:
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="string" />
向 Intent-filter
添加数据规范。
该规范可以是只有数据类型(mimeType
属性),可以是只有 URI,也可以是既有数据类型又有 URI。
<scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
用于指定网址格式的以下属性是可选的,但也相互依赖:
-
如果没有为
Intent
过滤器指定scheme
,则系统会忽略其他所有 URI 属性。 -
如果没有为过滤器指定
host
,则系统会忽略port
属性以及所有路径属性。
同一 <intent-filter>
元素中包含的所有 <data>
元素都对同一过滤器起作用。
<intent-filter . . . >
<data android:scheme="something" android:host="project.example.com" />
. . .
<!--
<data android:scheme="something" />
<data android:host="project.example.com" />
. . .
两种格式效果是一样的
-->
</intent-filter>
属性:
android:scheme
URI 的架构部分。这是指定 URI 时最基本的属性;必须至少为过滤器设置一个 scheme
属性,否则其他 URI 属性都没有意义。
android:host
URI 授权方的主机部分。
只有当为过滤器指定了 scheme
属性,此属性才有意义。
如需匹配多个子网域,请使用星号 (*
) 匹配主机中的零个或多个字符。
例如, *.google.com
与 www.google.com
、.google.com
和 developer.google.com
匹配
android:port
URI 授权方的端口部分。仅当同时为过滤器指定了 scheme
和 host
属性时,此属性才有意义。
android:path
android:pathPrefix
android:pathPattern
URI 的路径部分,必须以 / 开头。
path
属性指定与 Intent 对象中的完整路径匹配的完整路径。
pathPrefix
属性指定只与 Intent 对象中的路径的初始部分匹配的部分路径。
pathPattern
属性指定与 Intent 对象中的完整路径匹配的完整路径,但它可以包含以下通配符:
-
星号(“
*
”)匹配出现零次到多次的紧邻前面的字符的一个序列。 -
后跟星号的句点(“
.*
”)匹配零个或多个字符的任意序列。
由于在从 XML 读取字符串时(在将其解析为模式之前)将“\
”用作转义字符,因此您需要进行双重转义:例如,字面量“*
”将编写为“\\*
”,字面量“\
”将编写为“\\\\
”。这基本上与采用 Java 代码构造字符串时需要编写的内容一样。
android:mimeType
MIME 媒体类型,如 image/jpeg
或 audio/mpeg4-generic
。 子类型可以是星号通配符 (*
),以指示任何子类型都匹配。
Intent 过滤器经常会声明仅包含 android:mimeType
属性的 <data>
。
Android 框架中的 MIME 类型匹配区分大小写,这一点与正式的 RFC MIME 类型不同。
因此,您应始终使用小写字母指定 MIME 类型。
8.3、端口
编写隐式跳转按钮的主页面
findViewById(R.id.btn_port).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent("myaction", Uri.parse("mosang://portsend:8088")));
//主页面隐式跳转配置端口号
}
});
若存在两个跳转页面,且都不设置端口号
<activity android:name=".port1" android:exported="true">
<intent-filter>
<action android:name="myaction"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:scheme="mosang"
android:host="portsend"
android:path="/port"/>
<!--android:port:8090-->
</intent-filter>
</activity>
<activity android:name=".port2" android:exported="true">
<intent-filter>
<action android:name="myaction"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="mosang"
android:host="portsend"
android:path="/port"/>
<!--android:port:8088-->
</intent-filter>
</activity>
发现出现子弹窗供用户选择,选择后仍能跳转到指定页面
-
port不具备决定性,在host与scheme被选定后,依然作为一个候选项
-
同一主机的host和scheme相同,可以通过设置port来区分不同的应用进程
-
将两个进程分别设置不同的端口号,则可唯一指定一个应用进程
8.4、数据显示
抓取Intent对象中的内容
Intent it=getIntent();
Uri uri=it.getData();
((TextView)findViewById(R.id.tv_port1)).setText(
"this is port 1\n"+
"action: "+it.getAction()+"\n"+
"scheme: "+uri.getScheme()+"\n"+
"host: "+uri.getHost()+"\n"+
"port: "+uri.getPort()+"\n"+
"subpath: "+uri.getPath()+"\n"+
"para: "+uri.getQueryParameter("msg")
);
//Url:
//mosang://portsend:8090/class?msg=1111
intent包含显式匹配和隐式匹配的所有内容,显式匹配优先
清单文件中对应项的配置:
<data
android:scheme="mosang"
android:host="portsend"
android:path="/class"
android:port="8090"
/>
8.5、代码优化
代码显示:
当有冗余代码时,我们可以把常用代码封装
public class Util {
public static String info(TextView tv, Intent it) {
Uri uri=it.getData();
String str="";
if(tv.getId()==R.id.tv_port1)
str="this is port1";
else if(tv.getId()==R.id.tv_port2)
str="this is port2";
if(uri!=null &&it.getAction()!=null)//判断是否为隐式跳转
str=str+"\n"+
"action: "+it.getAction()+"\n"+
"scheme: "+uri.getScheme()+"\n"+
"host: "+uri.getHost()+"\n"+
"port: "+uri.getPort()+"\n"+
"subpath: "+uri.getPath()+"\n"+
"para: "+uri.getQueryParameter("msg");
return str;
}
}
注:
只有在隐式跳转时,才能提取出Intent内容
显式跳转会提示空指针异常,因为没有配置Intent内容
监听器对象
每当设置一个按钮事件时,都要new一个监听器对象
使用一个同一的监听器对象,通过switch来判断是那个对象发出的请求
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()){
//显式跳转
case R.id.btn_explicit:{
startActivity(new Intent(AMain.this,explicit_check.class));
break;
}
//隐式跳转
case R.id.btn_implicit:{
startActivity(new Intent("Implicit_Action", Uri.parse("mosang://implicit.check")));
break;
}
//间接跳转
case R.id.btn_indirect:{
startActivity(new Intent("Indirect_Action",Uri.parse("mosang://indirect.check/redirect")));
break;
}
}
}
};
findViewById(R.id.btn_explicit).setOnClickListener(listener);
findViewById(R.id.btn_implicit).setOnClickListener(listener);
findViewById(R.id.btn_indirect).setOnClickListener(listener);