URIから画像ファイル先を取得する。

はまりました。
URIから画像取得するだけだから楽ちんだろー。
と思っていたら、失敗して時間ばかりかかってしまったのでメモ。


最初にWEBの情報をベースに用意したのが以下のコード
/**
* UriからPathへの変換処理
* @param uri
* @return String
*/
public static String getPath(Context context, Uri uri) {
ContentResolver contentResolver = context.getContentResolver();
String columns = { MediaStore.Images.Media.DATA };
Cursor cursor = contentResolver.query(uri, columns, null, null, null);
Log.d(LOG_TAG, "uri.toString():" + uri.toString());
if (cursor == null) {
cursor = contentResolver.query(uri, columns, null, null, null);
Log.d(LOG_TAG, "uri.getPath(): " + uri.getPath());
if (null == cursor){
Log.e(LOG_TAG, "cursor is null");
}
}
cursor.moveToFirst();
String path = cursor.getString(0);
Log.d(LOG_TAG, "getPath:path:" + path);
cursor.close();
return path;
}

ギャラリーから取得したURI
ならば問題はなくPathを取得できる。
しかし、画像編集用のライブラリーであるAviaryからもどってくるURIを使用して
pathが取得しようとするとエラーになる。

http://www.aviary.com/

LogCat上ではこんな感じ
⇒ギャラリーから
12-12 15:03:54.600 D ImageUtilities( 8574) uri.toString():content://media/external/images/media/7951
12-12 15:03:54.600 D ImageUtilities( 8574) getPath:path:/mnt/sdcard/Pictures/aviary/aviary_1354264866459.jpg

⇒Aviaryから
12-12 15:05:30.420 D ImageUtilities( 8574) uri.toString():file:///mnt/sdcard/Pictures/NMM3/NMM3_1355292322370.jpg
12-12 15:05:30.420 D ImageUtilities( 8574) uri.getPath(): /mnt/sdcard/Pictures/NMM3/NMM3_1355292322370.jpg
12-12 15:05:30.420 E ImageUtilities( 8574) cursor is null

つまり、ここでなにが分かるかというと、
uriで取得しているデータのスキーマが違うために
上記ソースではfile:///〜始まる内容に対応できず、
cursorを生成しても、nullになってしまうのが問題。

と、いうわけでuriのスキーマから処理する内容を変えてあげるように
すればいい。
/**
* UriからPathへの変換処理
* Uriのscheme()から
* context://
* file://
* を判断して、処理する内容を変える。
* @param uri
* @return String
*/
public static String getPathFromUri(Context context, Uri uri) {
String filePath = null;
Log.d(LOG_TAG, "uri :" +uri);
if (uri !=null && "content".equals(uri.getScheme())) {
Cursor cursor = context.getContentResolver().query(uri, new String { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
cursor.moveToFirst();
filePath = cursor.getString(0);
cursor.close();
}else{
filePath = uri.getPath();
}
return filePath;
}

これでうまくできた。
取得するuriのスキーマが違っても大丈夫。