Android--Uri转实际路径详解

通过Uri得到实际路径,网上方法有很多,但我前几天试了一下,发现返回的值都是null,后来才发现,Uri的格式在Android4.4之后有了很大的改动。

content://media/extenral/images/media/17766(4.4前)
content://com.android.providers.media.documents/document/image:2706(4.4后)

  1. 4.4之前的方法
    4.4之前的方法网上都有很多,大多数都是基于cursor来实现的。这里主要讲4.4之后的。
  2. 4.4之后的方法
    代码在这里有了,大家可以对照来看。
    http://www.2cto.com/kf/201502/376975.html
    Uri分为三个部分
    content://com.android.providers.media.documents/document/image:2706
    scheme:content://
    authority: com.android.providers.media.documents
    path:document/image:2706

    所以要得到uri对应的文件路径
    1、先找到文件是属于什么类型(通过authority来判断,源码中就根据authority的值来分为external_document,media等),可以通过getAuthority()来得到。
    2、解析文件path的结构,这里拿MediaDocument举例
    String docId=DocumentContract.getDocumentId(uri);
    进入这个函数,发现包含getPathSegments(),这就是将uri中的path解析成多个部分,如document和image:2706,image是类型,2706就是ID啦。
    之后当然是判断类型咯,看看是image还是video还是audio,然后生成一个contentUri,这个时候的后面的就代表的是路径而不是id了。
    例如,contentUri=content://+authority+/external/image/media
    现在已经知道了,uri对应的id是2706,之后怎么得到它的信息呢?对,跟4.4版本之前的一样也是用cursor,所以有:

 cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
  这是个比较关键的函数,cursor相当于一个数据库里的光标,ContentResolver是内容解析对象,我们可以把要解析的内容想象成一个数据库,下面讲讲这几个参数的含义:
  uri,就是contentUri了,包含路径的
  projection,官方解释是a list of which columns return,意思就是返回哪些列,源码中是_data,意思就是返回_data列
  selection,源码中是_id=?
  selectionArgs,源码中是2706,即图片id,联合上面的参数就是在数据库寻找_id=2706的数据

好了,我们现在可以看到,返回的cursor,就是指向_id=2706的数据中的_data列的数据,其实这个数据就是我们需要的path了。
下面输出path

int column_index=cursor.getColumnIndex("_data")
String data=cursor.getString(column_index)

好了,其实也蛮简单的。。。但是我做了好久哎。。

你可能感兴趣的:(Android--Uri转实际路径详解)