2016-10-17 10 views
1

< Смотрите важные редактирует ниже>Проблема с «файлом» в Uri: получить размер файла, открыть PDF в внешнем просмотре и открыть входной поток (по сравнению с «контентом» схемы)?

Когда я открываю PDF в мое приложение в комплект поставки URI может быть 2 схемы: "файл" и "содержания":

  • Использование Dropbox : файл: ///data/data/com.dropbox.android/global/external/docpreviews/test2.pdf

  • Использование Google Drive: содержание : // СМИ/внешний/файл/142

С «содержание» вся моя функциональность работает, как ожидалось, но с «файл» я встречаю некоторые проблемы:

  1. Я понятия не имею, как получить размер файла PDF.
  2. Открытие PDF-файла во внешнем редакторе PDF приводит к ошибке, например, «невозможно открыть файл» (независимо от того, является ли это Dropbox, Google Диском или любым другим приложением).
  3. Открытие входного потока (для преобразования PDF в байт []) также вызывает проблемы: FileNotFoundException.

Возможным решением было бы преобразовать «файл» в «контент», тогда я был бы очень доволен. Я искал его некоторое время, но не могу понять, как, так что, я думаю, это невозможно. Итак, как решить эти 3 проблемы?

Мои AndroidManifest:

<activity android:name=".activities.PdfActivity" 
.... 
    <intent-filter android:label="Open PDF"> 
    <action android:name="android.intent.action.SEND"/> 
    <category android:name="android.intent.category.DEFAULT"/> 
    <data android:mimeType="application/pdf"/> 
    </intent-filter> 
</activity> 

В PdfActivity я собирать Uri:

uri = intent.getParcelableExtra(Intent.EXTRA_STREAM) 

1) Тогда получим размер файла:

switch (uri.getScheme()) { 
    case "file": 
    // How to get the filesize here? 
    break; 
    case "content": 
    // Get filesize using cursor 
    Cursor cursor = getContentResolver().query(uri, new String[]{MediaColumns.SIZE}, null, null, null); 
    cursor.moveToFirst(); 
    size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaColumns.SIZE)); 
    cursor.close(); 
    break; 
} 

2) Открытие PDF во внешнем средстве просмотра с этим кодом:

Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setDataAndType(uri, "application/pdf"); 
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

try { 
    startActivity(intent); 
} catch (ActivityNotFoundException e) { 
    // Show dialog: no PDF viewer on device 
} 

3) Преобразование PDF в байт [] с помощью InputStream:

public byte[] getByteArrayFromPdf(Uri uri) throws IOException { 
    InputStream inputStream = null; 
    try { 
     switch (uri.getScheme()) { 
      case "file": 
      // How to do this? 
      break; 
      case "content": 
      inputStream = getContentResolver().openInputStream(uri); 
      break; 
      default: 
      // Something going wrong... 
     } 
     return getByteArrayUsingInputStream(inputStream); 
    } finally { 
     if (inputStream != null) { 
      inputStream.close(); 
     } 
    } 
} 

редактирует: Мой файл сохраняется в папке загрузки (отсюда и контент-URI из Google Drive).

getContentResolver(). OpenInputStream (URI) вызывает FileNotFoundException для "файл" схемы. Хотя оба uri-схемы берутся из этого же файла. Это означает, что FileNotFoundException должен быть результатом чего-то другого, кроме файла, который не существует.

Видимо, это вызвано libcore.io.ErrnoException: open failed: EACCES (Permission denied), что имеет больше смысла, когда я просматриваю uri (файл) из Dropbox: появляется dropbox, открывает файл и сохраняет его в com.dropbox.android, в котором я не иметь доступ. Думаю, это объясняет все проблемы, правда?

FINAL EDIT: Как уже говорилось выше, это, вероятно, проблема с уединении файла, сделанного Dropbox PDF Viewer приложение, потому что с Adobe (и других приложений, которые также приводят к URI с «файл») У меня нет никаких проблем: новый файл (uri.getPath()). Length() дает мне размер файла, и получение входного потока работает так же, как с «содержанием» uri's.

Но это дает мне новый вопрос: это возможно для меня: открытие внешнего файла PDF (например, загрузка карты) с помощью приложения Dropbox, «Отправить PDF», чтобы открыть его в моем приложении, а затем каким-то образом получить доступ к этому файлу, чтобы я мог прочитать размер, открыть его в другом приложении для просмотра PDF и преобразовать его во входной поток?

пс. возможны ли другие схемы uri при открытии PDF-файла в моем приложении?

ответ

0

Я понятия не имею, как получить размер файла PDF

Вызов getPath() на Uri. Обмотайте этот путь в объекте File и вызовите length() на объект File.

Или замените существующий код на DocumentFile. Используйте fromSingleUri() для схемы content и fromFile() для схемы file. Затем позвоните по телефону getSize() по телефону DocumentFile.

Открытие PDF-файла во внешнем просмотрщике PDF приводит к ошибке, например, «невозможно открыть файл» (независимо от того, является ли это Dropbox, Google Диском или любым другим приложением).

Другие приложения не имеют прав на контент. Вы можете попытаться передать права, добавив FLAG_GRANT_READ_URI_PERMISSION в Intent.

Открытие входного потока (для преобразования PDF в байт []) также вызывает проблемы: FileNotFoundException.

Вы не видите код, предоставляющий вам это исключение. openInputStream() поддерживает схемы file и content, поэтому используйте их для обоих случаев.

+0

К сожалению, не работает: 1) File.length(), возвращает * 0 *. При использовании documentFile, * fromSingleUri * возвращает * null * (и, я думаю, вы имеете в виду .length() в DocumentFile вместо size()?) ... 2) Флаг не имеет значения ... 3) Я использовал openInputStream для «файла», который вызвал FileNotFoundException (я уточнил свой пост, описывающий это). На востоке последнее решение должно работать, может быть, Исключение дает нам подсказку? Может быть, это действительно не существует в этом ури? Ну, я открыл этот * тот же * PDF с обоими программами просмотра PDF (один дает «файл», другой «контент»), поэтому это не должно быть возможным. –

+1

@PKuijpers: 'Uri', который Dropbox дает вам, - это тот, к которому вы не можете получить доступ, из-за некоторой ошибки в своем приложении. «возможно ли, чтобы я ..."- вы, безусловно, можете использовать' ACTION_SEND' '<намерение-фильтр>' для '' для получения файлов PDF, если это то, что вы имеете в виду ... но у вас уже есть это. Итак, попробуйте этот поток и посмотрите, что вы получаете из своего выбранного приложения для просмотра PDF. Обратите внимание, что не все пользователи PDF могут предлагать опцию «share». «Существуют ли другие схемы uri при открытии PDF-файла в моем приложении таким образом?» - обязательно. http ',' https', 'android.resource' - три. – CommonsWare

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

  • Нет связанных вопросов^_^