DownloadManager.addCompletedDownload() 在 Android Q 上已弃用

Ste*_*ley 17 android android-download-manager

最近升级到 API 29 时,我的代码:

downloadManager.addCompletedDownload(downloadFilename,
    downloadFilename, true, saveInfo.mimeType,
    downloadPath, outputFile.length(), true)
Run Code Online (Sandbox Code Playgroud)

…现在产生弃用警告:

警告:'addCompletedDownload(String!, String!, Boolean, String!, String!, Long, Boolean): Long' 已弃用。在 Java 中已弃用

DownloadManager.addCompletedDownload 的 API 文档说:

此方法在 API 级别 29 中已弃用。应用程序应改为将文件提供给 MediaStore.Downloads 集合,以使其作为下载的一部分可供用户使用。

但是,我一直无法找到有关 MediaStore.Downloads 应该如何用作替代品的代码示例。该MediaStore.Downloads文件基本上是不存在的,而MediaStore文档提供无明显指引。

任何人都可以为上述代码提供符合 API 29 的替代品吗?

W0r*_*0le 13

更新

在 Android 10 (Q) 中,您必须使用该MediaStore概念。我做了一些测试,似乎使用下载管理器下载的文件(并存储在默认的“下载”文件夹中)会自动添加到MediaStore.Downloads数据库中。因此,您不需要像我下​​面描述的那样手动添加它们。在任何情况下,下面都有一段代码,您可以在其中插入数据MediaStore.Downloads

原答案

您必须更新MediaStore.Downloads集合。这样,您的文件将在Downloads文件夹中可见。在 Android Q 中,您不再需要更新DownloadManager而是MediaStore.Downloads集合。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    // You can add more columns.. Complete list of columns can be found at 
    // https://developer.android.com/reference/android/provider/MediaStore.Downloads
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.Downloads.TITLE, /* FILE_NAME */);
    contentValues.put(MediaStore.Downloads.DISPLAY_NAME, /* DISPLAY NAME */);
    contentValues.put(MediaStore.Downloads.MIME_TYPE, /* MIME TYPE */);
    contentValues.put(MediaStore.Downloads.SIZE, /* FILE SIZE */);

    // If you downloaded to a specific folder inside "Downloads" folder
    contentValues.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + File.separator + "Temp");

    // Insert into the database
    ContentResolver database = getContentResolver();
    database.insert(Downloads.EXTERNAL_CONTENT_URI, contentValues);
} else {
    DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    if (downloadManager != null) {
        downloadManager.addCompletedDownload(downloadFilename, downloadFilename, true, 
                                  saveInfo.mimeType, downloadPath, outputFile.length(), true)
    }
}
Run Code Online (Sandbox Code Playgroud)

注意以下差异

把这当成是一粒盐,因为我还在检查以下几点:

1 - 不再显示通知。我猜你现在有责任通知用户了。

2 -MediaStore.Downloads集合仅接受“/下载”文件夹下的文件。因此,这会影响下载位置。

要确认插入的位置等,您可以按如下方式转储数据库:

public void dumpDb() {
    DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    if (downloadManager != null) {
        Cursor cursor = downloadManager.query(new DownloadManager.Query());
        Log.e("TESTS", "DownloadManager dump start");
        while(cursor.moveToNext()) {
            Log.e("TESTS", "Title: " + cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE))
                    + " status: " + cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
                    + " id: " + cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID)));
        }
        Log.e("TESTS", "DownloadManager dump end");
        cursor.close();
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        ContentResolver contentResolver = getContentResolver();
        if (contentResolver != null) {
            Cursor cursor = contentResolver.query(Downloads.EXTERNAL_CONTENT_URI, null, null, null);
            Log.e("TESTS", "MediaStore Collection Dump start");
            if (cursor != null) {
                Log.e("TESTS", DatabaseUtils.dumpCursorToString(cursor));
                cursor.close();
            }

            Log.e("TESTS", "MediaStore Collection Dump end");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)