Android N - Download Manager Notification Cancel Button
Asked Answered
B

4

6

Android N has a new Cancel Button in the Download Manager Notification.

I would like to excecute some code in my app to stop a progressbar when the user presses this button. If any, which method is called?

Please also note that the Intent filter action DownloadManager.ACTION_NOTIFICATION_CLICKED is triggered only when the user clicks on the notification itself, not when he/she clicks of the Cancel button.

 if_downloadManager = new IntentFilter();
    if_downloadManager.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    if_downloadManager.addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED);

    br_downloadManager = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                ....
            }

            if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) {
                // This code is not executed when the user presses the Cancel Button in the Download Manager Notification
            }       
        }
    };

Thanks in advance.

Bond answered 3/2, 2017 at 17:33 Comment(1)
Did you find a solution ? I have the same problem.Hague
Z
1

I had the same problem in my app where I had to handle the Cancel button on the downloads notification and downloads deletion from the native Downloads app.

Turns out that if you register a receiver with the intent filter: DownloadManager.ACTION_DOWNLOAD_COMPLETE, it's always called when the cancel or downloads deletion is initiated.

So, How to differentiate between Download Complete and Download Deletion?

Well, it's quite simple:

  1. Get the Download Manager ID (dmid) of the canceled download from the Intent data that is passed as an argument to the handleReceive function of your BroadcastReceiver.
  2. Using that dmid query the DownloadManager for its status.
  3. The DownloadManager would either return null for that dmidor the value for DownloadManager.STATUS_SUCCESSFUL column would be false for the said download.
  4. Once you know this, you can do whatever you want!

For reference you can see how I did it here:

  1. My Receiver's declaration in AndroidManifest.xml: https://github.com/edx/edx-app-android/blob/8a75d0dba6b8570956eac5c21c99ecd5020c81ae/OpenEdXMobile/AndroidManifest.xml#L265-L271
  2. My Reciever's actual code that handles this case: https://github.com/edx/edx-app-android/blob/d986a9ab64e7a0f999024035ec6fcbdb3428f613/OpenEdXMobile/src/main/java/org/edx/mobile/module/download/DownloadCompleteReceiver.java#L50-L62
Zest answered 22/4, 2018 at 18:18 Comment(1)
Please show code, not references to your repository. Especially since you have interfaces and implementations going on in your code, that whoever goes to those links will end up jumping inside of your library just to figure out how getDownload(dmid) is implementedKilpatrick
B
0

Malko, I did not find a solution but I am using the following workaround meanwhile. I use the Android Handler to run every 10 seconds resetProgressIfNoOngoingDMRequest() below :

public int numberOfOngoingDMRequest() {
    cursor = downloadManager.query(new Query());
    int res = cursor.getCount();
    cursor.close();
    return res;
}

public boolean resetProgressIfNoOngoingDMRequest() {
    if (numberOfOngoingDMRequest() == 0) {
        refreshUpdateAllButton(false);
        resetEpisodesDownloadIds();
        act.misc.notifyEpisodesDataSetChanged();
        return true;
    }
    return false;
}

Not so nice but it does the job. And I do this only if the app is in the foreground.

Bond answered 29/3, 2017 at 3:36 Comment(0)
S
0

Another solution is use ContentObserver.

The content uri for download manager should be content://downloads/my_downloads, we can monitor the changing of this database. When you start a download with a download id, a row will be created content://downloads/my_downloads/{downloadId}. We can check this cursor to know if this task is canceled or not. If the returned cursor is empty or null, no record found in database, this download task is canceled by user.

        // get the download id from DownloadManager#enqueue
        getContentResolver().registerContentObserver(Uri.parse("content://downloads/my_downloads"),
                true, new ContentObserver(null) {
                    @Override
                    public void onChange(boolean selfChange, Uri uri) {
                        super.onChange(selfChange, uri);
                        if (uri.toString().matches(".*\\d+$")) {
                            long changedId = Long.parseLong(uri.getLastPathSegment());
                            if (changedId == downloadId[0]) {
                                Log.d(TAG, "onChange: " + uri.toString() + " " + changedId + " " + downloadId[0]);
                                Cursor cursor = null;
                                try {
                                    cursor = getContentResolver().query(uri, null, null, null, null);
                                    if (cursor != null && cursor.moveToFirst()) {
                                        Log.d(TAG, "onChange: running");
                                    } else {
                                        Log.w(TAG, "onChange: cancel");
                                    }
                                } finally {
                                    if (cursor != null) {
                                        cursor.close();
                                    }
                                }
                            }
                        }
                    }
                });

see the answer here

Shandra answered 15/1, 2018 at 2:18 Comment(0)
L
0

I have solution very similar to MiaN KhaLiD. DownloadManager.ACTION_DOWNLOAD_COMPLETE is always receiver when "Cancel" is clicked. I do that in receiver:

      Cursor cursor = downloadManager.query(query);

      cursor.moveToFirst();

      int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
      int status;
      try {
        status = cursor.getInt(columnIndex);
        KLog.d("download status = " + status);
      } catch (CursorIndexOutOfBoundsException e) {
        KLog.d("cancelled from notification");
        return;
      }
Latonya answered 15/3, 2019 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.