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後)
- 4.4之前的方法
4.4之前的方法網上都有很多,大多數都是基於cursor來實現的。這裡主要講4.4之後的。 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)
好了,其實也蠻簡單的。。。但是我做了好久哎。。