Permission denied : opening provider com.google.android.apps.photos.contentprovider.MediaContentProvider that is not exported from uid

纵然是瞬间 提交于 2019-12-01 05:10:17

Use ACTION_OPEN_DOCUMENT in your intent instead of ACTION_PICK. It allows long term, persistent access to files you request.

Intent galleryIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);

Documentation here: https://developer.android.com/guide/topics/providers/document-provider.html

Improving the @Ashton Coulson's answer, you can handle the Kitkat version to use this parameter:

String action;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    action = Intent.ACTION_OPEN_DOCUMENT;
} else {
    action = Intent.ACTION_PICK;
}
Intent intent = new Intent(action, uri);

The if is needed because as stated in the documentation, the Storage Access Framework (SAF) was introduced in Android 4.4 (API level 19).

Create a class name RealPathUtil like below

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class RealPathUtil {

@SuppressLint("NewApi")
public static String getRealPathFromURI_API19(Context context, Uri uri){
    String filePath = "";
    String wholeID = DocumentsContract.getDocumentId(uri);

     // Split at colon, use second item in the array
     String id = wholeID.split(":")[1];

     String[] column = { MediaStore.Images.Media.DATA };     

     // where id is equal to             
     String sel = MediaStore.Images.Media._ID + "=?";

     Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
                               column, sel, new String[]{ id }, null);

     int columnIndex = cursor.getColumnIndex(column[0]);

     if (cursor.moveToFirst()) {
         filePath = cursor.getString(columnIndex);
     }   

     cursor.close();

     return filePath;
}


@SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
      String[] proj = { MediaStore.Images.Media.DATA };
      String result = null;

      CursorLoader cursorLoader = new CursorLoader(
              context, 
        contentUri, proj, null, null, null);        
      Cursor cursor = cursorLoader.loadInBackground();

      if(cursor != null){
       int column_index = 
         cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
       cursor.moveToFirst();
       result = cursor.getString(column_index);
      }

      return result;  
}

public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
           String[] proj = { MediaStore.Images.Media.DATA };
           Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
           int column_index
      = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
           cursor.moveToFirst();
           return cursor.getString(column_index);
}
}

Then you can get the Real path in onActivityResult like

String realPath;
        // SDK < API11
        if (Build.VERSION.SDK_INT < 11)
            realPath = RealPathUtil.getRealPathFromURI_BelowAPI11(this, data.getData());

        // SDK >= 11 && SDK < 19
        else if (Build.VERSION.SDK_INT < 19)
            realPath = RealPathUtil.getRealPathFromURI_API11to18(this, data.getData());

        // SDK > 19 (Android 4.4)
        else
            realPath = RealPathUtil.getRealPathFromURI_API19(this, data.getData());

Resalt:

content://com.android.providers.media.documents/document/image:36

to

/storage/emulated/0/Pictures/JPEG_20190812_163204_299063245992150918.jpg

Hope this was helpful!!

You should take a persistable uri permission:

        Uri uri = intent.getData();

        context.getContentResolver().takePersistableUriPermission(uri
                   , intent.getFlags() 
                          & ( Intent.FLAG_GRANT_READ_URI_PERMISSION 
                          + Intent.FLAG_GRANT_WRITE_URI_PERMISSION 
                          )
                        ); 

you can add this line:

intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(FLAG_GRANT_PERSISTABLE_URI_PERMISSION);

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!