I'm developing a chat-like application module which requires on frequent polling (every 3 seconds) to fetch new messages from a server. Currently I'm doing this polling by using a foreground service to manage a separate thread. The
Since this is a foreground service, a notification is required, and I'm setting that up by creating a low priority/importance, so that the notification only shows up as an icon in the status bar.
protected void createNotificationChannel() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, title, NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(title);
channel.setShowBadge(true);
channel.enableVibration(true);
channel.setSound(null, null);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if(notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
}
// showNotification is true if the Notification "peek" should be displayed, and
// false to just display the notification in the status bar
public NotificationCompat.Builder buildNotification(boolean showNotification) {
List<Message> messageList = getMessageList();
Message oldest = messageList.size() > 0 ? messageList.get(0) : null;
Message newest = messageList.size() > 0 ? messageList.get(messageList.size() - 1) : null;
// Create the notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext(), channelId)
// Set notification data and appearance
.setSmallIcon(smallIcon)
.setColor(ContextCompat.getColor(getContext(), R.color.moxie_primary_color))
// Set notification options
.setPriority(showNotification ? NotificationCompat.PRIORITY_HIGH : NotificationCompat.PRIORITY_MIN)
.setDefaults(showNotification ? NotificationCompat.DEFAULT_VIBRATE : 0)
.setDefaults(0)
.setOnlyAlertOnce(false);
// If this is a stacking notification, set up the appropriate notification style
NotificationCompat.MessagingStyle style = new NotificationCompat.MessagingStyle(new Person.Builder().setName("Me").build());
for (Message message : getMessages()) {
style.addMessage(
message.message,
message.when,
new Person.Builder().setName(message.sender).build()
);
}
builder.setStyle(style);
return builder;
}
This works fine when the activity is in the foreground and the notification is silently visible in the status bar and no peek is displayed, which is appropriate because the message is actually displayed live in the chat activity itself.
The problem arises when I move the activity to the background. At that point I want the notification peek to be displayed to the user so they can see (and respond to) the incoming message. So far, I haven't found a way to actually accomplish that. Reposting the notification created by the code above with showNotification
set to true, which changes the priority and defaults doesn't seem to actually work.
Is there any way that I can use a foreground service notification and conditionally show or hide the notification peek?
Is there some better choice for frequent background polling than a foreground service (I was using either Timer
or JobService
depending on OS before, but dropped that because Android 10 results in unduly long delays in polling and complicated the process)? That way I could only post the notification if the activity was in the background and it's priority/importance never need change.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…