下载管理器下载完成但文件未存储。

6
我遇到了一个与DownloadManager相关的奇怪问题,下载成功了但文件未被存储。以下是我的代码:
try {
    DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
    request.setAllowedOverRoaming(false);
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
    request.setDestinationInExternalFilesDir(context, /temp/, "test.mp4");
    final long downloadId = manager.enqueue(request);
    boolean downloading = true;
    while (downloading) {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(downloadId);
        Cursor cursor = manager.query(query);
        cursor.moveToFirst();
        int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
        int bytesDownloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
        int bytesTotal = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
        if(status==DownloadManager.STATUS_SUCCESSFUL){
            Log.i("Progress", "success");
            downloading = false;
        }
        final int progress = (int) ((bytesDownloaded * 100l) / bytesTotal);
        cursor.close();
        subscriber.onNext(progress);
    }
    subscriber.onCompleted();
}catch (Exception e){
    subscriber.onError(e);
}

我在清单文件中包含了WRITE_EXTERNAL_STORAGE权限。我尝试将目录更改为Environment.DIRECTORY_DOWNLOADS,但文件仍未存储到下载目录中。我尝试在/Android/data/<my package>/中查找它,但下载的文件也不在那里。那么我的代码有什么问题呢?
另外,日志显示我的下载已完成。
请参考以下截图:enter image description here

你在外部存储中给出了文件夹路径 /temp/。你有检查过那里吗? - Rohit5k2
@Rohit5k2 我试过了,也没有找到... - Julio Abdilla
4个回答

7

我也曾遇到过这个问题,但当我改变了

    request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, videoName+".mp4");

to

request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS.toString(), videoName+".mp4");

现在它保存在“下载”文件夹中。

1
我遇到了和 Julio 一样的问题。我会收到下载完成的通知,但是找不到已下载的文件。我使用了 setDestinationInExternalFilesDir 方法。我尝试了 M.A.R. 的建议,使用 setDestinationInFilesPublicDir,但结果仍然相同;下载完成了,但文件无法找到。在一次尝试中,我使用了 setDestinatinonInExternalDir(context,"binary","MyFile")。这样做后,ExternalFileDir 中会有一个名为 "binary" 的目录,但是找不到文件 "MyFile"。
解决问题的方法是将 URL 协议从 http:// 更改为 https://。这对我起作用了,我可以下载到 ExternalFilesDir。我没有找到任何文档说明不能使用 http:// 协议进行下载。我只能说,在我将协议设置为 https:// 后,DownloadManager 才起作用。也许你需要做其他事情才能使用 http:// 协议。顺便说一下,这个更改对 ExternalFileDir 和 ExternalPublicDir 都有效。
以下是我用来测试 DownloadManager 工作情况的示例代码:
package com.example.downloader;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.os.Environment;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import java.io.File;

public class MainActivity extends AppCompatActivity {

    private long downloadID;
    private File file;
    Context context;

    private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            //Fetching the download id received with the broadcast
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);

            //Checking if the received broadcast is for our enqueued download by matching download id
            if (downloadID == id) {
                boolean fileExists = file.exists();
            Toast.makeText(MainActivity.this, "Download Completed " + fileExists, Toast.LENGTH_SHORT).show();
        }

    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            new Thread() {
                @Override
                public void run() {
                    beginDownload();
                }
            }.run();
        }
    });
    //set filter to only when download is complete and register broadcast receiver
    IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    registerReceiver(onDownloadComplete, filter);

}

private void beginDownload(){

    file=new File(getExternalFilesDir(null),"Dummy.txt");
    /*
    Create a DownloadManager.Request with all the information necessary to start the download
     */

    //DownloadManager.Request request=new DownloadManager.Request(Uri.parse("http://speedtest.ftp.otenet.gr/files/test10Mb.db"))   <-- this would not download
    DownloadManager.Request request=new DownloadManager.Request(Uri.parse("https://dev59.com/uZbfa4cB1Zd3GeqPzNJX"))
            .setTitle("Dummy File")// Title of the Download Notification
            .setDescription("Downloading")// Description of the Download Notification
            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)// Visibility of the download Notification
            //.setDestinationInExternalFilesDir(context, null, file.getName())// Uri of the destination file
            .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS.toString(),  file.getName())
            .setRequiresCharging(false)// Set if charging is required to begin the download
            .setAllowedOverMetered(true)// Set if download is allowed on Mobile network
            .setAllowedOverRoaming(true);// Set if download is allowed on roaming network

    DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    downloadID = downloadManager.enqueue(request);// enqueue puts the download request in the queue.
}

这是清单权限:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

我在使用ExternalFileDir或ExternalPublicDir下载位置时,不需要“android.permission.WRITE_EXTERNAL_STORAGE”权限来使此示例正常工作!我在某个地方读到过,在某个Android版本之上,这是不必要的,在这个例子中,我不需要添加它。


0

0
在我的情况下,添加这个代码起作用了(或者检查一下你是否将它设置为 false):
 DownloadManager.Request request = new DownloadManager.Request(uri);
 ...
 request.setVisibleInDownloadsUi(true);
 ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接