Sea*_*eau 6 java android android-intent android-notifications android-pendingintent
在我们的应用程序OneBusAway Android(Github上的开源)中,我们需要在用户解除特定提醒通知时收到通知,因此我们不会针对同一事件发布另一个提醒通知(他们的公共汽车到达多长时间).
我们通过侦听一个这样Intent在我们的应用程序,注册为DeleteIntent用Notification.当用户解除通知时(通过轻扫通知或点击通知窗口中的清除按钮),我们的应用程序应该收到通知Intent.
从测试来看,似乎使用Google Play上的当前版本(以及Github上的当前主分支),我们的应用程序从未在以下Android版本中收到DeleteIntent:
然而,确切的相同的代码DOES工作(即,登记为DeleteIntent意图是由该应用接收到的)上:
我查看了以下涉及DeleteIntent的SO帖子,并且列出的所有解决方案都不适用于Android 4.4.3和4.4.4:
当前工作的主分支使用服务来侦听Intent.但是,基于上面的一些帖子,我确实调整了一些代码,使其更符合使用BroadcastReceiver监听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源的链接:
创建通知
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();
}
Run Code Online (Sandbox Code Playgroud)
标题和其他动态通知信息稍后设置(如果通知仍未确定,则稍后重置):
@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);
}
Run Code Online (Sandbox Code Playgroud)
TripService 包含操作的常量:
public static final String ACTION_CANCEL =
"com.joulespersecond.seattlebusbot.action.CANCEL";
Run Code Online (Sandbox Code Playgroud)
AlarmReceiver
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());
...
}
}
Run Code Online (Sandbox Code Playgroud)
AndroidManifest
<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>
Run Code Online (Sandbox Code Playgroud)
有了上述内容,在Android 4.4.3/4.4.4上,当用户解除通知时,AlarmReceiver永远不会看到Intent.
我还尝试添加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();
Run Code Online (Sandbox Code Playgroud)
REMINDER_MIME_TYPE 是 application/vnd.com.joulespersecond.seattlebusbot.reminder
使用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>
Run Code Online (Sandbox Code Playgroud)
我也尝试过不使用支持库(即Notification.Builder代替使用NotificationCompat.Builder),但这也没有改变任何东西.
任何想法为什么这不适用于Android 4.4.3/4.4.4?
有关此问题的更多信息显示在Github问题中.
编辑
我还在一个小的Github项目"DeleteIntentDemo"中复制了这个问题:
https://github.com/barbeau/DeleteIntentDemo
重现的说明在本项目的自述文件中.
编辑2
这似乎是由于Android中存在错误Notification.setLatestEventInfo()- 我已在此处报告:https:
//code.google.com/p/android/issues/detail?id = 73720
有关解决方法,请参阅@ CommonsWare的答案.
编辑3
我的AOSP补丁修复此问题现已合并,因此在未来的Android版本中,旧版应用不会出现此问题:https://code.google.com/p/android/issues/detail? id = 73720#c4
但是,在上面的AOSP主题中强调一个人不应再使用Notification.setLatestEventInfo()- 而是Notification.Builder用来创建一个新的通知.
在示例项目中,如果删除以下行,则可以deleteIntent在运行 4.4.4 的 Nexus 4 上运行:
setLatestInfo(getActivity(), notification, routeId);
Run Code Online (Sandbox Code Playgroud)
我怀疑这个电话正在消灭你的deleteIntent. 作为处理的一部分,deleteIntent重新应用您的信息可能会起作用。NotificationsetLatestInfo()
| 归档时间: |
|
| 查看次数: |
3651 次 |
| 最近记录: |