Android N - Download Manager Notification Cancel Button

本小妞迷上赌 提交于 2019-12-18 17:34:32

问题


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.


回答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



回答2:


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.




回答3:


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




回答4:


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;
      }


来源:https://stackoverflow.com/questions/42029895/android-n-download-manager-notification-cancel-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!