9

In my app, I am using DownloadManager, for downloading PDF's, which notifies the application via a BroadcastReceiver once the download is completed. My problem is the onReceive() method of BroadcastReceiver is getting called twice. The code is as follows:

In my list adapter, a for loop is run for downloading the selected pdf's. The downloading code is written in another class as follows:

    public static void downloadCheat(final SherlockFragmentActivity activity, final String cheatName, String pathOnServer){

    Request request = new Request(
            Uri.parse(ApplicationConstants.CHEAT_DOWNLOAD_SERVER_URL
                    + "/" + pathOnServer + cheatName + ".pdf"));

    if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
        request.setShowRunningNotification(true);
    }
    else {
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    }

    final DownloadManager dm = (DownloadManager) activity
            .getSystemService(Context.DOWNLOAD_SERVICE);
    final long enqueue = dm.enqueue(request);

    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            long i = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            System.out.println(i);
            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                Query query = new Query();
                query.setFilterById(enqueue);
                Cursor c = dm.query(query);

                if (c.moveToFirst()) {
                    int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
                    if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
                    }
                }
                                    //create custom notification
            }
        }
    };

    activity.registerReceiver(receiver, new IntentFilter(
            DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}

I am trying to add notifications for each pdf download. This works perfectly with download managers own internal notification for HoneyComb and above versions but for GingerBread it does not work and hence I have to push my own custom notification. So I need to determine the exact time when the pdf is downloaded completely. As of now I am able to push my own custom notification but the notifications come twice for every pdf download (As onReceive() is getting twice for each pdf). Can anyone please explain why onReceive() is called twice(for every pdf). Is there any workaround for this? Also could someone please recommend how the broadcast receiver can be un-registered in my case here?The above code is not a part of Activity, so I am not sure how to unregister the receiver.

Thanks for stopping by and reading the post.

andro
  • 977
  • 1
  • 10
  • 21
  • 1
    Is the download id the same value in that two onReceive() calls? downloadid can be got by intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) – StarPinkER Mar 13 '13 at 00:43
  • I checked. When I download two pdf's the download id is same for both pdf's for the first time when onReceive is called(first.pdf -> id =1, second.pdf -> Id = 1). When its automatically called for the second time the download id changes (first.pdf -> Id = 2, second.pdf -> id = 2). So basically I I get to see four print statements printing 1,1,2,2. are the id's supposed to be unique for each pdf download ? – andro Mar 13 '13 at 01:04
  • I'm confused about your first.pdf->id = 1 and second.pdf->id = 1. Can you update your code so I can better understand what is your first and second? – StarPinkER Mar 13 '13 at 01:17
  • The above code chunk is inside a method. This method is called inside a for loop which runs for every pdf to be downloaded. So when I try to download two pdf files the for loop calls the above method twice. the sysout in the above code prints the download id's in the order (1,1,2,2).I think sysout should rpint only two times with unique download id each time. (Code update with sysout statement) – andro Mar 13 '13 at 01:41
  • Did You get the solution to the same? – Pravinsingh Waghela Jul 07 '21 at 07:40

3 Answers3

3

You normally register receivers onResume() and unregister in onPause(). Are you doing so?


I think I may have originally misunderstood what you were trying to do. You should be able to call unregisterReceiver from onReceive. Does this do what you want?

yarian
  • 5,922
  • 3
  • 34
  • 48
  • I am not registering the receiver in onResume(). The BroadcastReceiver is created for every pdf to be downloaded. As I have mentioned earlier, the code is in a separate class and not a part of Activity class. – andro Mar 13 '13 at 00:33
  • I see. I updated my answer. What happens if you unregister the receiver from onReceive? – yarian Mar 13 '13 at 00:45
  • If I try to unregister the receiver inside onReceive(), the application crashes saying "Receiver not registered". Please see my updated question to get an idea in more detail on I am trying to achieve. Thank you for your time. – andro Mar 13 '13 at 01:25
  • Unregistering your receiver in onPause means that your activity will not be able to receive any broadcasts when you go from that activity to another. Very useless. Register them under onCreate and unregister in the onDestroy method. – Johann Jul 07 '13 at 06:52
  • @AndroidDev It's not useless. Many times you only care about the broadcast if a given activity is running. Android recommends you do it this way to cut back unnecessary system overhead, if you can do so. http://developer.android.com/reference/android/content/BroadcastReceiver.html Furthermore, Android recommends you release system resources (and specifically mentions BroadcastReceivers) on the onPause call. http://developer.android.com/training/basics/activity-lifecycle/pausing.html – yarian Jul 07 '13 at 18:42
1

You said you are downloading two pdfs. I only see one Download Request in your method. So I assume what you did is to call that method twice. If that is true, you actually registered two receiver to receive the ACTION_DOWNLOAD_COMPLETE event.

You only need to register once in onCreate or onStart or some methods else. For notification purpose, you can use intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) to get the download id, the id is unique for each download. You can use this id to get the information about the downloaded file and make your file-specific notification.

StarPinkER
  • 14,081
  • 7
  • 55
  • 81
  • Yes, I have called this method twice(once for each pdf to be downloaded). The reason I did this is I want to create a separate notification for each pdf. Is there a way that I can achieve this by using only a single receiver? – andro Mar 13 '13 at 01:29
1

This looks like the same bug that is described here: https://code.google.com/p/android/issues/detail?id=18462

Brill Pappin
  • 4,692
  • 1
  • 36
  • 36