无法使用 DownloadManager 从 URL 下载名称中包含国际字符的文件

Cannot download file from URL with international characters in the name using DownloadManager

看来,DownloadManager 没有正确解析 URL 中的国际字符。

private DownloadManager mTestDl;

public void downloadTest() {
    mTestDl = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    BroadcastReceiver br = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);

            DownloadManager.Query q = new DownloadManager.Query();
            q.setFilterById(referenceId);
            Cursor c = mTestDl.query(q);
            if (!c.moveToFirst()) {
                Log.i(TAG, "No downloaded file");
            }
            else {
                c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                for (String cn : c.getColumnNames()) {
                    String value = c.getString(c.getColumnIndex(cn));
                    int intValue = c.getInt(c.getColumnIndex(cn));
                    Log.i(TAG, "XColumn: " + cn + ". Value: " + value + ". int value: " + intValue);
                }
            }
        }
    };

    registerReceiver(br, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

    Uri uri = Uri.parse("http://media.sample.com/video/[요기요]_11월_냠냠냠.mp4");
    DownloadManager.Request request = new DownloadManager.Request(uri);
    long dlid = mTestDl.enqueue(request);
    Log.v(TAG, "download ID: " + dlid);
}

结果是:

XColumn: _id. Value: 4141. int value: 4141
XColumn: local_filename. Value: null. int value: 0
XColumn: mediaprovider_uri. Value: null. int value: 0
XColumn: destination. Value: 2. int value: 2
XColumn: title. Value: . int value: 0
XColumn: description. Value: . int value: 0
XColumn: uri. Value: http://media.sample.com/video/[요기요]_11월_냠냠냠.mp4. int value: 0
XColumn: status. Value: 403. int value: 16
XColumn: hint. Value: null. int value: 0
XColumn: media_type. Value: null. int value: 0
XColumn: total_size. Value: -1. int value: -1
XColumn: last_modified_timestamp. Value: 1446747064114. int value: -656914638
XColumn: bytes_so_far. Value: 0. int value: 0
XColumn: allow_write. Value: 0. int value: 0
XColumn: local_uri. Value: content://downloads/my_downloads/4141. int value: 0
XColumn: reason. Value: placeholder. int value: 403

一般来说,HTTP 状态 403 意味着 "unauthorized access"。在这种情况下,虽然托管是 Amazon S3,但在尝试列出文件夹内容时会给出 403。因此,假设 URL 不正确。

DownloadManager 是否支持下载具有国际名称的文件?

编辑:标题

回答我自己的问题,如果使用 URLEncoder 对 URL 中的文件名进行编码,下载就会成功: 切换此行:

Uri uri = Uri.parse("http://media.sample.com/video/[요기요]_11월_냠냠냠.mp4");

给这个:

Uri uri = Uri.parse("http://media.sample.com/video/" + URLEncoder.encode("[요기요]_11월_냠냠냠.mp4", "UTF-8"));

现在文件下载成功了。我只能使用捕获 HTTP 请求的代理服务器来调试它。 DownloadManager.

没有给出任何提示