Android DownloadManager:新下载的文件会自动消失

Android DownloadManager:新下载的文件会自动消失,android,download-manager,Android,Download Manager,我在使用DownloadManager时遇到了一个非常奇怪的问题 我将一些.zip文件下载到/mnt/sdcard/download 调用BroadcastReceiver.onReceive(),并检查下载的文件是否存在,返回true 然而,过了一会儿,文件就不见了 虽然我没有删除它设置了写入外部存储的权限 有什么想法会导致这个问题,或者如何解决它 编辑:以下是代码: public class DownloadUtil { private DownloadTask task = null; p

我在使用DownloadManager时遇到了一个非常奇怪的问题

我将一些.zip文件下载到/mnt/sdcard/download

调用BroadcastReceiver.onReceive(),并检查下载的文件是否存在,返回true

然而,过了一会儿,文件就不见了

虽然我没有删除它设置了写入外部存储的权限

有什么想法会导致这个问题,或者如何解决它

编辑:以下是代码:

public class DownloadUtil {
private DownloadTask task = null;
private long downloadQueueId;
private DownloadManager downloadManager;
private DownloadCallback callback = null;


public DownloadUtil(DownloadCallback callback) {
    this.callback = callback;
}

public interface DownloadCallback {
    public void onDownloadComplete(String filename);
}

/** 
 * Call this to download a file.
 */
public void downloadFile(String address, String destName) {
    if (task != null) {
        return;
    }

    task = new DownloadTask(address, destName);
    task.execute((Void) null);
}

/**
 * Represents an asynchronous login/registration task used to download.
 */
public class DownloadTask extends AsyncTask<Void, Void, Boolean> {
    String address;
    String destName;

    public DownloadTask(String address, String destName) {
        this.address = address;
        this.destName = destName;
    }
    @Override
    protected Boolean doInBackground(Void... params) {
        boolean retVal = true;

        try {
            download(address, destName);
        } catch (Exception e1) {
            retVal = false;
            e1.printStackTrace();
            Log.e("DownloadUtil.java", "Exception downloading: ", e1);
        } 

        return retVal;
    }

    @Override
    protected void onPostExecute(final Boolean success) {
        task = null;

        if (success) {
            // finish();
        } else {

        }
    }

    @Override
    protected void onCancelled() {
        task = null;
    }
}


/**
 * Performs the actual download.
 */
private boolean download(String address, String destName) throws ClientProtocolException, IOException {
    boolean retVal = false;

    BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
        public void onReceive(Context ctxt, Intent intent) {
            String action = intent.getAction();
            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                Query query = new Query();
                query.setFilterById(downloadQueueId);
                Cursor c = downloadManager.query(query);
                if (c.moveToFirst()) {
                    int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
                    if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
                        String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                        Log.i("DownloadUtil.java", "File downloaded to: "+uriString);

                        uriString = uriString.substring(7);
                        File f = new File(uriString);
                        Log.i("DownloadUtil.java", "File: "+uriString+" exits: "+f.exists());
                        callback.onDownloadComplete(uriString);
                    }
                }
                TabLayoutActivity.context.unregisterReceiver(this);
            }
        }
    };

    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(address));
    request.setDescription("Download Request");
    request.setTitle("Download");
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, destName);

    downloadManager = (DownloadManager) TabLayoutActivity.context.getSystemService(Context.DOWNLOAD_SERVICE);
    TabLayoutActivity.context.registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    downloadQueueId = downloadManager.enqueue(request);

    return retVal;
}
公共类下载util{
私有下载任务task=null;
私有长下载队列ID;
私人下载管理器下载管理器;
private DownloadCallback=null;
公共下载util(下载回调){
this.callback=回调;
}
公共接口下载回调{
public void onDownloadComplete(字符串文件名);
}
/** 
*调用此命令下载文件。
*/
公共void下载文件(字符串地址、字符串名称){
如果(任务!=null){
返回;
}
任务=新下载任务(地址、目的地名称);
task.execute((Void)null);
}
/**
*表示用于下载的异步登录/注册任务。
*/
公共类DownloadTask扩展了AsyncTask{
字符串地址;
字符串名称;
公共下载任务(字符串地址、字符串名称){
this.address=地址;
this.destName=destName;
}
@凌驾
受保护的布尔doInBackground(Void…params){
布尔值retVal=true;
试一试{
下载(地址、目的地名称);
}捕获(异常e1){
retVal=false;
e1.printStackTrace();
Log.e(“DownloadUtil.java”,“异常下载:”,e1);
} 
返回返回;
}
@凌驾
受保护的void onPostExecute(最终布尔值成功){
task=null;
如果(成功){
//完成();
}否则{
}
}
@凌驾
受保护的void onCancelled(){
task=null;
}
}
/**
*执行实际下载。
*/
私有布尔下载(字符串地址,字符串destName)抛出ClientProtocolException,IOException{
布尔retVal=false;
BroadcastReceiver onDownloadComplete=新的BroadcastReceiver(){
公共void onReceive(上下文ctxt,意图){
String action=intent.getAction();
if(DownloadManager.ACTION\u DOWNLOAD\u COMPLETE.equals(ACTION)){
查询=新查询();
setFilterById(downloadQueueId);
游标c=downloadManager.query(查询);
if(c.moveToFirst()){
int columnIndex=c.getColumnIndex(DownloadManager.COLUMN_状态);
if(DownloadManager.STATUS_SUCCESSFUL==c.getInt(columnIndex)){
String uriString=c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
Log.i(“DownloadUtil.java”,“文件下载到:”+uriString);
uriString=uriString.substring(7);
文件f=新文件(uriString);
Log.i(“DownloadUtil.java”,“文件:+uriString+”退出:+f.exists());
callback.onDownloadComplete(uriString);
}
}
TabLayoutActivity.context.unregisterReceiver(此);
}
}
};
DownloadManager.Request=newdownloadmanager.Request(Uri.parse(address));
request.setDescription(“下载请求”);
请求。设置标题(“下载”);
setDestinationNexternalPublicDir(Environment.DIRECTORY\u下载,destName);
downloadManager=(downloadManager)TabLayoutActivity.context.getSystemService(context.DOWNLOAD\u服务);
TabLayoutActivity.context.registerReceiver(onDownloadComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
downloadQueueId=downloadManager.enqueue(请求);
返回返回;
}
}


编辑2:此行为是否由远程服务器引起?我刚刚注意到,如果我从我的一台服务器下载完全相同的文件,那么代码运行良好。似乎只有从客户服务器下载文件时才会出现问题。

检查此问题:


是的,这与@Artjom列出的问题有关。DownloadManager中有一个bug,它有时(经常?)会为已经完成的下载发出另一个下载请求。“下载完成”操作也会广播,但由于后续下载失败,它会删除下载条目并另外删除本地文件


我已通过检查文件是否存在(+大小)并将其移动到另一个位置来解决此问题。

它不会显示在您的应用程序或/mnt/sdcard/Download中。文件会显示在应用程序中。如果在BroadcastReceiver.onReceive()处调用file.exists(),则返回true。我甚至可以打开并阅读它的内容。但是,过一会儿file.exists()将返回false(),文件将从/mnt/sdcard/Download中删除。在模拟器上发生。然后你需要粘贴你的代码,这样我们就可以看到发生了什么