2014/11/23
Androidの画像選択で嵌ったのでメモ
Android 5.0(lolipop)がリリースされたのでインストールしてみた。
体感速度で倍ぐらいになってビビったよ。
で、自作の付箋アプリの動作を確認していたら画像選択で落ちやがったのでその対応メモ。
とりあえず、ログを見るとこれで落ちてた。
android.content.ActivityNotFoundException: No Activity found to handle Intent
{ act=android.intent.action.PICK typ=image/* }
Intent.ACTION_PICK image/* はシステムの画像選択を呼び出すはずだけど無くなったのか?
ググったら KitKat からは Intent.ACTION_OPEN_DOCUMENT
に変わったらしい。
でも KitKat 以前は Intent.ACTION_PICK のままである必要がある。うへ
とりあえず、これでどっちでも画像選択が起動するようになったよ。
@TargetApi(Build.VERSION_CODES.KITKAT)
public static void startChoosePicture(Activity context, int code) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
context.startActivityForResult(intent, code);
} else {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
context.startActivityForResult(intent, code);
}
}
これでOKかと思ったら甘かったね。
OSを再起動すると選択した画像が表示されない。
ログを見たらこんなエラーが出てた。
java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider
from ProcessRecord{2787cc3a 22044:org.kotemaru.android.postit/u0a109} (pid=22044, uid=10109)
requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
単純に MANAGE_DOCUMENTS をパーミッションに加えても解決しない。
ググったら見つかったよ。
- stackoverflow.com:Android KitKat securityException when trying to read from MediaStore
takePersistableUriPermission()で永続的パーミッションを得ないと再起動したら見えなくなるのか。
そんなの見落とすよ、API考えろよGoogle。
画像URI取得にこれをはさんだらうまく行った。
@TargetApi(Build.VERSION_CODES.KITKAT)
public static Uri getResultChoosePictureUri(Context context, int requestCode, int resultCode, Intent returnedIntent) {
if (resultCode != Activity.RESULT_OK) return null;
Uri uri = returnedIntent.getData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final int takeFlags = returnedIntent.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION;
context.getContentResolver().takePersistableUriPermission(uri, takeFlags);
}
return uri;
}
Androidはバージョン間差異が細かすぎるよ。
この投稿へのコメント

コメント・フォーム