在我们的应用程序OneBusAway Android(Github上的开源)中,当用户拒绝特定的提醒通知时,我们需要收到通知,因此我们不会为同一事件发布另一个提醒通知(他们的总线到达前多长时间)。
我们通过在我们的应用程序中侦听Intent
来做到这一点,该Intent
注册为DeleteIntent
和通知
。当用户拒绝通知时(通过将其滑动或点击通知窗口中的清除按钮),我们的应用程序应该会收到该Intent
。
通过测试,在Google Play上的当前版本(以及Github上的当前主分支)下,我们的应用程序在以下Android版本中似乎从未收到DeleteIntent:
但是,完全相同的代码在以下情况下工作(即,应用程序接收到注册为DeleteIntent的Intent):
我看了以下关于DeleteIntent的帖子,上面列出的解决方案都不适用于Android 4.4.3和4.4.4:
当前工作的主分支使用服务来侦听Intent。但是,根据上面的一些帖子,我确实调整了一些代码,使其更符合使用BroadcastRecencer侦听Intent的工作示例。
使用BroadcastReceiver的代码位于以下Github分支中:
https://github.com/CUTR-at-USF/onebusaway-android/tree/issue104-RepeatingReminders
以下是我当前版本的摘录(该版本仍适用于Android 4.1.2及更低版本,但不适用于4.4.3或4.4.4),以及指向Github源代码的链接:
创建通知
https://github.com/CUTR-at-USF/onebusaway-android/blob/issue104-RepeatingReminders/onebusaway-android/src/main/java/com/joulespersecond/seattlebusbot/tripservice/NotifierTask.java#L131
private Notification createNotification(Uri alertUri) {
//Log.d(TAG, "Creating notification for alert: " + alertUri);
Intent deleteIntent = new Intent(mContext, AlarmReceiver.class);
deleteIntent.setAction(TripService.ACTION_CANCEL);
deleteIntent.setData(alertUri);
return new NotificationCompat.Builder(mContext)
.setSmallIcon(R.drawable.ic_stat_notification)
.setDefaults(Notification.DEFAULT_ALL)
.setOnlyAlertOnce(true)
.setDeleteIntent(PendingIntent.getBroadcast(mContext, 0,
deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT))
.setAutoCancel(true)
.build();
}
标题和其他动态通知信息将在几行之后设置(如果通知未被删除,则稍后重置):
@SuppressWarnings("deprecation")
private void setLatestInfo(Notification notification,
String stopId,
String routeId,
long timeDiff) {
final String title = mContext.getString(R.string.app_name);
final PendingIntent intent = PendingIntent.getActivity(mContext, 0,
new ArrivalsListActivity.Builder(mContext, stopId).getIntent(),
PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(mContext,
title,
getNotifyText(routeId, timeDiff),
intent);
}
TripService
包含操作的常量:
public static final String ACTION_CANCEL =
"com.joulespersecond.seattlebusbot.action.CANCEL";
报警接收器
https://github.com/CUTR-at-USF/onebusaway-android/blob/issue104-RepeatingReminders/onebusaway-android/src/main/java/com/joulespersecond/seattlebusbot/AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
private static final String TAG = "AlarmReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "In onReceive with intent action " + intent.getAction());
...
}
}
Android清单
https://github.com/CUTR-at-USF/onebusaway-android/blob/issue104-RepeatingReminders/onebusaway-android/src/main/AndroidManifest.xml
<receiver android:name=".AlarmReceiver">
<!-- These action names must match the constants in TripService -->
<intent-filter>
<action android:name="com.joulespersecond.seattlebusbot.action.SCHEDULE" />
<action android:name="com.joulespersecond.seattlebusbot.action.POLL" />
<action android:name="com.joulespersecond.seattlebusbot.action.CANCEL" />
</intent-filter>
</receiver>
如上所述,在Android 4.4.3/4.4.4上,当用户拒绝通知时,AlarmReceiver永远看不到意图。
我还尝试添加MIME类型,如在应用程序之间使用隐式意图的自定义操作中所指定的,但这在Android 4.4.3/4.4.4上也不起作用:
Intent deleteIntent = new Intent(mContext, AlarmReceiver.class);
deleteIntent.setAction(TripService.ACTION_CANCEL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
deleteIntent.setDataAndTypeAndNormalize(alertUri, TripService.REMINDER_MIME_TYPE);
} else {
deleteIntent.setDataAndType(alertUri, TripService.REMINDER_MIME_TYPE);
}
return new NotificationCompat.Builder(mContext)
.setSmallIcon(R.drawable.ic_stat_notification)
.setDefaults(Notification.DEFAULT_ALL)
.setOnlyAlertOnce(true)
.setDeleteIntent(PendingIntent.getBroadcast(mContext, 0,
deleteIntent, 0))
//.setLights(0xFF00FF00, 1000, 1000)
//.setVibrate(VIBRATE_PATTERN)
.build();
提醒_MIME_TYPE
是应用程序/vnd。通用域名格式。焦耳秒。seattlebusbot。提醒
使用MIME类型的清单:
<receiver android:name=".AlarmReceiver">
<!-- These action names must match the constants in TripService -->
<intent-filter>
<action android:name="com.joulespersecond.seattlebusbot.action.SCHEDULE" />
<action android:name="com.joulespersecond.seattlebusbot.action.POLL" />
<action android:name="com.joulespersecond.seattlebusbot.action.CANCEL" />
<data android:mimeType="application/vnd.com.joulespersecond.seattlebusbot.reminder" />
</intent-filter>
</receiver>
我还尝试不使用支持库(即使用Notification.Builder
而不是NotificationCompat.Builder
),但这也没有改变任何事情。
知道为什么这在Android4.4.3/4.4.4上不起作用吗?
有关此问题的更多信息,请参阅Github问题。
编辑
我还在一个小型Github项目“DeleteIntentDemo”中复制了这个问题:
https://github.com/barbeau/DeleteIntentDemo
本项目的自述文件中有复制说明。
编辑2
这似乎是由于Android系统在通知中出现了一个错误。setLateStevenInfo()
-我在这里报告过:https://code.google.com/p/android/issues/detail?id=73720
有关解决方法,请参阅@commonware的答案。
编辑3
我的AOSP补丁修复了这个问题,现在已经被合并,所以这个问题不会出现在Android未来版本的遗留应用中:https://code.google.com/p/android/issues/detail?id=73720#c4
然而,在上面的AOSP线程中,强调了不应再使用通知。setLateStevenInfo()
——使用通知。生成器
创建新通知。
你一定有不同的问题,因为我能够在几个4.3和4.4模拟器中接收deleteintent。
我想测试你的“简单”项目,但它使用Android Studio,所以我做了自己的简单测试。
复制的步骤:
-创建一个活动,并在清单中将启动模式设置为singleInstance。
-在按钮或菜单项的处理程序中,启动通知:
Intent deleteIntent = new Intent(this, MainActivity.class);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setOnlyAlertOnce(true)
.setContentTitle("Notification delete intent test")
.setContentText("Please dismiss this notification by swipping or deleting it. A Toast will be shown if the deletion intent works.")
.setDeleteIntent(PendingIntent.getActivity(this, 0, deleteIntent, 0))
.setAutoCancel(true)
.build();
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify((int)System.currentTimeMillis(), notification);
-覆盖onNewIntent
以在通知取消时显示祝酒词或记录消息:
@Override
public void onNewIntent(Intent intent){
Toast.makeText(this, "Notification deleted!", Toast.LENGTH_LONG).show();
}
要取消通知,请轻扫或按清除按钮。按压它不起作用,因为自动取消不被视为显式用户操作,因此不会传递删除意图。
在您的示例项目中,如果删除以下行,deleteIntent
适用于运行4.4.4的Nexus 4:
setLatestInfo(getActivity(), notification, routeId);
我怀疑这个电话正在清除你的deleteIntent
。作为setLatestInfo()
处理的一部分,可以将deleteIntent
重新应用到通知
。
这三个系统都为应用提供了向用户发送通知的API。 Electron允许开发人员使用HTML5 Notification API快速发送通知,并通过当前系统的自带通知API来显示。 注意: 由于这是一个HTML5 API,因此它仅在渲染器进程中可用 1 let myNotification = new Notification('测试标题', { 2 body: '测试通知' 3 }) 4 5
最好的做法是什么,以通知所有的片断,在一些变化的后备栈? 我尝试使用和每个片段订阅事件,然后当发生更改时,主活动向所有订阅者发送post事件。 只有我取消订阅被破坏的片段。 我不喜欢这个解决方案,因为如果backbackback中有很多片段,它可能会同时占用大量的侦听器。 我的应用程序,有无限深入,从一个片段替换到另一个片段(并添加到backstack),您可以再次替换(并添加到backstack
问题内容: 尝试获取SD卡ID时,我在服务onCreate()中遇到问题。使用src-external / android- core中android.os包的FileUtils类。 崩溃日志: 提前致谢! 问题答案: 是平台内部类,用注释。您不应该使用它。
2020年,四大主流浏览器计划不再支持 TLS 1.0 和 1.1。这些旧版本容易受到攻击和利用,不再具备实用性。 通过与 Mozilla 的合作,在你使用的系统中至少有一个仅使用 TLS 1.0 或 1.1,你可以在下面找到它们。 一旦浏览器终止对这些旧协议的支持,该系统将无法建立HTTPS 连接。 现在请尽快启用或升级到 TLS 1.2 或 1.3,以防止中断、停机和用户不满的事件发生。 您的
只能搜到一些早期的,官方文档似乎都没对应关系的表格之类的
问题内容: 我有几个用Swift 2.2编写,用Xcode 7.3编译的应用程序,这些应用程序在App Store上实时运行。这些应用程序利用推送通知,并且在iOS 9.3和更早版本中可以正常运行。 但是,在已升级到iOS 10的设备上,我的应用程序未收到任何推送通知。仍在运行iOS 9的设备仍在接收通知。 考虑到可能是证书或权利问题,我尝试了以下操作:将我的一个应用程序升级到Swift 2.3,