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);
...