Search code examples
androiddownloadandroid-download-managerandroid-ion

DownloadManager vs InputStream.read()


I have 2 simple implementation of DownloadManager and custom download task:

  • DownloadManager

    public void onCreate(Bundle savedInstanceState) {
     ...
     mDownloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    }
    
    private void startDownload(String link) 
     Uri uri=Uri.parse(link);
    
     DownloadManager.Request req = new DownloadManager.Request(uri);
    
     req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
            | DownloadManager.Request.NETWORK_MOBILE)
            .setAllowedOverRoaming(false)
            .setVisibleInDownloadsUi(false)
            .setTitle(getString(R.string.app_name))
            .setDescription(getString(R.string.waiting_for_downloading))
            .setDestinationInExternalPublicDir(dataPath,fileName);
    
     lastDownload = mDownloadManager.enqueue(req);
    }
    
    private void queryStatus() {
     Cursor c = mDownloadManager.query(new DownloadManager.Query().setFilterById(lastDownload));
    
     if (c == null) return;
    
     switch (c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS))) {
            case DownloadManager.STATUS_FAILED:
                downloadError();
                break;
            case DownloadManager.STATUS_RUNNING:
                ...
                break;
            case DownloadManager.STATUS_SUCCESSFUL:
                ...
                break;
            default: break;
        }
        c.close();
     }
    
  • custom download task

    new AsyncTask<String, Void, Void>() {
     @Override
      protected Void doInBackground(String... params) {
        try {
          URL url = new URL(params[0]);
          InputStream input = new BufferedInputStream(url.openStream());
          OutputStream output = new FileOutputStream(saveFile);
          byte data[] = new byte[1024];
    
          while ((count = input.read(data)) != -1) {
              output.write(data, 0, count);
          }
          output.flush();
          output.close();
          input.close();
    
        } catch (Exception e) {
             downloadError();
            }
       return null;
      }
    }
    

in general cases both methods works ok, but on some devices (for ex xiaomi android 6) DownloadManager works 2-3 times slower or i got DownloadManager.STATUS_FAILED error. but why? is DownloadManager unstable? or it's smth about settings?

p.s: i would like to use DownloadManager because of customization that i shouldn't implement by myself like set up allowed network or show progress in notification area.

update v0.1

1) I have handler that called queryStatus() check one time per 1 sec.

2) trying to connect to another wi-fi network with nexus phone - DownloadManager works ok, but custom implementation fails...

update v0.2

tried to call AsyncTask downloader from Service (to continue download in case user close the app without canceling process), UI updates via BroadcastReceiver + sendBreadcase() call from the Service - result: downloading became several times slower and now (from time to time) I got an unexpected end of stream exception. [Trying the same files I've downloaded when makes call from Activity]

update v0.3

forgot to notice: DownloadManager fails with 1008 reason = ERROR_CANNOT_RESUME

tried ION also. looks if works better than DownloadManager but some times got an error End of data reached before content length was read: 70385664/77217546

so, still looking the most stable solution...


Solution

  • ok... there was a lot of tests passed with different wi-fi connections and set of devices. ION grant the most stable results.