¿Cómo persistir el permiso en Android API 19 (KitKat)?

En mi aplicación, almaceno la ruta de la imagen en mi base de datos SQlite para su uso posterior. El camino que obtengo es

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

Cuando recupero esta ruta de la base de datos y trato de recuperar la imagen de esa ruta lanza Android

 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 

De acuerdo con https://developer.android.com/guide/topics/providers/document-provider.html#permissions Necesito persistir el permiso agregando el siguiente código

 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); 

Cuando agregué este código a mi clase ImageAdapter, que amplía los lanzamientos de android BaseAdapter

 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 

Esta es la parte relevante de mi código de 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; } 

¿Qué estoy haciendo mal? Gracias

Creo que lo he resuelto. La intención de la solicitud:

 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); 

y 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); } } ... 

No he probado este prekitkat, mi teléfono funciona con 5.1, ¿alguien puede verificar esto en teléfonos más antiguos?

El código enumerado a continuación,

 // 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); } } 

funcionó bien para mí, de todos modos noté que el número máximo de uri persistente que se otorga a mi aplicación está limitado a 128. Si selecciono más de 128 uri, obtengo el error:

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

justo cuando trato de procesar una imagen para la cual no pude persistir el permiso. ¿Puedes encontrar alguna solución?

Otra forma de evitar los permisos de solicitud es usar SharedPreferences. guarde uri como una cadena (o de otra manera que lo necesite) y recupérelo sin ningún problema.