2017-01-17 1 views
4

Все, что я хотел, это открыть файл PDF в моем каталоге внешних загрузок.

Я использовал этот код, чтобы открыть файл, и он работал нормально.Открытие файла в папке загрузок Android N (API 24+)

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() 
      + File.separator + filename); 
    Uri path = Uri.fromFile(file); 
    Intent pdfOpenintent = new Intent(Intent.ACTION_VIEW); 
    pdfOpenintent.setDataAndType(path, "application/" + getExtension(filename)); 
    pdfOpenintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    try { 
     CourseModulesActivity.this.startActivity(pdfOpenintent); 
    } catch (ActivityNotFoundException e) { 
     pdfOpenintent.setType("application/*"); 
     startActivity(Intent.createChooser(pdfOpenintent, "No Application found to open File - " + filename)); 
    } 

Сейчас в андроида N (API 24+), он выходит из строя говоря android.os.FileUriExposedException

Я следовал по ссылке - https://stackoverflow.com/a/38858040/4788557 и https://developer.android.com/training/secure-file-sharing/share-file.html#ShareFile конвертировать мой код это -

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() 
      + File.separator + filename); 
    Uri path = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", file); 
    Intent pdfOpenintent = new Intent(Intent.ACTION_VIEW); 
    pdfOpenintent.setData(path); 
    pdfOpenintent.setType("application/" + getExtension(filename)); 
    pdfOpenintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    pdfOpenintent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    try { 
     CourseModulesActivity.this.startActivity(pdfOpenintent); 
    } catch (ActivityNotFoundException e) { 
     pdfOpenintent.setType("application/*"); 
     startActivity(Intent.createChooser(pdfOpenintent, "No Application found to open File - " + filename)); 
    } 

и добавил поставщик xml as -

<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
<external-path name="external_files" path="."/> 
</paths> 

и проявляется как -

<manifest...> 
.... 
<application...> 
.... 
    <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> 
.... 
</application> 

Итак, теперь приложение не врезаться на N, но приложения PDF не удается открыть файл.
Любая помощь в этом направлении?

ответ

2

Я использовал этот код, чтобы открыть файл, и для его работы он отлично работает.

Есть по крайней мере две ошибки в этом коде:

  • "application/" + getExtension(filename) не является соответствующий алгоритм для нахождения типа MIME для файла, так как не все типы MIME начинаются с application/ (например, image/jpeg , text/plain). Используйте MimeTypeMap.

  • setType() clears the data previously set on the Intent, поэтому ваш Intent не имеет Uri.

Plus, не следует использовать конкатенацию, чтобы построить путь к файлу, так как ваш код не обрабатывает случай, когда кто-то решил иметь DIRECTORY_DOWNLOADS конец в /. Заменить:

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() 
     + File.separator + filename); 

с:

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fiename); 

но приложения PDF не удается открыть файл

Там нет в вашем Intent не Uri, так как ваш второй фрагмент кода содержит та же ошибка, что и первый фрагмент кода. Используйте setDataAndType() для установки как Uri, так и типа MIME за один раз. Или просто используйте setData() и избавляйтесь от setType(), так как FileProvider будет использовать MimeTypeMap для определения типа MIME.

FWIW, this sample app демонстрирует использование FileProvider, чтобы служить PDF-файлу для просмотра PDF-файлов.

+1

все это конкретные типы приложений pdf/xlxs и т. Д. Файлы ... Настоящая ошибка была 'setDataAndType()' Спасибо. – Harshit

Смежные вопросы