Android开发-Uri路径

8.1、概述

通用资源标志符(Universal Resource Identifier, 简称"URI")

Uri代表要操作的数据,Android上可用的每种资源 (图像、视频片段、网页等) 都可以用Uri来表示。

从概念上来讲,URI包括URL。

Uri通常有三种形式

  1. <scheme>://<authority><absolute path>?<query>#<fragment>

    主要用于访问本地资源,scheme可用content,file替代

  2. <scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]

    主要用于访问网络资源,scheme通常为http

  3. <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.comwww.google.com.google.comdeveloper.google.com匹配

android:port

URI 授权方的端口部分。仅当同时为过滤器指定了 schemehost 属性时,此属性才有意义。

android:path android:pathPrefix android:pathPattern

URI 的路径部分,必须以 / 开头。

path 属性指定与 Intent 对象中的完整路径匹配的完整路径。

pathPrefix 属性指定只与 Intent 对象中的路径的初始部分匹配的部分路径。

pathPattern 属性指定与 Intent 对象中的完整路径匹配的完整路径,但它可以包含以下通配符:

  • 星号(“*”)匹配出现零次到多次的紧邻前面的字符的一个序列。

  • 后跟星号的句点(“.*”)匹配零个或多个字符的任意序列。

由于在从 XML 读取字符串时(在将其解析为模式之前)将“\”用作转义字符,因此您需要进行双重转义:例如,字面量“*”将编写为“\\*”,字面量“\”将编写为“\\\\”。这基本上与采用 Java 代码构造字符串时需要编写的内容一样。

android:mimeType

MIME 媒体类型,如 image/jpegaudio/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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值