私のアプリには、ライブラリから写真を選択する機能があります。まさにこの選択からのファイルパスが必要です。
これは、写真を選択する目的を作成するコードです。
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, INTENT_REQUEST_CODE_SELECT_PHOTO);
これは、URIからファイルパスを取得するコードです。
Cursor cursor = null;
String path = null;
try {
String[] projection = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
cursor.moveToFirst();
path = cursor.getString(columnIndex);
} finally {
if (cursor != null) {
cursor.close();
}
}
return path;
昨日のGoogleフォトアプリの更新の前は、すべて正常に機能していました。 URIの解析後、path
はnullになりました。
URIはこれに似ています:content://com.google.Android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F75209/ACTUAL
また、Intent.ACTION_GET_CONTENTアクションでインテントを作成しようとしました-運はありません。
以下のコードは、最新のGoogleフォトでもコンテンツURIを取得するために機能しています。私が試したのは、コンテンツURIに権限がある場合、一時ファイルに書き込み、一時イメージURIを返すことです。
同じことを試すことができます:
private static String getImageUrlWithAuthority(Context context, Uri uri)
{
InputStream is = null;
if (uri.getAuthority() != null)
{
try
{
is = context.getContentResolver().openInputStream(uri);
Bitmap bmp = BitmapFactory.decodeStream(is);
return writeToTempImageAndGetPathUri(context, bmp).toString();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
finally
{
try
{
if (is != null)
{
is.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return null;
}
private static Uri writeToTempImageAndGetPathUri(Context inContext, Bitmap inImage)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
これは間違いなく回避策ですが、何らかの理由で明らかになった実際のコンテンツURIを抽出できます:content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F75209
authority=media and path=external/images/media/xxx
で新しいURIを作成することができ、コンテンツリゾルバーは実際のURLを返しました。
サンプルコード:
String unusablePath = contentUri.getPath();
int startIndex = unusablePath.indexOf("external/");
int endIndex = unusablePath.indexOf("/ACTUAL");
String embeddedPath = unusablePath.substring(startIndex, endIndex);
Uri.Builder builder = contentUri.buildUpon();
builder.path(embeddedPath);
builder.authority("media");
Uri newUri = builder.build();