DownloadManager下载已完成但文件未存储

时间:2016-02-26 13:20:25

标签: android android-download-manager download-manager

我遇到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

4 个答案:

答案 0 :(得分:0)

我也有这个问题,但是当我改变时它解决了

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

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

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

答案 1 :(得分:0)

我遇到了朱利奥所说的同样的问题。我将收到有关下载已完成但找不到下载文件的通知。我正在使用setDestinationInExternalFilesDir方法。我尝试了M.A.R.建议使用setDestinationInFilesPublicDir,但结果相同;下载完成,但找不到文件。我曾经尝试过一次 setDestinatinonInExternalDir(上下文,“二进制”,“ MyFile”)。当我这样做时,ExternalFileDir中将有一个目录名称“ binary”,但是找不到文件“ MyFile”。

为我解决了问题的方法是将url协议从http://更改为https://。这对我有用,因此我可以下载到ExternalFilesDir。我尚未找到任何文档说明您无法使用http://协议下载。我只能说DownloadManager仅在将协议设置为https://时才起作用。也许您还需要执行其他操作才能使用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://stackoverflow.com/questions/37082354/download-manager-not-working"))
            .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版本之上的某处阅读了该信息,这不是必需的,在此示例中,我不需要添加它。

答案 2 :(得分:0)

我只是遇到了这个线程:

How to solve Android P DownloadManager stopping with "Cleartext HTTP traffic to 127.0.0.1 not permitted"?

我没有尝试过,但是它谈到了使用http发送明文需要做什么。使用https具有隐私和数据完整性的优势。如果下载后添加了自己的代码以进行签名验证,那么您将拥有一个非常安全的频道,但是如果您必须使用http,请尝试使用该解决方案!

答案 3 :(得分:0)

在我的情况下,添加此功能有效(或者检查是否未将其设置为false):

 DownloadManager.Request request = new DownloadManager.Request(uri);
 ...
 request.setVisibleInDownloadsUi(true);
 ...