Открытие файла pdf Ошибка: к этому файлу не удалось получить доступ. Проверьте местоположение или сеть и повторите попытку. Android 6 Marshmallow

Я пытаюсь получить файл с внешнего хранилища, тогда я должен отправить этот файл в PDF-ридеры, используя намерения. Ранее ниже код работал нормально, но после установки Android 6 (обновление Marshmallow) мой код не работает и получает сообщение с тостом

« Не удалось получить доступ к этому файлу. Проверьте местоположение или сеть и повторите попытку ».

(Это связано с новыми разрешениями времени выполнения для Android). Я просто попробовал все решения (поставщики контента и т. Д., Но не работает). Какие-нибудь решения?

File file = new File(getFilesDir(), "myfile.pdf"); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/pdf"); intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); Intent intentChooser = Intent.createChooser(intent, "Choose Pdf Application"); try { startActivity(intentChooser); } catch (ActivityNotFoundException e) { //com.adobe.reader startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.adobe.reader"))); } 

Используйте FileProvider (который в любом случае является общепринятым подходом с Android Nougat – в противном случае вы получите android.os.FileUriExposedException ), а затем не забудьте предоставить разрешения для всех необходимых ему пакетов:

 Uri uri = FileProvider.getUriForFile( context, context.getApplicationContext().getPackageName(), myFile); Intent pdfIntent = new Intent(Intent.ACTION_VIEW); pdfIntent.setDataAndType(apkURI, "application/pdf"); pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); grantAllUriPermissions(context, pdfIntent, apkURI); 

Где grantAllUriPermissions() :

 private void grantAllUriPermissions(Context context, Intent intent, Uri uri) { List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } } 

Рассмотрев вышеприведенные ответы, самое простое решение заключается в следующем.

  Uri pdf = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", file); Intent pdfOpenintent = new Intent(Intent.ACTION_VIEW); pdfOpenintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP); pdfOpenintent.setDataAndType(pdf, "application/pdf"); try { startActivity(pdfOpenintent); } catch (ActivityNotFoundException e) { // handle no application here.... } 

Ключ должен одновременно установить FLAG_GRANT_READ_URI_PERMISSION и FLAG_ACTIVITY_CLEAR_TOP.

Убедитесь, что ваш поставщик указан в ApplicationManifest.xml

 <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> </provider> 

Hers – файл provider_paths

 <?xml version="1.0" encoding="utf-8"?> <paths> <external-path name="external_files" path="."/> </paths> 

Просто нашел рабочее решение как для предыдущих, так и для новых ОС Android:

Шаг 1. Создание имен классов SampleContentProvider

 import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor; import java.io.File; import java.io.FileNotFoundException; /** * Created by naveed on 7/2/16. */ public class SampleContentProvider extends ContentProvider { @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { File privateFile = new File(uri.getPath()); return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY); } @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } } 

Шаг 2. Добавьте поставщика в манифест приложения :

 <provider android:name=".SampleContentProvider" android:authorities="your_package_name" android:exported="true" /> 

Шаг 3: Теперь, наконец, передайте абсолютный путь файла к намерению , используя Uri

  Intent intent = new Intent(Intent.ACTION_VIEW); File file = new File(getFilesDir(), "myfile.pdf"); String absoluteFilePath = file.getAbsolutePath(); String mimeType = "application/pdf"; Uri uri = Uri.parse("content://"+"Your_package_name"+"/" + absoluteFilePath); intent.setDataAndType(uri, mimeType); Intent intentChooser = Intent.createChooser(intent, "Choose Pdf Application"); startActivity(intentChooser); 

Я надеюсь, что это поможет вам. Спасибо всем за вашу помощь.

Пожары намерены обрабатывать файлы известных типов mime, Code:

 private void openFile(Uri fileUri) { String mimeType = mModel.getMimeType(fileUri); if (mimeType != null) { //we have determined a mime type and can probably handle the file. try { /*Implicit intent representing the action we want. The system will determine is it can handle the request.*/ Intent i = new Intent(Intent.ACTION_VIEW); i.setDataAndType(fileUri, mimeType); //We ask the Activity to start this intent. mView.getActivity().startActivity(i); } catch (ActivityNotFoundException e) { /*If we have figured out the mime type of the file, but have no application installed to handle it, send the user a message. */ Toast.makeText(mView.getActivity(), "The System understands this file type," + "but no applications are installed to handle it.", Toast.LENGTH_LONG).show(); } } else { /*if we can't figure out the mime type of the file, let the user know.*/ Toast.makeText(mView.getActivity(), "System doesn't know how to handle that file type!", Toast.LENGTH_LONG).show(); } }