目录

Uri简介

UriMatcher

ContentUris

获取Uri路径后面的ID

从路径中获取ID

uri与file、path相互转化

Uri转file

Uri转path

file转Uri

file转path

path转Uri

path转file

被document封装过后的Uri

Android4.4之前的Uri形式

Android4.4之后的Uri形式

通过获取图片路径代码来分析document

Android4.4之后获取图片路径

4.4以上获得的Uri内容

判断该Uri是否是document封装过的

获取图片数据库数据表里指定的行

获取Uri的路径 getAuthority()

观察获取图片完整路径的方法

Android4.4 之前获取图片路径

一个调用相册获取图片的demo

常用Uri


Uri简介

通用资源标识符(Universal Resource Identifier) 简称Uri

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

Android的Uri由以下三部分组成

1."content://"、数据的路径、标识ID(可选)

例如所有图片

1. Uri:content://media/external

2. Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

某个图片

Uri:content://media/external/images/media/4

Android 提供他了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris

UriMatcher

UriMatcher 类主要用于匹配Uri

public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;//第一步,初始化
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);  //第二步,注册待匹配的Uri
matcher.addURI(AUTHORITY,"book",BOOK_DIR);
matcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);//第三步,进行匹配
Uri uri = Uri.parse("content://" + "com.example.yy" + "/book");
int match = matcher.match(uri);  switch (match){case BOOK_DIR:  return "vnd.android.cursor.dir/book";  case BOOK_ITEM:  return "vnd.android.cursor.item/book";  default:  return null;  }
//上面返回的是Uri对应的MIME

ContentUris

获取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 

从路径中获取ID

Uri uri = Uri.parse("content://com.example.yy/book/10")
long personid = ContentUris.parseId(uri);  

uri与file、path相互转化

Uri转file

File = new File(new URI(uri.toString)));

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;}

file转Uri

URI uri = file.toURI();

file转path

string path = file.getPath();

path转Uri

Uri uri = Uri.parse(path);

path转file

File file = new File(path);

被document封装过后的Uri

Android4.4之前的Uri形式

Uri : content://media/extenral/images/media/17766

Android4.4之后的Uri形式

content://com.android.providers.media.documents/document/image%3A82482

由此可见,4.4以上的系统使用了document封装过了

通过获取图片路径代码来分析document

Android4.4之后获取图片路径

private void handleImageOkKitKat(Intent data) {String imagePath=null;Uri uri = data.getData();Log.d("intent.getData :",""+uri);if (DocumentsContract.isDocumentUri(this,uri)){String docId = DocumentsContract.getDocumentId(uri);Log.d("getDocumentId(uri) :",""+docId);Log.d("uri.getAuthority() :",""+uri.getAuthority());if ("com.android.providers.media.documents".equals(uri.getAuthority())){String id = docId.split(":")[1];String selection = MediaStore.Images.Media._ID + "=" + id;imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);}else if ("com.android,providers.downloads.documents".equals(uri.getAuthority())) {Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));imagePath = getImagePath(contentUri,null);}}else if ("content".equalsIgnoreCase(uri.getScheme())){imagePath = getImagePath(uri,null);}displayImage(imagePath);}

4.4以上获得的Uri内容

Uri uri = data.getData(); Log.d("intent.getData :",""+uri);

运行结果:D/uri=intent.getData :﹕ content://com.android.providers .media.documents/document/image%3A82483 可以看到Uri不同于之前系统版本, 选取不同的图片观察Uri是相同的。

判断该Uri是否是document封装过的

静态方法:isDocumentUri(Context context, Uri uri)

DocumentsContract.isDocumentUri(this,uri

获取图片数据库数据表里指定的行

静态方法:getDocumentId(Uri uri)

String docId = DocumentsContract.getDocumentId(uri);

运行结果: D/getDocumentId(uri) :﹕ image:82482 返回一个字符串, 实际上就代表了该图片存储数据库数据表里的行的位置。

获取Uri的路径 getAuthority()

属于Uri对象的对象方法。

uri.getAuthority()

运行结果: D/uri.getAuthority() :﹕ com.android.providers.media.documents 可以对照Uri的组成判断。 “content://” + 数据的路径 + 标示ID(可选)

如果路径不同获取图片的方式是不一样的

 if ("com.android.providers.media.documents".equals(uri.getAuthority())){String id = docId.split(":")[1];String selection = MediaStore.Images.Media._ID + "=" + id;imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection); }else if ("com.android,providers.downloads.documents".equals(uri.getAuthority())) {Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));imagePath = getImagePath(contentUri,null);}

com.android.providers.media.documents路径下的图片是经过特殊封装的,

而com.android.providers.downloads.documents并没有。

观察获取图片完整路径的方法

这里再观察获取图片完整路径的方法(getImagePath)的代码,本质是使用内容提供器获取数据:

public String getImagePath(Uri uri,String selection) {String path = null;Cursor cursor = getContentResolver().query(uri,null,selection,null,null);   //内容提供器if (cursor!=null){if (cursor.moveToFirst()){path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));   //获取路径}}cursor.close();return path;}

由上,可以知道com.android.providers.media.documents使用document封装是向数据表添加了MediaStore.Images.Media.DATA列形成了一个新数据库

MediaStore.Images.Media.EXTERNAL_CONTENT_URI只有根据MediaStore.Images.Media.DATA来查询,此时的id(id指的不是之前的getDocumentId(uri)的docID,而是将docID以:分割获取的数值标号)是对应图片行MediaStore.Images.Media.DATA列的标号。

而com.android.providers.downloads.documents路径则是以4.4之前版本的形式的Uri存储的。

Android4.4 之前获取图片路径

private void handleImageBeforeKitKat(Intent data) {Uri uri = data.getData();String imagePath = getImagePath(uri,null);displayImage(imagePath);}

Uri里就包含了该图片所在行的id。

Uri : content://media/extenral/images/media/17766

使用内容提供器可以轻松获取路径。

一个调用相册获取图片的demo

public class MainActivity extends AppCompatActivity {private static final int TAKE_PHOTO = 1;private static final int CROP_PHOTO = 2;private static final int CHOOSE_PIC = 3;private Button takePhoto;private Button choosePicture;private ImageView picture;Uri imageUri;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);picture = (ImageView) findViewById(R.id.picture);takePhoto = (Button) findViewById(R.id.take_photo);takePhoto.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {File outputFile = new File(Environment.getExternalStorageDirectory(),"output_image.jpg");try{if (outputFile.exists()){outputFile.delete();}outputFile.createNewFile();} catch (IOException e) {e.printStackTrace();}imageUri = Uri.fromFile(outputFile);Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);startActivityForResult(intent,TAKE_PHOTO);}});choosePicture = (Button) findViewById(R.id.choose_picture);choosePicture.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent("android.intent.action.GET_CONTENT");intent.setType("image/*");startActivityForResult(intent,CHOOSE_PIC);}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){switch (requestCode){case TAKE_PHOTO:if (resultCode==RESULT_OK){Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(imageUri,"image/*");intent.putExtra("scale", true);intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);startActivityForResult(intent,CROP_PHOTO);}break;case CROP_PHOTO:if (resultCode==RESULT_OK){try {Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));picture.setImageBitmap(bitmap);} catch (FileNotFoundException e) {e.printStackTrace();}}break;case CHOOSE_PIC:if (resultCode==RESULT_OK){if (Build.VERSION.SDK_INT>=19){handleImageOkKitKat(data);}else{handleImageBeforeKitKat(data);}}default:break;}}private void handleImageBeforeKitKat(Intent data) {Uri uri = data.getData();String imagePath = getImagePath(uri,null);displayImage(imagePath);}private void handleImageOkKitKat(Intent data) {String imagePath=null;Uri uri = data.getData();Log.d("uri=intent.getData :",""+uri);if (DocumentsContract.isDocumentUri(this,uri)){String docId = DocumentsContract.getDocumentId(uri);        //数据表里指定的行Log.d("getDocumentId(uri) :",""+docId);Log.d("uri.getAuthority() :",""+uri.getAuthority());if ("com.android.providers.media.documents".equals(uri.getAuthority())){String id = docId.split(":")[1];String selection = MediaStore.Images.Media._ID + "=" + id;imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);}else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));imagePath = getImagePath(contentUri,null);}}else if ("content".equalsIgnoreCase(uri.getScheme())){imagePath = getImagePath(uri,null);}displayImage(imagePath);}private void displayImage(String imagePath) {if (imagePath!=null){Bitmap bitImage = BitmapFactory.decodeFile(imagePath);picture.setImageBitmap(bitImage);}else{Toast.makeText(MainActivity.this,"failed to get image",Toast.LENGTH_SHORT).show();}}public String getImagePath(Uri uri,String selection) {String path = null;Cursor cursor = getContentResolver().query(uri,null,selection,null,null);   //内容提供器if (cursor!=null){if (cursor.moveToFirst()){path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));   //获取路径}}cursor.close();return path;}
}

常用Uri

显示网页: 1. Uri uri = Uri.parse("http://www.google.com"); 2. Intent it = new Intent(Intent.ACTION_VIEW,uri); 3. startActivity(it); 显示地图: 1. Uri uri = Uri.parse("geo:38.899533,-77.036476"); 2. Intent it = new Intent(Intent.Action_VIEW,uri); 3. startActivity(it); 路径规划: 1. Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 2. Intent it = new Intent(Intent.ACTION_VIEW,URI); 3. startActivity(it); 拨打电话:
调用拨号程序 1. Uri uri = Uri.parse("tel:xxxxxx"); 2. Intent it = new Intent(Intent.ACTION_DIAL, uri);   3. startActivity(it);   1. Uri uri = Uri.parse("tel.xxxxxx"); 2. Intent it =new Intent(Intent.ACTION_CALL,uri); 3. 要使用这个必须在配置文件中加入<uses-permission id="Android.permission.CALL_PHONE" /> 发送SMS/MMS
调用发送短信的程序 1. Intent it = new Intent(Intent.ACTION_VIEW); 2. it.putExtra("sms_body", "The SMS text"); 3. it.setType("vnd.android-dir/mms-sms"); 4. startActivity(it);
发送短信 1. Uri uri = Uri.parse("smsto:0800000123"); 2. Intent it = new Intent(Intent.ACTION_SENDTO, uri); 3. it.putExtra("sms_body", "The SMS text"); 4. startActivity(it);
发送彩信 1. Uri uri = Uri.parse("content://media/external/images/media/23"); 2. Intent it = new Intent(Intent.ACTION_SEND); 3. it.putExtra("sms_body", "some text"); 4. it.putExtra(Intent.EXTRA_STREAM, uri); 5. it.setType("image/png"); 6. startActivity(it); 发送Email 1. 2. Uri uri = Uri.parse("mailto:xxx@abc.com"); 3. Intent it = new Intent(Intent.ACTION_SENDTO, uri); 4. startActivity(it); 1. Intent it = new Intent(Intent.ACTION_SEND); 2. it.putExtra(Intent.EXTRA_EMAIL, "me@abc.com"); 3. it.putExtra(Intent.EXTRA_TEXT, "The email body text"); 4. it.setType("text/plain"); 5. startActivity(Intent.createChooser(it, "Choose Email Client"));   1. Intent it=new Intent(Intent.ACTION_SEND);   2. String[] tos={"me@abc.com"};   3. String[] ccs={"you@abc.com"};   4. it.putExtra(Intent.EXTRA_EMAIL, tos);   5. it.putExtra(Intent.EXTRA_CC, ccs);   6. it.putExtra(Intent.EXTRA_TEXT, "The email body text");   7. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");   8. it.setType("message/rfc822");   9. startActivity(Intent.createChooser(it, "Choose Email Client")); 添加附件 1. Intent it = new Intent(Intent.ACTION_SEND); 2. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text"); 3. it.putExtra(Intent.EXTRA_STREAM, "[url=]file:///sdcard/mysong.mp3[/url]"); 4. sendIntent.setType("audio/mp3"); 5. startActivity(Intent.createChooser(it, "Choose Email Client")); 播放多媒体 1.   2. Intent it = new Intent(Intent.ACTION_VIEW); 3. Uri uri = Uri.parse("[url=]file:///sdcard/song.mp3[/url]"); 4. it.setDataAndType(uri, "audio/mp3"); 5. startActivity(it); 1. Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); 2. Intent it = new Intent(Intent.ACTION_VIEW, uri); 3. startActivity(it);   Uninstall 程序 1. Uri uri = Uri.fromParts("package", strPackageName, null); 2. Intent it = new Intent(Intent.ACTION_DELETE, uri); 3. 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); uninstall apk
/**未测试
Uri uninstallUri = Uri.fromParts("package", "xxx", null);
returnIt = new Intent(Intent.ACTION_DELETE, uninstallUri);
*/
Uri packageURI = Uri.parse("package:"+wistatmap);
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent); install apk
Uri installUri = Uri.fromParts("package", "xxx", null);
returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);
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);
//where pkg_name is the full package path for an application //进入联系人页面
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全解相关推荐

  1. Android动画全解

    Android动画全解 在Android开发中经常会碰到动画,看到别的应用有很酷炫的应用时,总是想怎么去实现,但是每次都是发现感觉是知道怎么做的,实际做起来还是无从下手的感觉,究其原因还是 Andro ...

  2. Android单元测试全解

      自动化测试麻烦吗?说实在,麻烦!有一定的学习成本.但是,自动化测试有以下优点: 节省时间:可以指定测试某一个activity,不需要一个个自己点 单元测试:既然Java可以进行单元测试,Andro ...

  3. android 10文件权限 三星,三星Android系统文件夹全解

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 三星android系统的开放,使其用户可以自己查看系统和SD卡中的文件夹.就系统和SD卡中常见的目录代表什么意思,下面是一个较实用的总结: 一.SD卡中 ...

  4. android 三星存储位置,三星Android系统文件夹全解

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 三星android系统的开放,使其用户可以自己查看系统和SD卡中的文件夹.就系统和SD卡中常见的目录代表什么意思,下面是一个较实用的总结: 一.SD卡中 ...

  5. 矿点三星android版本,三星Android系统文件夹全解

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 三星android系统的开放,使其用户可以自己查看系统和SD卡中的文件夹.就系统和SD卡中常见的目录代表什么意思,下面是一个较实用的总结: 一.SD卡中 ...

  6. Android 混淆全解

    开启混淆 位置:通常在app目录下的build.gradle 把 minifyEnabled设置为true即可 如下: release{minifyEnabled true//是否启动混淆 ture: ...

  7. 三星android是啥意思,三星Android系统文件夹全解

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 三星android系统的开放,使其用户可以自己查看系统和SD卡中的文件夹.就系统和SD卡中常见的目录代表什么意思,下面是一个较实用的总结: 一.SD卡中 ...

  8. android uri详解,URI与URL详解

    https://blog.csdn.net/readiay/article/details/52862379 看开源框架经常看到会用到URL或者URI之类的,为什么要熟悉这个呢? 比如说你写一个网络程 ...

  9. 三星里的Android是什么,三星Android系统文件夹全解

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 三星android系统的开放,使其用户可以自己查看系统和SD卡中的文件夹.就系统和SD卡中常见的目录代表什么意思,下面是一个较实用的总结: 一.SD卡中 ...

  10. android系统手机流量控制方法amp;,基于Android的手机流量控制软件全解.doc

    基于Android的手机流量控制软件全解 基于Android的手机流量控制软件 设计与实现 1 绪论 1.1 手机移动互联网进展 这些年,移动通信和互联网成为当今世界发展最快.市场潜力最大.前景最诱人 ...

最新文章

  1. python初学之魔法方法1
  2. mysql基础语句整理
  3. x86终端登录horizon view设置
  4. 好久没写博客了,改天要把原博客资料整理下,弄个链接什么
  5. iOS:通过URL构件UIImage
  6. ARM9之NAND FLASH总结
  7. java内存模型作用是什么_什么是JVM内存模型?
  8. 前端的ajax缓存,解析jquery中的ajax缓存问题
  9. POJ-3468-A Simple Problem with integers
  10. Could not find modernizr-2.6.2 in any of the sources
  11. c51语言中 位取反指令,C51的几种位操作运算说明
  12. 为什么世界是由数学构成的
  13. 微信小程序样式大全(一)
  14. Windows10怎么样添加并设置为卓越性能模式
  15. 四级地址插件升级改造(京东商城地址选择插件)city-picker
  16. 51单片机程序存储器和数据存…
  17. Powershell运行脚本异常:无法加载文件...因为在此系统上禁止运行脚本
  18. 网站流量日志数据分析系统(模块开发----数据仓库设计)
  19. 帆软思迈特软件Smartbi两家区别在哪里?
  20. 【历史上的今天】9 月 12 日:世界上第一块集成电路诞生;QNX 操作系统开源;苹果推出 iPhone X

热门文章

  1. postgresql使用教程
  2. 《北漂的京城巡回礼》
  3. 当贝 X3 Air 评测 当贝x3air参数
  4. CES Asia专题|视觉暂留黑科技,这款全息展示机有点酷
  5. 抖音强势入局服装生意,出手就是1个亿,服装实体店出路在哪?
  6. Linux进程控制:wait获取子进程退出状态 WIFEXITED和WIFSIGNALED用法
  7. finally在python中是什么意思_在Python中解释try,except和finally语句。
  8. Java - reduce函数的应用
  9. reduce函数详解
  10. MP3 base64加密解密