I would like to have an ongoing notification for my ForegroundService
that requires as small place as possible. I like the "Android System - USB charging this device" style, but I cannot find any example how to achieve this.
Can anyone point me in the right direction?
The style is given to the notification if the channel is assigned the importance IMPORTANCE_MIN
.
It looks like there is no way to use Androids built in style for notifications of IMPORTANCE_MIN
to be used with a ForegroundService
.
Here is the description of IMPORTANCE_MIN
:
Min notification importance: only shows in the shade, below the fold. This should not be used with Service.startForeground since a foreground service is supposed to be something the user cares about so it does not make semantic sense to mark its notification as minimum importance. If you do this as of Android version Build.VERSION_CODES.O, the system will show a higher-priority notification about your app running in the background.
To display a compact single line notification like the charging notification, you have to create a Notification Channel
with priority to IMPORTANCE_MIN.
@TargetApi(Build.VERSION_CODES.O)
private static void createFgServiceChannel(Context context) {
NotificationChannel channel = new NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_MIN);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(channel);
}
And then create an ongoing notification like that:
public static Notification getServiceNotification(Context context) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "channel_id");
mBuilder.setContentTitle("One line text");
mBuilder.setSmallIcon(R.drawable.ic_notification);
mBuilder.setProgress(0, 0, true);
mBuilder.setOngoing(true);
return mBuilder.build();
}
NOTE
Please note that I've tested it with an IntentService
instead of a Service
, and it works. Also I've just checked setting a Thread.sleep()
of 15 seconds and the notification is showing perfectly until the IntentService
stops itself.
There are some images (sorry some texts are in Spanish, but I think the images are still useful):
And if you drag down and opens the notification, it's shown as follows:
EXTRA
If you notice that Android System shows a notification indicating all apps which are using battery (apps with ongoing services), you can downgrade the priority of this kind of notifications and it will appear as one line notifications like the charging notification.
Take a look at this:
Just long click on this notification, and select ALL CATEGORIES:
And set the importance to LOW:
Next time, this "battery consumption" notification will be shown as the charging notification.
You need to set the Notification priority to Min, the Notification Channel importance to Min, and disable showing the Notification Channel Badge.
Here's a sample of how I do it. I've included creating the full notification as well for reference
private static final int MYAPP_NOTIFICATION_ID= -793531;
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
String CHANNEL_ID = "myapp_ongoing";
CharSequence name = context.getString(R.string.channel_name_ongoing);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_MIN);
channel.setShowBadge(false);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notification_add_reminder)
.setContentTitle(context.getString(R.string.app_name))
.setContentText(context.getString(R.string.create_new))
.setOngoing(true).setWhen(0)
.setChannelId(CHANNEL_ID)
.setPriority(NotificationCompat.PRIORITY_MIN);
// Creates an intent for clicking on notification
Intent resultIntent = new Intent(context, MyActivity.class);
...
// The stack builder object will contain an artificial back stack
// for the
// started Activity.
// This ensures that navigating backward from the Activity leads out
// of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MyActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
notificationManager.notify(MYAPP_NOTIFICATION_ID, mBuilder.build());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With