DownloadManager COLUMN_LOCAL_FILENAME устарел

В Android N я получаю исключение. Это известная проблема в документации, которая просит меня использовать ContentResolver.openFileDescriptor()

https://developer.android.com/reference/android/app/DownloadManager.html#COLUMN_LOCAL_FILENAME

Я не уверен, как использовать. Где здесь объект ContentResolver, который я могу использовать для получения имени файла? Я никогда не использовал его. Поэтому я буду признателен за любую помощь.

08-04 11: 20: 59.765 7010 7290 W System.err: java.lang.SecurityException: COLUMN_LOCAL_FILENAME устарел; вместо этого используйте ContentResolver.openFileDescriptor() вместо

08-04 11: 20: 59.765 7010 7290 W System.err: at android.app.DownloadManager $CursorTranslator.getString(DownloadManager.java:1499)

Вот мой код.

    DownloadManager.Query query = new DownloadManager.Query();
    query.setFilterById(id);
    Cursor cursor = downloadManager.query(query);

    final String downloadFilePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
    cursor.close();

Я попробовал downlaodManager.getFileUri, но это не то, что я ищу. Цените любую помощь.

Спасибо

Ответ 1

Теперь для меня работает следующее:

    String downloadFilePath = null;
    String downloadFileLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
    if (downloadFileLocalUri != null) {
        File mFile = new File(Uri.parse(downloadFileLocalUri).getPath());
        downloadFilePath = mFile.getAbsolutePath();
    }

Ответ 2

Используйте getUriForDownloadedFile для загрузки загруженного Uri.

DownloadManager downloadManager = DownloadManager.class.cast(getSystemService(DOWNLOAD_SERVICE));
Uri uri = downloadManager.getUriForDownloadedFile(id);

Ответ 3

Вы можете уменьшить targetSdk менее 24 в gradle. Обычно этот подход не является рекомендуемым, но мы можем преодолеть эту ошибку, уменьшив целевое значение sdk 23 или что-нибудь (но менее 24).

Ответ 4

String downloadFileLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));

Вышеуказанный метод может вызвать CursorIndexOutOfBoundsException в случае пустого списка строк.

A Курсор - это объект, который помещается перед первой записью. Поэтому мы должны сначала проверить, нет ли вообще результата. Вот мой пример:

int index = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);

if (cursor.moveToFirst()) {
    String downloadFileLocalUri = cursor.getString(index);
    if (downloadFileLocalUri != null) {
        File mFile = new File(downloadFileLocalUri);

        downloadFileName = mFile.getName();
        downloadFilePath = mFile.getAbsolutePath();
    }
}
cursor.close();

Ответ 5

Для тех, кто находит это полезное

Мне пришлось использовать DownloadManager.COLUMN_URI
вместо DownloadManager.COLUMN_LOCAL_URI


Вот мои результаты для каждого соответствующего столбца

Ответ 6

techtinkerer answer также не работал у меня, потому что я не всегда получал URI файла, как указывал CommonsWare, но часто URI содержимого. Но есть несколько способов, по которым вы все равно можете получить файл из URI содержимого.

1) Вы можете вызвать getContentResolver(). openInputStream (myContentUri), чтобы получить входной поток, который затем можно записать в файл, созданный во внешнем или внутреннем хранилище.

2) Вы можете вызвать getContentResolver(). openFileDescriptor (myContentUri, "r" ), чтобы открыть ParcelFileDescriptor только для чтения. Хотя вы не можете получить абсолютный путь к файлу из ParcelFileDescriptor, многие методы, принимающие файлы или URI, также принимают ParcelFileDescriptor.

Например, я использовал DownloadManager для загрузки PDF, затем откройте его с помощью PdfRenderer, конструктор которого принимает ParcelFileDescriptor:

PdfRenderer renderer;
ParcelFileDescriptor pdfFileDescriptor = getContentResolver().openFileDescriptor(pdfUri, "r");
if (pdfFileDescriptor != null) renderer = new PdfRenderer(pdfFileDescriptor);
pdfFileDescriptor.close();

В другом примере BitmapFactory также имеет способ декодирования ParcelFileDescriptor:

(из https://developer.android.com/guide/topics/providers/document-provider.html)

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
    ParcelFileDescriptor parcelFileDescriptor =
        getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();
    return image;
}

Итак, в зависимости от того, что вы хотите сделать, ParcelFileDescriptor может быть всем, что вам нужно.