java.lang.SecurityException: отказ в доступе: открытие поставщика com.estrongs.android.pop.app.FileContentProvider
Caused by java.lang.SecurityException: Permission Denial: opening provider com.estrongs.android.pop.app.FileContentProvider from ProcessRecord{341eeb8 5431:xx.xxxx.xxxx/u0a289} (pid=5431, uid=10289) that is not exported from uid 10188
at android.os.Parcel.readException(Parcel.java:1686)
at android.os.Parcel.readException(Parcel.java:1639)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4199)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:5548)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2283)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1517)
at android.content.ContentResolver.query(ContentResolver.java:516)
at android.content.ContentResolver.query(ContentResolver.java:474)
at org.chromium.base.ContentUriUtils.getDisplayName(ContentUriUtils.java:181)
at org.chromium.android_webview.AwWebContentsDelegateAdapter$GetDisplayNameTask.doInBackground(AwWebContentsDelegateAdapter.java:2374)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Код Чтобы открыть файл выбора
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivityForResult(Intent.createChooser(intent, "Open CSV"), READ_REQUEST_CODE);
Шаги, чтобы воспроизвести проблему
1) Открыть галерею для выбора фото
2) В слайд-меню выберите ES File Explore.
3) Теперь работает некоторый URI-файл и происходит сбой файла
Примечание: - FileProvider уже реализован
2 ответа
Кажется, проблема в Nougat(7.1.1) Nexus(проверено!)
Временное решение
из вашего кода вызовите getFilePathFromUri(это, URI)
public static String getFilePathFromUri(Context context, Uri _uri) {
String filePath = "";
if (_uri != null && "content".equals(_uri.getScheme())) {
//Cursor cursor = context.getContentResolver().query(contentURI, null, null, null, null);
//context.revokeUriPermission(_uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(_uri,
new String[]
{
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.MIME_TYPE,
MediaStore.Video.VideoColumns.DATA,
}, null, null, null);
cursor.moveToFirst();
filePath = cursor.getString(0);
} catch (SecurityException e) {
//if file open with third party application
if (_uri.toString().contains("/storage/emulated/0")) {
filePath = "/storage/emulated/0" + _uri.toString().split("/storage/emulated/0")[1];
}
} finally {
if (cursor != null)
cursor.close();
}
} else {
filePath = _uri.getPath();
}
return filePath;
}
Поэтому я скачал приложение (ES File Explorer), с которым у вас были проблемы, и создал демонстрационное приложение, которое его использует. Работает нормально, вот весь необходимый код для решения вашей проблемы:
Сначала настройте код запроса:
private static final int READ_REQUEST_CODE = 42;
Затем установите кнопку, которая вызовет perfromFileSearch()
функция:
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
performFileSearch();
}
});
Теперь создайте свой perfromFileSearch()
функция вызывается обратным вызовом кнопки, показанным выше. Это создаст ваше намеренное действие.
public void performFileSearch()
{
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// Filter to only show results that can be "opened", such as a
// file (as opposed to a list of contacts or timezones)
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filtering files to show only images, using the image MIME data type.
// To search for all documents available via installed storage providers,
// it would be "*/*".
intent.setType("image/*");
// Explicit call to ensure we will get expected results.
startActivityForResult(intent, READ_REQUEST_CODE);
}
Наконец, вот последний кусок головоломки. Мы будем обрабатывать результаты нашего намерения через функцию обратного вызова onActivityResult. В том же упражнении мы добавляем этот фрагмент кода:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData)
{
// The ACTION_GET_CONTENT intent was sent with the request code
// READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
// response to some other intent, and the code below shouldn't run at all.
// This is why we have a conditional statement below :)
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
// The image selected by the user won't be returned in the intent.
// Instead, a URI to the selected image will be contained in the return intent
// provided to this method as a parameter.
// Pull that URI using resultData.getData().
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
// Here I just print the uri to show you that it will not crash.
// We can use this URI to identify our resource (image).
Log.i("MainActivity", "Uri: " + uri.toString());
}
}
}