【问题标题】:Android N - Download Manager Notification Cancel ButtonAndroid N - 下载管理器通知取消按钮
【发布时间】:2017-06-21 03:47:52
【问题描述】:

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

提前致谢。

【问题讨论】:

  • 您找到解决方案了吗?我也有同样的问题。

标签: android android-notifications android-download-manager cancel-button


【解决方案1】:

我的解决方案与 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;
      }

【讨论】:

    【解决方案2】:

    我在我的应用中遇到了同样的问题,我必须处理下载通知上的“取消”按钮并从本机 下载 应用删除下载。

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

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

    嗯,很简单:

    1. 从作为参数传递给BroadcastReceiver 的handleReceive 函数的Intent data 获取已取消下载的下载管理器ID (dmid)。
    2. 使用 dmid 查询 DownloadManager 的状态。
    3. DownloadManager 将为该 dmid 返回 null,或者对于所述下载,DownloadManager.STATUS_SUCCESSFUL 列的值将为 false。
    4. 一旦你知道这一点,你就可以为所欲为!

    作为参考,您可以在这里查看我是如何做到的:

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

    【讨论】:

    • 请显示代码,而不是对您的存储库的引用。特别是因为您的代码中有接口和实现,所以访问这些链接的人最终会跳入您的库,只是为了弄清楚getDownload(dmid) 是如何实现的
    【解决方案3】:

    另一种解决方案是使用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();
                                        }
                                    }
                                }
                            }
                        }
                    });
    

    看答案here

    【讨论】:

      【解决方案4】:

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

      不是很好,但它可以完成工作。只有当应用程序在前台时,我才会这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多