Android Uri
Uri在Android也是比较常见的一个工具类,最常用的场景是通过Uri可以访问特定的ContentProvider,其次通过Uri启动特定的界面。应用也可以添加定义处理一些Uri,也就是熟悉的DeepLink,详见Android DeepLink跳转。
1、Uri
什么是Uri?统一资源标识符(Uri)是一串字符串,用于标识抽象资源或物理资源。Android还提供了两个Uri工具类,见Uri工具:UriMatcher和ContentUris。
1.1、介绍
Uri是Uniform Resource Identifier的简称,中文叫统一资源标识符,在android.net包中的工具类。Java也有一个全是大写的URI类,在java.net包中,可以说Android的Uri借鉴了Java中的URI。
此外Android提供的这个Uri不会像Java中的URI会抛出异常,是一个“安静”的类,即使Uri错误最多也是没有任何动作效果可执行。或者得到的是无用的数据。
1.2、结构
RFC 2396中约定的Uri基本规范如下:
[scheme:][scheme-specific-part][#fragment]URI语法不需要特定于方案的部分具有所有URI中通用的任何常规结构或语义集。 但是,URI的子集确实共享一种通用语法,用于表示名称空间内的层次关系。 此“通用URI”语法包含四个主要部分的序列,于是可以进一步划分:
[scheme:][//authority][path][?query][#fragment]Authority部分又可以再细分为host和port,最终的Uri格式为:
[scheme:][//host:port][path][?query][#fragment]2、Uri方法
Uri类提供了一系列的get方法获取Uri中的各种字段数据,另外还提供若干种构造方法,用于创建Uri实例。
2.1、构造
①static Uri parse(String uriString):创建一个Uri来解析URI字符串,最常用的构造Uri方法。
②static Uri fromFile(File file):从文件创建一个Uri。 URI的格式为"file://",文件路径字符 '/'除外。示例:"file:///tmp/android.txt"。
③static Uri fromParts(String scheme,String ssp,String fragment):从给定的组件创建一个不透明的Uri。 对ssp进行编码,这意味着该方法不能用于创建分层URI。
④static Uri withAppendedPath(Uri baseUri, String pathSegment):将path字段附加到当前Uri来创建新的Uri。
⑤Builder buildUpon():从当前Uri复制属性构造一个新的Builder用来创建Uri对象。
⑥Uri normalizeScheme():将Uri中的字段全部转换为小写。
2.2、字段获取
①String getAuthority():获取URI的authority部分。
②boolean getBooleanQueryParameter(String key, boolean defaultValue)
③String getEncodedAuthority()
④String getEncodedFragment()
⑤String getEncodedPath()
⑥String getEncodedQuery()
⑦String getEncodedSchemeSpecificPart()
⑧String getEncodedUserInfo():从Authority获取编码的用户信息。
⑨String getFragment():获取Uri中的fragment字段
⑩String getHost():获取Authority的host部分
⑪String getLastPathSegment()
⑫String getPath():获取Uri中的path部分
⑬List<String> getPathSegments():返回Path的各个部分字符串集合
⑭int getPort():获取Authority的port字段
⑮String getQuery():获取Uri中的query部分
⑯String getQueryParameter(String key):获取查询字段指定key对应的值
⑰Set<String> getQueryParameterNames():返回所有查询参数的唯一名称Set集。按名称的首次出现顺序返回。
⑱List<String> getQueryParameters(String key)
⑲String getScheme():获取Uri中的schem字段
⑳String getSchemeSpecificPart()
㉑String getUserInfo()
2.3、其它方法
①isAbsolute():Uri是否是绝对URI:以scheme组件起始的完整格式,如http://fanyi.youdao.com。表示以对标识出现的环境无依赖的方式引用资源。
②isHierarchical():Uri是否分层URI:如果此URI具有“ http://google.com”之类的层次结构,则返回true。如果绝对URI的scheme部分以“ /”开头,则是分层的。相对URI始终是分层的。
③isOpaque():Uri是否是不透明URI:scheme-specific-part组件不是以正斜杠(/)起始的,如mailto:xxx@abc.com。由于不透明URI无需进行分解操作,因此不会对scheme-specific-part组件进行有效性验证。
④isRelative():是否是相对URI:不以scheme组件起始的非完整格式,如fanyi.youdao.com。表示以对依赖标识出现的环境有依赖的方式引用资源。
3、系统Uri
Android给开发者提供了很多内置的Uri,通过这些Uri可以访问系统的各种Provider内容,借助Uri打开系统应用程序特定的系统界面。
3.1、网页
打开网页
Uri uri = Uri.parse("http://Quibbler.cn/");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);打开网页并使用搜索引擎搜索
Intent intent = new Intent();
intent.setAction(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, "析物言理");
startActivity(intent);3.2、短信拨号
跳转到拨号界面并输出携带的号码。更多关于短信的操作详见短信操作:原来用户隐私这么容易暴露。
Uri uri = Uri.parse("tel:110");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);直接打电话,需要权限"android.permission.CALL_PHONE"
Uri uri = Uri.parse("tel:10086");
Intent intent = new Intent(Intent.ACTION_CALL, uri);
startActivity(intent);打开短信界面,填入号码和短信内容;如果不putExtra指定sms_body短信内容字段,那么打开短信界面,只填收件人号码。
Uri uri = Uri.parse("smsto:10086");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra("sms_body", "短信内容");
startActivity(intent);3.3、媒体相关
播放音乐,可以是从文件创建的Uri,也可以直接是歌曲在线URL地址。
Uri uri = Uri.parse("http://m7.music.126.net/b91c04da915b301617.mp3");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "audio/mp3");
startActivity(intent);打开邮件发送界面
Uri uri= Uri.parse("mailto:fluent0418@gmail.com");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(intent);3.4、应用商店跳转(不可靠)
应用商店查找(应用名或者包名)国内各手机厂商各不相同
Uri uri = Uri.parse("market://search?q=抖音");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);应用在应用商店详情页面(不好用,具体还是以各个手机厂商的应用商店跳转方式为准)
Uri uri = Uri.parse("market://details?id=应用ID");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);4、示例
看再多代码,不如实操编写一遍。以下面的Uri为例
Uri uri = Uri.parse("quibbler://fluent:8080/data/test/cache?time=90&name=zhao#析物言理");获取scheme
String scheme = uri.getScheme();
Log.d(TAG, "scheme = " + scheme);
//scheme = quibbler获取authority
String authority = uri.getAuthority();
Log.d(TAG, "authority = " + authority);
//authority = fluent:8080获取host
String host = uri.getHost();
Log.d(TAG, "host = " + host);获取port,注意是int类型
int port = uri.getPort();
Log.d(TAG, "port = " + port);获取path相关内容
String path = uri.getPath();
Log.d(TAG, "path = " + path);
//path = /data/test/cache
List<String> pathList = uri.getPathSegments();
Log.d(TAG, "pathList = " + pathList.toString());
//pathList = [data, test, cache]获取query相关内容
String query = uri.getQuery();
Log.d(TAG, "query = " + query);
//query = time=90&name=zhao
Set<String> querySet = uri.getQueryParameterNames();
Log.d(TAG, "querySet = " + querySet.toString());
//querySet = [time, name]
Log.d(TAG, "time = " + uri.getQueryParameter("time") + "\tname = " + uri.getQueryParameter("name"));
//time = 90 name = zhao获取最后的fragment字段
String fragment = uri.getFragment();
Log.d(TAG, "fragment = " + fragment);
//fragment = 析物言理参考博客:
Docs > Reference > Uri">Android Developers > Docs > Reference > Uri
RFC 2396 - Uniform Resource Identifiers (URI): Generic Syntax

