Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/208.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android DownloadManager下载已完成,但未存储文件_Android_Android Download Manager_Download Manager - Fatal编程技术网

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

Android DownloadManager下载已完成,但未存储文件,android,android-download-manager,download-manager,Android,Android Download Manager,Download Manager,我在下载管理器时遇到了奇怪的问题,下载成功,但文件未存储 这是我的代码: try { DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setAllowedNe

我在下载管理器时遇到了奇怪的问题,下载成功,但文件未存储

这是我的代码:

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\u EXTERNAL\u STORAGE
。我尝试将目录更改为
Environment.directory\u DOWNLOADS
,但文件仍然没有存储到DOWNLOADS目录。我试图在
/Android/data/
上找到它,但下载的文件也不在那里。那么我的代码怎么了

其他: 日志中显示我的下载已完成


我也有这个问题,但当我换衣服时它就解决了

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


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

我遇到了与胡里奥所说的相同的问题。我会得到通知,下载完成,但下载的文件找不到。我使用的是SetDestinationNexternalFilesDir方法。我使用setDestinationInFilesPublicDir尝试了M.A.R.建议,但结果是一样的;下载已完成,但找不到文件。有一次我用了 SetDestinationNonExternalDir(上下文,“二进制”、“MyFile”)。当我这样做时,ExternalFileDir中会有一个目录名“binary”,但找不到文件“MyFile”

对我来说,解决问题的方法是将url协议从http://更改为https://。这对我很有用,我可以下载到ExternalFilesDir。我没有发现任何文档说明您不能使用http://protocol下载。我只能说,DownloadManager只有在我将协议设置为https://时才起作用。也许要使用http://protocol,您还需要做一些其他事情。顺便说一下,此更改对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.
}
package com.example.downloader;
导入android.app.DownloadManager;
导入android.content.BroadcastReceiver;
导入android.content.Context;
导入android.content.Intent;
导入android.content.IntentFilter;
导入android.net.Uri;
导入android.os.Bundle;
导入com.google.android.material.floatingactionbutton.floatingactionbutton;
导入androidx.appcompat.app.appcompat活动;
导入androidx.appcompat.widget.Toolbar;
导入android.os.Environment;
导入android.view.view;
导入android.view.Menu;
导入android.view.MenuItem;
导入android.widget.Toast;
导入java.io.File;
公共类MainActivity扩展了AppCompatActivity{
私人长下载ID;
私有文件;
语境;
private BroadcastReceiver onDownloadComplete=新的BroadcastReceiver(){
@凌驾
公共void onReceive(上下文、意图){
//获取随广播接收的下载id
long id=intent.getLongExtra(DownloadManager.EXTRA\u DOWNLOAD\u id,-1);
//通过匹配下载id检查接收的广播是否用于排队下载
if(downloaddid==id){
布尔fileExists=file.exists();
Toast.makeText(MainActivity.this,“下载完成”+文件存在,Toast.LENGTH_SHORT.show();
}
}
};
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
上下文=这个;
setContentView(R.layout.activity_main);
Toolbar Toolbar=findviewbyd(R.id.Toolbar);
设置支持操作栏(工具栏);
FloatingActionButton fab=findViewById(R.id.fab);
fab.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
新线程(){
@凌驾
公开募捐{
beginDownload();
}
}.run();
}
});
//将filter设置为仅在下载完成时,并注册广播接收器
IntentFilter=newintentfilter(DownloadManager.ACTION\u DOWNLOAD\u COMPLETE);
registerReceiver(onDownloadComplete,过滤器);
}
私有void beginDownload(){
file=新文件(getExternalFilesDir(null),“Dummy.txt”);
/*
创建DownloadManager.Request,其中包含启动下载所需的所有信息
*/

//DownloadManager.Request=new DownloadManager.Request(Uri.parse(“http://speedtest.ftp.otenet.gr/files/test10Mb.db)我刚刚遇到了这个问题:


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

在我的例子中,adding此操作有效(或检查您是否未将其设置为false):


您已经在外部存储中提供了文件夹路径
/temp/
。您检查过了吗?@Rohit5k2我检查过了,也没有检查过。。。
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" />
 DownloadManager.Request request = new DownloadManager.Request(uri);
 ...
 request.setVisibleInDownloadsUi(true);
 ...