我遇到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>/
找到它,而下载的文件也没有。那么我的代码有什么问题呢?
其他: 在日志中显示我的下载已完成。
答案 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)
我只是遇到了这个线程:
我没有尝试过,但是它谈到了使用http发送明文需要做什么。使用https具有隐私和数据完整性的优势。如果下载后添加了自己的代码以进行签名验证,那么您将拥有一个非常安全的频道,但是如果您必须使用http,请尝试使用该解决方案!
答案 3 :(得分:0)
在我的情况下,添加此功能有效(或者检查是否未将其设置为false):
DownloadManager.Request request = new DownloadManager.Request(uri);
...
request.setVisibleInDownloadsUi(true);
...