5

I have a BroadcastReceiver registered in manifest for ACTION_DOWNLOAD_COMPLETE broadcast.

when I receive this broadcast, I extract download id:

public class DownloadCompleteBroadcastReceiver
    extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent != null) {

            String action = intent.getAction();

            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                handleDownloadCompleteReceiver(context, intent);
            }
        }
    }

    private void handleDownloadCompleteReceiver(Context context, Intent intent) {

        long enqueueId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);

        if (enqueueId != -1) {

            Intent startServiceIntent = new Intent(context, HandleAPKDownloadCompleteIntentService.class);

            startServiceIntent.putExtra(HandleAPKDownloadCompleteIntentService.EXTRA_ENQUEUE_ID, enqueueId);

            context.startService(startServiceIntent);
        }
    }
}

I'm getting a valid value for the enqueueId and starting IntentServiceto handle the file been downloaded:

@Override
protected void onHandleIntent(Intent intent) {

    long enqueueId = intent.getLongExtra(EXTRA_ENQUEUE_ID, -1);

    if (enqueueId == -1) {

        return;
    }

    DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);

    DownloadManager.Query query = new DownloadManager.Query();

    query.setFilterById(enqueueId);

    Cursor c = dm.query(query);

    if (c != null) {

        if (c.moveToFirst()) {

            int statusColumnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
            int downloadManagerDownloadStatus = c.getInt(statusColumnIndex);

            if (DownloadManager.STATUS_SUCCESSFUL == downloadManagerDownloadStatus) {
                ...
                ...
            }
            else if (DownloadManager.STATUS_FAILED == downloadManagerDownloadStatus) {
                ...
                ...
            }
            else {
                reportToGoogleAnalyticsUnexpectedStatus(downloadManagerDownloadStatus);
            }

        }

        c.close();
    }
}

at this point downloadManagerDownloadStatus = 2, which according to the documentation is STATUS_RUNNING

it does not make any sense, because the broadcast ACTION_DOWNLOAD_COMPLETE already been called, so the download should not be running.

I see this happening a lot of times in google analytics, but cannot reproduce.

  • any idea why it happens?

  • any idea how to reproduce?

  • should I consider this state as success or failure of the download?

I really don't understand if consider such download as success or not, because from one side - the download complete broadcast fired, but from the other hand the status is running.

point that worth mentioning: I'm using download manager intensively: starts 10-15 downloads at once in trigger to particular flow in the app,

Thanks in advance.

Tal Kanel
  • 10,475
  • 10
  • 60
  • 98

4 Answers4

2

You mention that you are commencing multiple downloads.

point that worth mentioning: I'm using download manager intensively: starts 10-15 downloads at once in trigger to particular flow in the app,

Now to explain clearly what is happening in the onHandleIntent.

Taken from the android docs

protected abstract void onHandleIntent (Intent intent)

This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().

It is quite possible that you are tripping the DownloadManager.ACTION_DOWNLOAD_COMPLETE with one or more successful downloads, and then the thread is then in a STATUS_RUNNING state, with a multiple of reasons the download is not completing.

As mentioned by the other answer, you may have run out of memory. I'd suggest logging your app at each stage and see exactly what is being downloaded and where it is getting stuck. Then investigate why it is stopping.

2

The behavior seems odd. You could try the below to get just the two cases you are interested in (in addition to the setFilterById()):

query.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL | DownloadManager.STATUS_FAILED);

But this is not going to shine any light on why you are getting what you are getting. I would suggest you add the below log to see what's in that cursor, that will give you a better idea.

DatabaseUtils.dumpCursorToString(cursor)

UPDATE: This is worth checking out: DownloadManager.ACTION_DOWNLOAD_COMPLETE broadcast receiver receiving same download id more than once with different download statuses in Android

Community
  • 1
  • 1
Henry
  • 17,490
  • 7
  • 63
  • 98
1

As I used the DownloadManager before.I think you can pay attention to these points:

1.DownloadManager seems to have relationship with the DownloadProvider.apk,when the process of this app is killed,there maybe will be something wrong with DownloadManager.

2.When you don't have enough storage space,you will have this:

Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR

this kind of situation maybe will tell you the status is Downloads.Impl.STATUS_RUNNING.

ifeegoo
  • 7,054
  • 3
  • 33
  • 38
  • thanks for your answer, but I don't understand.. what is the connection/relation between DownloadsImpl.STATUS_RUNNING to DownloadMnager.STATUS_RUNNIG? they are entirely different consts. – Tal Kanel Oct 11 '15 at 14:18
  • I mean that under the situation that you don't have enough space,this will cause ACTION_DOWNLOAD_COMPLETE,and then you query the status you could get STATUS_RUNNING. – ifeegoo Oct 11 '15 at 15:04
  • did you actually encountered this situation? if yes - did you encountered on particular device? – Tal Kanel Oct 11 '15 at 15:06
  • Oh,no,my friend has occured this situation,and he told me before.I didn't encounter this. – ifeegoo Oct 19 '15 at 10:42
1

I have been using this a couple of times with similar problems. Make sure to double check everything like:

  • android.permission.INTERNET
  • query.setFilterByStatus(DownloadManager.STATUS_PAUSED|DownloadManager.STATUS_PENDING|DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_SUCCESSFUL);
  • Check this good DownloadManager tutorial.

I hope this helps in any way.

Gillsoft AB
  • 4,185
  • 2
  • 19
  • 35