web-dev-qa-db-ja.com

Android API 19(KitKat)で権限を永続化する方法は?

私のアプリケーションでは、さらに使用するために画像のパスをSQliteデータベースに保存します。私が得る道は

content://com.Android.providers.media.documents/document/image%3A71964

データベースからこのパスを取得し、そのパスから画像を取得しようとするとAndroid throws

Java.lang.SecurityException: Permission Denial: opening provider
com.Android.providers.media.MediaDocumentsProvider 
from ProcessRecord{42c84ec8 23911:com.gots.gb/u0a248} (pid=23911, uid=10248) 
requires Android.permission.MANAGE_DOCUMENTS or Android.permission.MANAGE_DOCUMENTS

によると https://developer.Android.com/guide/topics/providers/document-provider.html#permissions 次のコードを追加して権限を保持する必要があります

final int takeFlags = intent.getFlags()
        & (Intent.FLAG_GRANT_READ_URI_PERMISSION
        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(uri, takeFlags);

このコードを、BaseAdapterを拡張するImageAdapterクラスに追加するとAndroid throws

08-21 02:14:38.530: W/System.err(24452): Java.lang.SecurityException:
No permission grant found for UID 10248 and Uri 
content://com.Android.providers.media.documents/document/image:71964

これは私のImageAdapterコードの関連部分です

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView ;


    if (convertView == null){
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(new GridView.LayoutParams(185, 185));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(8, 8, 8, 8);

    }
    else{
        imageView = (ImageView)convertView ;
    }

    InputStream is = null;
    Bitmap bitmap = null ;

    try {

        Log.d(TAG,String.valueOf(list.get(position)));
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        final int takeFlags = intent.getFlags()
                & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        // Check for the freshest data.

        if (Build.VERSION.SDK_INT >= 19){
            mContext.getContentResolver().takePersistableUriPermission(list.get(position), takeFlags);
        }


        is = mContext.getContentResolver().openInputStream(list.get(position));

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 8;
        bitmap = BitmapFactory.decodeStream(is,null, options);
        is.close();
        imageView.setImageBitmap(bitmap);

        return imageView;

    }
    catch (Exception e) {
        e.printStackTrace();

        return null;
    }

私は何が間違っているのですか?ありがとう

16
Pdksock

私はそれを解決したと信じています。リクエストの目的:

Intent intent;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat){
    intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
}else{
    intent = new Intent(Intent.ACTION_GET_CONTENT);
}
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, getResources().getString(R.string.form_pick_photos)), REQUEST_PICK_PHOTO);

およびonActivityResult

...
// KitKat fixed (broke) content access; to keep the URIs valid over restarts need to persist access permission
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
    final int takeFlags = data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION;
    ContentResolver resolver = getActivity().getContentResolver();
    for (Uri uri : images) {
        resolver.takePersistableUriPermission(uri, takeFlags);
    }
}
...

私はこのKitKat以前をテストしていません、私の電話は5.1を実行しています、誰かが古い電話でこれを確認できますか?

29
DariusL

以下にリストされているコード、

// KitKat fixed (broke) content access; to keep the URIs valid over restarts need to persist access permission
if(Utils.isKitkat())
{
    final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION);
    ContentResolver resolver = getActivity().getContentResolver();
    for (Uri uri : images)
    {
        resolver.takePersistableUriPermission(uri, takeFlags);
    }
}

とにかく、アプリに付与される永続可能なuriの最大数が128に制限されていることに気付きました。128uriを超える値を選択すると、次のエラーが発生します。

Java.lang.SecurityException: Permission Denial: opening provider........

権限を保持できなかった画像を処理しようとしたとき。解決策を見つけられますか?

0
David