Android N - 下载管理器通知取消按钮

5

Android N在下载管理器通知中新增了一个取消按钮。

我想在我的应用程序中执行一些代码,以便在用户按下此按钮时停止进度条。如果有任何方法被调用,请告诉我是哪个方法。

请注意,Intent过滤操作DownloadManager.ACTION_NOTIFICATION_CLICKED仅在用户单击通知本身时触发,而不是在单击取消按钮时触发。

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

提前感谢。


你找到解决方案了吗?我也有同样的问题。 - Malko
4个回答

1

我在我的应用程序中遇到了同样的问题,需要处理下载通知上的取消按钮以及从本地下载应用程序中删除下载。

事实证明,如果您使用意图过滤器注册接收器:DownloadManager.ACTION_DOWNLOAD_COMPLETE,则始终在启动取消或下载删除时调用它。

那么,如何区分下载完成和下载删除?

嗯,很简单:

  1. 从作为参数传递给您的BroadcastReceiverIntent data中获取已取消下载的下载管理器ID(dmid)。
  2. 使用该dmid查询DownloadManager以获取其状态。
  3. 对于该dmid,DownloadManager将返回null,或者所述下载的DownloadManager.STATUS_SUCCESSFUL列的值将为false
  4. 一旦您知道了这一点,您可以做任何想做的事情!

有关参考,您可以在此处查看我的操作:

我的接收器在AndroidManifest.xml中的声明: https://github.com/edx/edx-app-android/blob/8a75d0dba6b8570956eac5c21c99ecd5020c81ae/OpenEdXMobile/AndroidManifest.xml#L265-L271 我的接收器实际处理这种情况的代码: https://github.com/edx/edx-app-android/blob/d986a9ab64e7a0f999024035ec6fcbdb3428f613/OpenEdXMobile/src/main/java/org/edx/mobile/module/download/DownloadCompleteReceiver.java#L50-L62

3
请提供代码,而不是仅引用您的代码库。特别是因为您的代码中涉及接口和实现,前往这些链接的人最终将跳转到您的库内部,以弄清getDownload(dmid)的实现方式。请确保您的代码易于理解。 - vlatkozelka

0

另一种解决方案是使用 ContentObserver

下载管理器的内容URI应为 content://downloads/my_downloads,我们可以监视此数据库的更改。当您使用下载ID启动下载时,将创建一行 content://downloads/my_downloads/{downloadId}。我们可以检查此光标以了解此任务是否已取消。如果返回的光标为空或null,则在数据库中找不到记录,表示此下载任务已被用户取消。

        // 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();
                                    }
                                }
                            }
                        }
                    }
                });

请查看答案这里


0
Malko,我没有找到解决方案,但与此同时我正在使用以下的解决方法。我使用Android Handler每10秒运行下面的resetProgressIfNoOngoingDMRequest()函数:
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;
}

虽然不太好看,但它能完成任务。而且我只在应用程序在前台时才这样做。


0

我有一个与MiaN KhaLiD非常相似的解决方案。当单击“取消”时,DownloadManager.ACTION_DOWNLOAD_COMPLETE始终被接收器接收。我在接收器中执行以下操作:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接