Android N - 下载管理器通知取消按钮
Android N - Download Manager Notification Cancel Button
Android N 在下载管理器通知中有一个新的取消按钮。
我想在我的应用程序中执行一些代码,以便在用户按下此按钮时停止进度条。如果有,调用了哪个方法?
另请注意,Intent 过滤器操作 DownloadManager.ACTION_NOTIFICATION_CLICKED 仅在用户单击通知本身时触发,而不是在 he/she 单击“取消”按钮时触发。
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,我没有找到解决方案,但同时我正在使用以下解决方法。
我使用 Android 处理程序 运行 每 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;
}
不太好,但它完成了工作。我只在应用程序在前台时才这样做。
另一个解决方案是使用 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
我在我的应用程序中遇到了同样的问题,我必须处理下载通知上的取消按钮和从本机 下载 应用程序删除下载。
事实证明,如果您使用 Intent 过滤器注册接收器:DownloadManager.ACTION_DOWNLOAD_COMPLETE,它总是在启动取消或下载删除时被调用。
那么,如何区分下载完成和下载删除?
嗯,很简单:
- 从作为参数传递给
BroadcastReceiver
的 handleReceive
函数的 Intent data
获取已取消下载的下载管理器 ID (dmid
)。
- 使用
dmid
查询 DownloadManager 的状态。
- 对于该
dmid
,DownloadManager 将 return 为空,或者对于所述下载,DownloadManager.STATUS_SUCCESSFUL
列的值将是 false
。
- 知道了这个,就可以为所欲为了!
作为参考,您可以在此处查看我是如何做到的:
- 我的接管人在 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
我的解决方案与 MiaN KhaLiD 非常相似。单击 "Cancel" 时,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;
}
Android N 在下载管理器通知中有一个新的取消按钮。
我想在我的应用程序中执行一些代码,以便在用户按下此按钮时停止进度条。如果有,调用了哪个方法?
另请注意,Intent 过滤器操作 DownloadManager.ACTION_NOTIFICATION_CLICKED 仅在用户单击通知本身时触发,而不是在 he/she 单击“取消”按钮时触发。
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,我没有找到解决方案,但同时我正在使用以下解决方法。 我使用 Android 处理程序 运行 每 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;
}
不太好,但它完成了工作。我只在应用程序在前台时才这样做。
另一个解决方案是使用 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
我在我的应用程序中遇到了同样的问题,我必须处理下载通知上的取消按钮和从本机 下载 应用程序删除下载。
事实证明,如果您使用 Intent 过滤器注册接收器:DownloadManager.ACTION_DOWNLOAD_COMPLETE,它总是在启动取消或下载删除时被调用。
那么,如何区分下载完成和下载删除?
嗯,很简单:
- 从作为参数传递给
BroadcastReceiver
的handleReceive
函数的Intent data
获取已取消下载的下载管理器 ID (dmid
)。 - 使用
dmid
查询 DownloadManager 的状态。 - 对于该
dmid
,DownloadManager 将 return 为空,或者对于所述下载,DownloadManager.STATUS_SUCCESSFUL
列的值将是false
。 - 知道了这个,就可以为所欲为了!
作为参考,您可以在此处查看我是如何做到的:
- 我的接管人在 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
我的解决方案与 MiaN KhaLiD 非常相似。单击 "Cancel" 时,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;
}