java - 下载管理器在网络断开和系统重启的情况下无法恢复下载

标签 java android download-manager android-download-manager

我创建了一个简单的应用程序,该应用程序应该下载大型 zip 文件。经过一番研发后,我得出的结论是我必须使用下载管理器来实现这一目标。 我希望在设备重新启动或互联网连接不稳定的情况下自动恢复下载。目前,代码能够按预期下载大文件,但如果互联网连接波动或系统重新启动,它就会停止下载。

Activity :

public class MainActivity extends ActionBarActivity {

    String Download_path = "http://wickedbrains.com/map/mumbai.zip";
     String Download_ID = "DOWNLOAD_ID";

     SharedPreferences preferenceManager;
     DownloadManager downloadManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        preferenceManager = PreferenceManager.getDefaultSharedPreferences(this);
           downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);

           Button btnDownload = (Button)findViewById(R.id.download);
           btnDownload.setOnClickListener(new Button.OnClickListener(){

       @Override
       public void onClick(View arg0) {

        // Locate storage location
            String filepath = "";

            File folder = new File(
                    Environment.getExternalStorageDirectory() + "/osmdroid");
            boolean success = true;
            if (!folder.exists()) {
                success = folder.mkdir();
            }
            if (success) {
                // Do something on success
                filepath = Environment.getExternalStorageDirectory()
                        .getPath() + "/osmdroid";

                // Deleting if zip file exists
                File folder2 = Environment.getExternalStorageDirectory();
                String fileName = folder2.getPath() + "/osmdroid/mumbai.zip";

                File myFile = new File(fileName);
                if(myFile.exists())
                    myFile.delete();

            }


    //Starting download manager to download file
        Uri Download_Uri = Uri.parse(Download_path);
        DownloadManager.Request request = new DownloadManager.Request(Download_Uri);

        long download_id =  downloadManager.enqueue(request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |DownloadManager.Request.NETWORK_MOBILE)
                .setAllowedOverRoaming(false)
                .setTitle("Test")
                .setDescription("Map Download")
                .setDestinationInExternalPublicDir("/osmdroid","mumbai.zip"));

       // long download_id = downloadManager.enqueue(request);

        //Save the download id
        Editor PrefEdit = preferenceManager.edit();
        PrefEdit.putLong(Download_ID, download_id);
        PrefEdit.commit();
       }});
       }

     @Override
     protected void onResume() {
      // TODO Auto-generated method stub
      super.onResume();

      IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
      registerReceiver(downloadReceiver, intentFilter);
     }

     @Override
     protected void onPause() {
      // TODO Auto-generated method stub
      super.onPause();

      unregisterReceiver(downloadReceiver);
     }

     private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {

      @Override
      public void onReceive(Context arg0, Intent arg1) {
       // TODO Auto-generated method stub
       DownloadManager.Query query = new DownloadManager.Query();
       query.setFilterById(preferenceManager.getLong(Download_ID, 0));
       Cursor cursor = downloadManager.query(query);

       if(cursor.moveToFirst()){
        int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
        int status = cursor.getInt(columnIndex);
        int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
        int reason = cursor.getInt(columnReason);

        if(status == DownloadManager.STATUS_SUCCESSFUL){
         //Retrieve the saved download id
         long downloadID = preferenceManager.getLong(Download_ID, 0);

         ParcelFileDescriptor file;
         try {
          file = downloadManager.openDownloadedFile(downloadID);
          Toast.makeText(MainActivity.this,
            "File Downloaded: " + file.toString(),
            Toast.LENGTH_LONG).show();
         } catch (FileNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          Toast.makeText(MainActivity.this,
            e.toString(),
            Toast.LENGTH_LONG).show();
         }

        }else if(status == DownloadManager.STATUS_FAILED){
         Toast.makeText(MainActivity.this,
           "FAILED!\n" + "reason of " + reason,
           Toast.LENGTH_LONG).show();
        }else if(status == DownloadManager.STATUS_PAUSED){
         Toast.makeText(MainActivity.this,
           "PAUSED!\n" + "reason of " + reason,
           Toast.LENGTH_LONG).show();
        }else if(status == DownloadManager.STATUS_PENDING){
         Toast.makeText(MainActivity.this,
           "PENDING!",
           Toast.LENGTH_LONG).show();
        }else if(status == DownloadManager.STATUS_RUNNING){
         Toast.makeText(MainActivity.this,
           "RUNNING!",
           Toast.LENGTH_LONG).show();
        }
       }
      }

     };

    }

我哪里出错了?我应该怎么做才能启用恢复下载功能?

最佳答案

引用自文档,

The download manager will conduct the download in the background, taking care of HTTP interactions and retrying downloads after failures or across connectivity changes and system reboots.

我猜下载管理器默认会处理重试。

如果您遇到问题,可以使用 DownloadManager.Query 类并查询 COLUMN_STATUSCOLUMN_REASON 来获取下载状态

编辑:

开始下载

dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
Request request = new Request( YOUR_DOWNLOAD_URL );
long enqueue = dm.enqueue(request);

enqueue 更像是下载请求 ID。您可以使用该队列来获取下载进度/状态

查询下载状态

Query query = new Query();
query.setFilterById(enqueue);
Cursor c = dm.query(query);
if (c.moveToFirst()) {

    int downloadStatus = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));

    if (DownloadManager.STATUS_SUCCESSFUL == downloadStatus) {
        // download succeded
    } else if (DownloadManager.STATUS_FAILED == downloadStatus){
        String failedReason = c.getString(c.getColumnIndex(DownloadManager.COLUMN_REASON));
        // handle failures
    }
}

我自己没有测试过代码。但它应该可以工作。

关于java - 下载管理器在网络断开和系统重启的情况下无法恢复下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25237176/

相关文章:

android - 在 flutter 中构建应用程序 2 次后构建失败

android - 带有自定义适配器 (BaseAdapter) 的 MultiAutoCompleteTextView

android - 取消正在进行的下载不会删除通知

android - 从 IntentService 显示 ProgressBar 或 Dialog 以获取下载进度

java - 代码工厂方法

java - 当 TestNG 监听器打开时,不会执行 Catch 语句

Android Market 通用应用程序(平板电脑 + 手机)

android - 从捕获的 DownloadManager Intent 中检索文件路径

java - 使用变量调用 onclick 函数

java - 如何在Struts 2中获取内容类型为x-www-form-urlencoded的参数