Mar*_*ies 18 notifications android android-notifications
我有一个通知,支持播放,前进和后退.
private static Notification createNotification(String interpret, String title, boolean paused) {
// if (builder == null)
builder = new NotificationCompat.Builder(context);
builder.setPriority(Notification.PRIORITY_MAX);
builder.setAutoCancel(false);
builder.setContentTitle(title);
builder.setContentText(interpret);
builder.setOngoing(true);
builder.setOnlyAlertOnce(true);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentIntent(PendingIntent.getActivity(context, 9, new Intent(context, ApplicationActivity.class), Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT));
builder.addAction(R.drawable.av_previous, "", PendingIntent.getBroadcast(context.getApplicationContext(), 0, new Intent(NotificationPlayerControlReceiver.MUSIC_PLAYER_INTENT).putExtra("resultcode", NotificationPlayerControlReceiver.PREVIOUS), PendingIntent.FLAG_CANCEL_CURRENT));
if (paused)
builder.addAction(R.drawable.av_play, "", PendingIntent.getBroadcast(context.getApplicationContext(), 2, new Intent(NotificationPlayerControlReceiver.MUSIC_PLAYER_INTENT).putExtra("resultcode", NotificationPlayerControlReceiver.PLAY), PendingIntent.FLAG_CANCEL_CURRENT));
else
builder.addAction(R.drawable.av_pause, "", PendingIntent.getBroadcast(context.getApplicationContext(), 3, new Intent(NotificationPlayerControlReceiver.MUSIC_PLAYER_INTENT).putExtra("resultcode", NotificationPlayerControlReceiver.PAUSE), PendingIntent.FLAG_CANCEL_CURRENT));
builder.addAction(R.drawable.av_next, "", PendingIntent.getBroadcast(context.getApplicationContext(), 1, new Intent(NotificationPlayerControlReceiver.MUSIC_PLAYER_INTENT).putExtra("resultcode", NotificationPlayerControlReceiver.NEXT), PendingIntent.FLAG_CANCEL_CURRENT));
Notification notification = builder.build();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
notification.tickerView = null;
return notification;
}
Run Code Online (Sandbox Code Playgroud)
更新通知:
public static void update(String interpret, String title, boolean paused) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, createNotification(interpret, title, paused));
}
Run Code Online (Sandbox Code Playgroud)
为了避免在更新时闪烁,我将构建器设置为全局变量,并在每次更新时重复使用它,这非常有用.但重用它,意味着我添加的所有按钮都被重用,并且不可能删除之前添加的操作.
按钮更改只有在每次更新时重新初始化NotificationCompat.Builder时才有效,这意味着我再次闪烁.
如何避免闪烁,但让按钮改变?
编辑:刚刚检查过Rocket Player,他们也没有解决问题,但谷歌播放音乐确实如此
Mar*_*fer 12
就像鲍里斯所说,问题是每次更新都会建立一个新的通知.我的解决方案涵盖相同的逻辑,但我使用NotificationBuilder...
这是代码:
if (mNotificationBuilder == null) {
mNotificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(iconId)
.setContentTitle(title)
.setContentText(message)
.setLargeIcon(largeIcon)
.setOngoing(true)
.setAutoCancel(false);
} else {
mNotificationBuilder.setContentTitle(title)
.setContentText(message);
}
Run Code Online (Sandbox Code Playgroud)
请记住,这mNotificationBuilder是班级中的私人领域.
问题是您每次要更新时都会创建新通知.我遇到了同样的问题,当我做了以下事情时它已修复:
createNotification.码:
private static Notification createNotification(String interpret, String title, boolean paused) {
if (mNotification == null) {
// do the normal stuff you do with the notification builder
} else {
// set the notification fields in the class member directly
... set other fields.
// The below method is deprecated, but is the only way I have found to set the content title and text
mNotification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
}
return mNotification;
}
Run Code Online (Sandbox Code Playgroud)
现在当你打电话时notify不会出现闪烁:
manager.notify(0, createNotification(interpret, title, paused));
Run Code Online (Sandbox Code Playgroud)
PS:我还遇到了一个问题,如果我执行setLatestEventInfo了大大小小的图标被淹没了.这就是我做的原因:
int tmpIconResourceIdStore = mNotification.icon;
// this is needed to make the line below not change the large icon of the notification
mNotification.icon = 0;
// The below method is deprecated, but is the only way I have found to set the content title and text
mNotification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotification.icon = tmpIconResourceIdStore;
Run Code Online (Sandbox Code Playgroud)
查看Adnroid ccode此行mNotification.icon = 0;会禁用图标搞砸.
我知道这是一个相当古老的问题,但由于我没有在其他任何地方找到解决方案,我认为现在回答这个问题可能会帮助其他人解决同样的问题。
这个问题一开始有点棘手。我今天也遇到了,作为我固执的自己,经过一段时间的搜索和尝试,找到了解决方案。
为了与低于 19 的 API 级别兼容,我的解决方案是使用NotificationCompat支持库中的类。
正如其他人所建议的NotificationCompat.Builder那样,只要需要通知,我就会保留对 的引用。我在我的通知中使用的操作仅在最初创建 时添加Builder,而那些将根据情况改变的操作,我也存储在服务的私有成员中。更改后,我会重新使用该Builder对象并NotificationCompat.Action根据我的需要调整该对象。然后我根据 API 级别调用Builder.getNotification()orBuilder.build()方法(由于支持库,可能不需要,但我没有检查。如果我可以省略,请写评论,以便我可以改进我的代码;)
这是我上面刚刚描述的示例代码:
public Notification createForegroundNotification(TaskProgressBean taskProgressBean, boolean indeterminate) {
Context context = RewardCalculatorApplication.getInstance();
long maxTime = TaskUtils.getMaxTime(taskEntry);
long taskElapsedTime = TaskUtils.calculateActualElapsedTime(taskProgressBean);
long pauseElapsedTime = taskProgressBean.getPauseElapsedTime();
int pauseToggleActionIcon;
int pauseToggleActionText;
PendingIntent pauseToggleActionPI;
boolean pauseButton = pauseElapsedTime == 0;
if(pauseButton) {
pauseToggleActionIcon = R.drawable.ic_stat_av_pause;
pauseToggleActionText = R.string.btnTaskPause;
pauseToggleActionPI = getPendingIntentServicePause(context);
} else {
pauseToggleActionIcon = R.drawable.ic_stat_av_play_arrow;
pauseToggleActionText = R.string.btnTaskContinue;
pauseToggleActionPI = getPendingIntentServiceUnpause(context);
}
String contentText = context.getString(R.string.taskForegroundNotificationText,
TaskUtils.formatTimeForDisplay(taskElapsedTime),
TaskUtils.formatTimeForDisplay(pauseElapsedTime),
TaskUtils.formatTimeForDisplay(taskProgressBean.getPauseTotal()));
// check if we have a builder or not...
boolean createNotification = foregroundNotificationBuilder == null;
if(createNotification) { // create one
foregroundNotificationBuilder = new NotificationCompat.Builder(context);
// set the data that never changes...plus the pauseAction, because we don't change the
// pauseAction-object, only it's data...
pauseAction = new NotificationCompat.Action(pauseToggleActionIcon, getString(pauseToggleActionText), pauseToggleActionPI);
foregroundNotificationBuilder
.setContentTitle(taskEntry.getName())
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(getPendingIntentActivity(context))
.setOngoing(true)
.addAction(R.drawable.ic_stat_action_done, getString(R.string.btnTaskFinish), getPendingIntentServiceFinish(context))
.addAction(pauseAction);
}
// this changes with every update
foregroundNotificationBuilder.setContentText(contentText);
if(indeterminate) {
foregroundNotificationBuilder.setProgress(0, 0, true);
} else {
foregroundNotificationBuilder.setProgress((int) maxTime, (int) taskElapsedTime, false);
}
// if this is not the creation but the button has changed, change the pauseAction's data...
if(!createNotification && (pauseButton != foregroundNotificationPauseButton)) {
foregroundNotificationPauseButton = pauseButton;
pauseAction.icon = pauseToggleActionIcon;
pauseAction.title = getString(pauseToggleActionText);
pauseAction.actionIntent = pauseToggleActionPI;
}
return (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
? foregroundNotificationBuilder.getNotification() // before jelly bean...
: foregroundNotificationBuilder.build(); // since jelly bean...
}
Run Code Online (Sandbox Code Playgroud)
变量foregroundNotificationBuilder、pauseAction和foregroundNotificationPauseButton是服务类的私有成员。这些getPendingIntent...()方法是简单地创建PendingIntent对象的便捷方法。
然后当我需要使用 更新通知时调用此方法NotificationManager,并将其移交给服务的startForeground()方法。这解决了闪烁和通知中不可更新操作的问题。
| 归档时间: |
|
| 查看次数: |
5319 次 |
| 最近记录: |