美文网首页
Android 中的 Uri 如何使用呢 ?

Android 中的 Uri 如何使用呢 ?

作者: 蜗牛是不是牛 | 来源:发表于2023-06-26 16:18 被阅读0次

    问题

    Android 中常用的 uri 如何使用呢 ?(此篇分析基础为Android 7.1.1系统源码),参看Android官方说明:https://developer.android.com/reference/android/net/Uri,代码可在此查看:https://github.com/LineageOS/android_frameworks_base/blob/lineage-20.0/core/java/android/net/Uri.java

    1 概述

    通用资源标志符 URI (Universal Resource Identifier),URI 在 java.net.URI 中定义,显然是 Java 提供的一个类。而 Uri 位置在 android.net.Uri 中定义(Android 源码内位置:frameworks/base/core/java/android/net/Uri.java),是特有针对 Android 系统定义的类。Uri 代表要操作的数据,Android 上可用的每种资源(图像、视频片段、网页等)都可以用 Uri 来表示。

    Uri 的组成部分:

    • 访问资源的命名机制(scheme)
    • 存放资源的主机名(authority)
    • 资源自身的名称,由路径表示(path)

    Uri 的结构:

    # 基本形式
    [scheme:]scheme-specific-part[#fragment]
    # 第二形式
    [scheme:][//authority][path][?query][#fragment]
    # 第三形式
    [scheme:][//host:port][path][?query][#fragment]
    
    

    特别针对scheme说明下,Uri中有这么几种常用标识:

    • content : 主要操作的是ContentProvider,它代表的是数据库中的某个资源
    • http : 某网站资源
    • file : 本地机器上的资源
    • git : git仓库中的资源
    • ftp : ftp服务器上的资源

    2 Uri 的结构

    2.1 基本形式

    # 基本形式
    [scheme:]scheme-specific-part[#fragment]
    
    

    2.2 第二形式

    # 第二形式
    [scheme:][//authority][path][?query][#fragment]
    
    

    注意其中规则:

    1. path 可以有多个,每个用 / 连接,比如:```
      scheme://authority/path1/path2/path3?query#fragment

    2. query 参数可以带有对应的值,也可以不带,如果带对应的值用 = 表示,如:```
      //这里有一个参数id,它的值是1
      scheme://authority/path1/path2/path3?id=1#fragment

    3. query 参数可以有多个,每个用 & 连接,如:```
      /*
      这里有3个参数:
      参数1:id,其值是:1
      参数2:name,其值是:pedro
      参数3:old,没有对它赋值,所以它的值是null
      */
      scheme://authority/path1/path2/path3?id = 1&name=pedro&old#fragment

    在android中,除了scheme、authority是必须要有的,其它的几个path、query、fragment,它们每一个可以选择性的要或不要,但顺序不能变

    2.3 第三形式

    第二形式中 authority 又可以分为 host:port 的形式,这是划分最细的形式:

    # 第三形式
    [scheme:][//host:port][path][?query][#fragment]
    
    

    2.4 例子

    可以通过这个例子检测下学习效果:

    http://www.pedro11.com:8080/yourpath/fileName.html?stove=10&path=32&id=4#harvic
    
    

    3 Uri 的UML类图

    我把 Android 源码中 frameworks/base/core/java/android/net/Uri.java (也可在此查看:https://github.com/LineageOS/android_frameworks_base/blob/lineage-20.0/core/java/android/net/Uri.java)导入到 IDEA 工程中,通过 IDEA 的 Diagram 工具生成了它的 UML 类图(注意其中紫色方法为抽象方法),更方便分析这个有意思的类(在Uri.java中可以看出它有很多内部类,而且内部类又继承了Uri类本身)。\

    类图中各个小图标的含义可查看这里:https://jetbrains.design/intellij/resources/icons_list/

    4 从 Uri 中提取 String

    • getScheme() : 获取Uri中的scheme字符串部分,即 http
    • getSchemeSpecificPart() : 获取Uri中的scheme-specific-part:部分,即 //www.pedro11.com:8080/yourpath/fileName.html
    • getFragment() : 获取Uri中的Fragment部分,即 harvic
    • getAuthority() : 获取Uri中Authority部分,即 www.pedro11.com:8080
    • getPath() : 获取Uri中path部分,即 /yourpath/fileName.html
    • getQuery() : 获取Uri中的query部分,即 stove=10&path=32&id=4
    • getHost() : 获取Authority中的Host字符串,即 www.pedro11.com
    • getPost() : 获取Authority中的Port字符串,即 8080
    • getPathSegments() : 依次提取出Path的各个部分的字符串,存入List< String>
    • getQueryParameter(String key) : 通过传进去query中某个Key的字符串,返回它对应的值
    String mUriStr = "http://www.pedro11.com:8080/yourpath/fileName.html?stove=10&path=32&id=4#harvic";
    Uri mUri = Uri.parse(mUriStr);
    List<String> pathSegList = mUri.getPathSegments();
    for (String pathItem:pathSegList){
        Log.d("qijian","pathSegItem:"+pathItem);
    }
    
    Log.d(tag,"getQueryParameter(\"stove\"):"+mUri.getQueryParameter("stove"));
    Log.d(tag,"getQueryParameter(\"id\"):"+mUri.getQueryParameter("id"));
    
    

    6 Uri操作工具类

    6.1 ContentUris 处理 Uri

    ContentUris 有两个作用:

    • 为路径加上ID
    • 从Uri路径中获取ID
    1. 为Uri路径加上ID: withAppendedId(uri, id)```
      //比如有这样一个Uri
      Uri uri = Uri.parse("content://com.example.yy/book");

      //通过ContentUris的withAppendedId()方法,为该Uri加上ID
      Uri resultUri = ContentUris.withAppendedId(uri, 10);

      //最后resultUri为:
      //content://com.example.yy/book/10

    2. 从Uri路径中获取ID—parseId(uri)```
      Uri uri = Uri.parse("content://com.example.yy/book/10")
      long bookId= ContentUris.parseId(uri);

    6.2 UriMatcher 处理 Uri

    待添加

    6.3 uri与file、path相互转化

    1. uri 转 file```
      file = new File(new URI(uri.toString()));

    2. file 转 uri```
      URI uri = file.toURI();

    3. uri 转 path```
      private String getPath(Context context, Uri uri) {
      String path = null;
      Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
      if (cursor == null) {
      return null;
      }
      if (cursor.moveToFirst()) {
      try {
      path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
      } catch (Exception e) {
      e.printStackTrace();
      }
      }
      cursor.close();
      return path;
      }

    4. path 转 uri```
      Uri uri = Uri.parse(path);

    5. file 转 path```
      String path = file.getPath();

    6. path 转 file```
      File file = new File(path);

    8 常用Uri

    //显示网页: 
        Uri uri = Uri.parse("http://www.google.com"); 
        Intent it = new Intent(Intent.ACTION_VIEW,uri); 
        startActivity(it); 
     
    //显示地图: 
        Uri uri = Uri.parse("geo:38.899533,-77.036476"); 
        Intent it = new Intent(Intent.Action_VIEW,uri); 
        startActivity(it); 
     
    //路径规划: 
        Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 
        Intent it = new Intent(Intent.ACTION_VIEW,URI); 
        startActivity(it); 
     
    //调用拨号程序,要使用这个必须在配置文件中加入<uses-permission id="Android.permission.CALL_PHONE" /> 
        Uri uri = Uri.parse("tel:xxxxxx"); 
        Intent it = new Intent(Intent.ACTION_DIAL, uri);   
        startActivity(it);
    
        Uri uri = Uri.parse("tel.xxxxxx"); 
        Intent it =new Intent(Intent.ACTION_CALL,uri); 
     
    //调用发送短信的程序 
        Intent it = new Intent(Intent.ACTION_VIEW); 
        it.putExtra("sms_body", "The SMS text"); 
        it.setType("vnd.android-dir/mms-sms"); 
        startActivity(it);
    
    //发送短信 
        Uri uri = Uri.parse("smsto:0800000123"); 
        Intent it = new Intent(Intent.ACTION_SENDTO, uri); 
        it.putExtra("sms_body", "The SMS text"); 
        startActivity(it);   
    
    //发送彩信 
        Uri uri = Uri.parse("content://media/external/images/media/23"); 
        Intent it = new Intent(Intent.ACTION_SEND); 
        it.putExtra("sms_body", "some text"); 
        it.putExtra(Intent.EXTRA_STREAM, uri); 
        it.setType("image/png"); 
        startActivity(it); 
     
    //发送Email 
        Uri uri = Uri.parse("mailto:xxx@abc.com"); 
        Intent it = new Intent(Intent.ACTION_SENDTO, uri); 
        startActivity(it); 
      
        Intent it = new Intent(Intent.ACTION_SEND); 
        it.putExtra(Intent.EXTRA_EMAIL, "me@abc.com"); 
        it.putExtra(Intent.EXTRA_TEXT, "The email body text"); 
        it.setType("text/plain"); 
        startActivity(Intent.createChooser(it, "Choose Email Client"));
      
        Intent it=new Intent(Intent.ACTION_SEND);   
        String[] tos={"me@abc.com"};   
        String[] ccs={"you@abc.com"};   
        it.putExtra(Intent.EXTRA_EMAIL, tos);   
        it.putExtra(Intent.EXTRA_CC, ccs);   
        it.putExtra(Intent.EXTRA_TEXT, "The email body text");   
        it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");   
        it.setType("message/rfc822");   
        startActivity(Intent.createChooser(it, "Choose Email Client")); 
     
    //添加附件 
        Intent it = new Intent(Intent.ACTION_SEND);
        it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");
        it.putExtra(Intent.EXTRA_STREAM, "[url=]file:///sdcard/mysong.mp3[/url]");
        sendIntent.setType("audio/mp3");
        startActivity(Intent.createChooser(it, "Choose Email Client"));
     
    //播放多媒体 
        Intent it = new Intent(Intent.ACTION_VIEW); 
        Uri uri = Uri.parse("[url=]file:///sdcard/song.mp3[/url]"); 
        it.setDataAndType(uri, "audio/mp3"); 
        startActivity(it); 
      
        Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); 
        Intent it = new Intent(Intent.ACTION_VIEW, uri); 
        startActivity(it);   
     
    //Uninstall APP
        Uri uri = Uri.fromParts("package", strPackageName, null); 
        Intent it = new Intent(Intent.ACTION_DELETE, uri); 
        startActivity(it); 
     
    //调用相册 
        public static final String MIME_TYPE_IMAGE_JPEG = "image/*"; 
        public static final int ACTIVITY_GET_IMAGE = 0; 
        Intent getImage = new Intent(Intent.ACTION_GET_CONTENT); 
        getImage.addCategory(Intent.CATEGORY_OPENABLE); 
        getImage.setType(MIME_TYPE_IMAGE_JPEG); 
        startActivityForResult(getImage, ACTIVITY_GET_IMAGE); 
     
    //调用系统相机应用程序,并存储拍下来的照片 
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
        time = Calendar.getInstance().getTimeInMillis(); 
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/tucue", time + ".jpg"))); 
        startActivityForResult(intent, ACTIVITY_GET_CAMERA_IMAGE); 
     
    //play audio 
        Uri playUri = Uri.parse("[url=]file:///sdcard/download/everything.mp3[/url]"); 
        returnIt = new Intent(Intent.ACTION_VIEW, playUri); 
     
    //发送附件 
        Intent it = new Intent(Intent.ACTION_SEND);   
        it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");   
        it.putExtra(Intent.EXTRA_STREAM, "[url=]file:///sdcard/eoe.mp3[/url]");   
        sendIntent.setType("audio/mp3");   
        startActivity(Intent.createChooser(it, "Choose Email Client")); 
     
    //搜索应用 
        Uri uri = Uri.parse("market://search?q=pname:pkg_name");   
        Intent it = new Intent(Intent.ACTION_VIEW, uri);   
        startActivity(it);   
     
    //进入联系人页面 
        Intent intent = new Intent(); 
        intent.setAction(Intent.ACTION_VIEW); 
        intent.setData(People.CONTENT_URI); 
        startActivity(intent); 
     
    //查看指定联系人 
        Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, info.id);//info.id联系人ID 
        Intent intent = new Intent(); 
        intent.setAction(Intent.ACTION_VIEW); 
        intent.setData(personUri);
        startActivity(intent); 
    
    

    相关文章

      网友评论

          本文标题:Android 中的 Uri 如何使用呢 ?

          本文链接:https://www.haomeiwen.com/subject/smfgydtx.html