この方法が分からなかったので。
▼ 例えば次のURIがあるとする
1 |
content://com.android.providers.media.documents/document/image:3982 |
▼ これから実際のパスを取得したい
1 |
/storage/emulated/0/Download/path/to/mypictures/hogehoge.png |
意外とやり方が面倒で困りました。
そこで自分への忘備録も兼ね、
AndroidでUriからパス取得する方法をまとめます。
まずは間違ったパス取得やり方について...
まずは失敗したやり方から
最初はこういうコードを書いてみました。
▼ 例えばこういうコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/// uri は各自のものに置き換え... ContentResolver cr = getContentResolver(); String[] columns = { MediaStore.Images.Media.DATA }; Cursor cursor = cr.query(uri, columns, null, null, null); cursor.moveToFirst(); String path = cursor.getString(cursor.getColumnIndexOrThrow( MediaStore.Images.Media.DATA )); cursor.close(); Log.d('path : ' + path); |
このコードの出力が path : null に...
でも、なぜかググるとこの方法が出てきます。
どうやら完全に非推奨になったやり方みたいです。
KitKat以降でUriからパス取得するには
実はさっきの間違った方法・・・
Android3.0未満でのみ有効です。
実際は次のバージョンごとに条件分岐が必要です。
- Android4.4以上(KitKat以降)
- Android3.1~3.2
- それ以外の古いバージョン
現在はAndroid3未満のシェアはかなり低いです。
そこでKitKat以降の正しい方法だけまとめます。
その Uri => パス への変換方法がこちら
▼ こういうコードを試してみた
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
String wholeId = DocumentsContract.getDocumentId(uri); String id = wholeId.split(":")[1]; ContentResolver cr = getContentResolver(); String[] columns = { MediaStore.Images.Media.DATA }; String selection = MediaStore.Images.Media._ID + "=?"; Cursor cursor = cr.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, selection, new String[]{id}, null); cursor.moveToFirst(); String path = cursor.getString( cursor.getColumnIndexOrThrow(columns[0])); cursor.close(); Log.d(TAG, "path : " + path); |
今度はしっかりとパス取得できました。
ただURIを渡すだけではだめで、SQLのWHERE句に相当するもの( = MediaStore.Images.Media._ID + "=?" )とその引数(= new String[]{id} )を渡す必要があるみたいですね。
そうすれば問題なく取得可能。
Android4.4以降なら全部カバーできます。
APIレベルごとにパス取得処理を切り替え
実用的にはAPIレベルごとに切り替えます。
▼ 切り替えのコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
String path = ""; int apiVersion; try { apiVersion = android.os.Build.VERSION_SDK_INT; } catch(NumberFormatException e) { apiVersion = 3; } if (apiVersion > Build.VERSION_CODES_KITKAT) { /// Android4.4以降の場合... String wholeId = DocumentsContract.getDocumentId(uri); String id = wholeId.split(":")[1]; ContentResolver cr = getContentResolver(); String[] columns = { MediaStore.Images.Media.DATA }; String selection = MediaStore.Images.Media._ID + "=?"; Cursor cursor = cr.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, selection, new String[]{id}, null); cursor.moveToFirst(); path = cursor.getString( cursor.getColumnIndexOrThrow(columns[0])); cursor.close(); } else { /// それ以前の古いバージョンの場合... ContentResolver cr = getContentResolver(); String[] columns = { MediaStore.Images.Media.DATA }; Cursor cursor = cr.query(uri, columns, null, null, null); cursor.moveToFirst(); path = cursor.getString(cursor.getColumnIndexOrThrow( MediaStore.Images.Media.DATA )); cursor.close(); } Log.d(TAG, "path : " + path); |
こういう風にAPIバージョンに応じて処理切り替えが確実ですが、Android4.4以降がターゲットならこういう切り替えは必要ありません。自分自身もこういうコードは書かないです。
でも念のためにコードを載せておきます。
以上、AndroidでのUriからパス取得でした。
間違いがあればコメントからどうぞ、ではまた(^^)/~~~