Android:统一资源标识URI的理解及相关用法

百科词条 ↓

统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。

该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。URI由包括确定语法和相关协议的方案所定义。

Web上可用的每种资源 -HTML文档、图像、视频片段、程序等 - 由一个通用资源标识符(Uniform Resource Identifier, 简称"URI")进行定位。

  • 用于在互联网上标识一个资源,比如 https://blog.csdn.net/plus_left 这个URI,指的是我的博客网页
    这时你肯定想问URL和URN与URI的关系,下边将会为你解答,先明确的告诉你:URL和URN是URI的子集

1.URI一般由三部分组成

1.主机名

存放资源的自身的名称,由路径表示。
参考下面的URI,它符合当前的RFC4395规范:协议名称://域名.根域名/目录/文件名.后缀

  • 例如http://b.c/d/e.f (假设b.c是一个可用的域名,e.f是一个标准的文件)
    这个URI是这样的:这是一个可通过HTTP协议访问的资源,位于主机b.c上,通过URI中的字符串“/d”访问主机上的“d”文件夹,通过“e.f”请求访问主机上“/d/e.f”这个文件。
  • URI的另一个例子,指向一个用户的邮箱:mailto:名称@域名

2.标志符

有的URI指向一个资源的内部。 这种URI以"#"结束,并跟着一个anchor标志符(称为片段标志符)。

  • 例如,下面是一个指向section_2的URI:
    协议://域名/目录/文件#片段标示符(例如:/a/b.php#a)

3.相对URI

相对URI不包含任何命名规范信息。它的路径通常指同一台机器上的资源。相对URI可能含有相对路径(如,“…”表示上一层路径),还可能包含片段标志符。

假设我们有一个基本的URI: 协议://域名/目录a/目录b/文件c
  • 下面的链接中使用了相对URI:
    …/文件D(返回到了a目录之后进入了D文件
    它扩展成完全的URI就是 “协议://域名/目录a/文件D”。
  • 下面是一个图像的相对URI:
<IMG src="../icons/logo.gif" alt="logo">

它扩展成完全的URI就是 “协议://域名/目录a/icons/logo.gif”。

2.URI与URL、URN之间的关系

  1. 狭义理解
  • 只在Java项目中理解URI 和 URL
    -URI : 绝对路径
    -URL : 完整路径

表面上看URI包含了URL

  1. 广义理解
  • 在任意的WEB项目中理解URI和URL
    URI : 资源的名称
    URL : 资源的真名

URI包含了URL

大家平时说的,将“URL”放到浏览器中。这里提到的URL ,其实不是一个URL ,是网址的意思。URI 是统一资源标识符,而 URL 是统一资源定位符。笼统地说,每个 URL 都是 URI,但不一定每个 URI 都是 URL。
Android:统一资源标识URI的理解及相关用法_第1张图片

  • RUI、RUL、URN
    URI :Uniform Resource Identifier,统一资源标识符;
    URL:Uniform Resource Locator,统一资源定位符;
    URN:Uniform Resource Name,统一资源名称。
  • Web上地址的基本形式是URI,它代表统一资源标识符。有两种形式:
    URL:目前URI的最普遍形式就是无处不在的URL或统一资源定位器。
    URN:URL的一种更新形式,统一资源名称(URN, Uniform ResourceName)不依赖于位置,并且有可能减少失效连接的个数。但是其流行还需假以时日,因为它需要更精密软件的支持。

3.Android中URI的使用

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

  • Android的Uri由以下三部分组成: “content://”、数据的路径、标示ID(可选) 举些例子,如:
    所有联系人的Uri: content://contacts/people
    某个联系人的Uri: content://contacts/people/5
    所有图片Uri: content://media/external
    某个图片的Uri:content://media/external/images/media/4
  • 我们经常需要解析Uri,并从Uri中获取数据。 Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。
  • 下面就一起看一下这两个类的作用。

1.UriMatcher

  • UriMatcher 类主要用于匹配Uri. 使用方法如下。

首先第一步,初始化:

UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);  

第二步,注册需要的Uri:

matcher.addURI("com.yfz.Lesson", "people", PEOPLE);  
matcher.addURI("com.yfz.Lesson", "person/#", PEOPLE_ID);  

第三步,与已经注册的Uri进行匹配:

    Uri uri = Uri.parse("content://" + "com.yfz.Lesson" + "/people");  
    int match = matcher.match(uri);  
           switch (match)  
           {  
               case PEOPLE:  
                   return "vnd.Android.cursor.dir/people";  
               case PEOPLE_ID:  
                   return "vnd.android.cursor.item/people";  
               default:  
                   return null;  
           }  

match方法匹配后会返回一个匹配码Code,即在使用注册方法addURI时传入的第三个参数。
上述方法会返回"vnd.Android.cursor.dir/person".

总结:

  • 常量 UriMatcher.NO_MATCH 表示不匹配任何路径的返回码
  • #号为通配符
  • *号为任意字符

2.ContentUris

ContentUris 类用于获取Uri路径后面的ID部分

  1. 为路径加上ID: withAppendedId(uri, id) 比如有这样一个Uri:
Uri uri = Uri.parse("content://com.yfz.Lesson/people");  

通过withAppendedId方法,为该Uri加上ID

Uri resultUri = ContentUris.withAppendedId(uri, 10);

最后resultUri为: content://com.yfz.Lesson/people/10
2. 从路径中获取ID: parseId(uri)

Uri uri = Uri.parse("content://com.yfz.Lesson/people/10")  
long personid = ContentUris.parseId(uri);  

最后personid 为 :10

4.URI的常用用法

1. 联系人的相关URI

管理联系人的Uri:
ContactsContract.Contacts.CONTENT_URI

管理联系人的电话的Uri:
ContactsContract.CommonDataKinds.Phone.CONTENT_URI

管理联系人的Email的Uri:
ContactsContract.CommonDataKinds.Email.CONTENT_URI

  • Contacts有两个表,分别是rawContact和Data,
    • rawContact记录了用户的id和name,
      id : 其中id栏名称为:ContactsContract.Contacts._ID
      name : 名称栏为ContactContract.Contracts.DISPLAY_NAME,

电话信息表的外键id为ContactsContract.CommonDataKinds.Phone.CONTACT_ID,

电话号码栏名称为:ContactsContract.CommonDataKinds.Phone.NUMBER.
data表中Email地址栏名称为:
ContactsContract.CommonDataKinds.Email.DATA

其外键栏为:ContactsContract.CommonDataKinds.Email.CONTACT_ID)

2.关于多媒体的一些URI:

存储在sd卡上的音频文件:
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

存储在手机内部存储器上的音频文件:
MediaStore.Audio.Media.INTERNAL_CONTENT_URI

SD卡上的图片文件内容:
MediaStore.Audio.Images.EXTERNAL_CONTENT_URI

手机内部存储器上的图片:
MediaStore.Audio.Images.INTERNAL_CONTENT_URI

SD卡上的视频:
MediaStore.Audio.Video.EXTERNAL_CONTENT_URI

手机内部存储器上的视频:
MediaStore.Audio.Video.INTERNAL_CONTENT_URI

  • 图片的显示名栏:Media.DISPLAY_NAME,

    图片的详细描述栏为:Media.DESCRIPTION

    图片的保存位置:Media.DATA

3.短信URI:

短信URI:
Content://sms

发送箱中的短信URI:
Content://sms/outbox

收信箱中的短信URI:
Content://sms/sent

草稿中的短信URI:
Content://sms/draft

常用代码:

// 获取手机号

Cursorphone=cursor.query
(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,ContactsContract.CommonDataKinds.Phone.
CONTACT_ID +"="+ContactId, null, null);

// 复杂点:

Cursor phone = cursor.query
(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +"="
+ ContactId +" AND "+ ContactsContract.CommonDataKinds.Phone.
+ TYPE +"="+ ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE,
 null, null);

ContactsContract.CommonDataKinds.Phone.TYPE 表示联系人电话的类型,

主要对应如下:
TYPE_MOBILE : 手机号码
TYPE_HOME : 住宅电话
TYPE_WORK : 公司电话

  • 打开一个网页,类别是Intent.ACTION_VIEW
    Uri
    uri = Uri.parse("http://www.baidu.com/");
    Intent
    intent = new Intent(Intent.ACTION_VIEW,uri);

  • 打开地图并定位到一个点
    Uri
    uri = Uri.parse("geo:52.76,-79.0342");
    Intent
    intent = new Intent(Intent.ACTION_VIEW, uri);

打开拨号界面,类型是Intent.ACTION_DIAL
Uri
uri = Uri.parse("tel:10086");
Intent
intent = new Intent(Intent.ACTION_DIAL,uri);

  • 直接拨打电话,与之不同的是,这个直接拨打电话,而不是打开拨号界面
    Uri
    uri = Uri.parse("tel:10086");
    Intent
    intent = new Intent(Intent.ACTION_CALL, uri);

参考:

https://baijiahao.baidu.com/s?id=1591884958560949588&wfr=spider&for=pc
https://blog.csdn.net/DUANJIEFEI/article/details/46274581
https://blog.csdn.net/sunqiujing/article/details/75011871

你可能感兴趣的:(Android)