Notifications not working on Api 27(8.1.0) - android

Notifications are working for Oreo 8.0(Api 26) and below perfectly fine but they are not working with Oreo 8.1.0.
below is the stack trace of an error
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 actions=2 vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
I am creating Notification channel for Oreo still it's not working for Oreo 8.1.0. I also refer other stack overflow link but not getting any clue why this error occuring in my case.
UpdateAlarmActivity.java
public class UpcomingAlarmReceiver extends BroadcastReceiver {
public static final String TAG = "UpcomingAlarmReceiver";
public static final String ACTION_DISMISS_NOW = "com.funswitch.funrooster.action.DISMISS_NOW";
public static final String ACTION_CANCEL_NOTIFICATION = "com.funswitch.funrooster.action.CANCEL_NOTIFICATION";
public static final String ACTION_SHOW_SNOOZING = "com.funswitch.funrooster.action.SHOW_SNOOZING";
public static final String EXTRA_ALARM = "com.funswitch.funrooster.extra.ALARM";
public static final String CHANNEL_NAME = "CHANNEL_NOTIFICATION";
String NOTIFICATION_CHANNEL_ID = "io.funswitch.funrooster.Channel";
#Override
public void onReceive(final Context context, final Intent intent) {
final byte[] alarmBytes = intent.getByteArrayExtra(EXTRA_ALARM);
// Un-marshall the bytes into a parcel and create our Alarm with it.
final Alarm alarm = ParcelableUtil.unmarshall(alarmBytes, Alarm.CREATOR);
if (alarm == null) {
throw new IllegalStateException("No alarm received");
}
final long id = alarm.getId();
final NotificationManager nm = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
final boolean actionShowSnoozing = ACTION_SHOW_SNOOZING.equals(intent.getAction());
if (intent.getAction() == null || actionShowSnoozing) {
// Prepare notification
// http://stackoverflow.com/a/15803726/5055032
// Notifications aren't updated on the UI thread, so we could have
// done this in the background. However, no lengthy operations are
// done here, so doing so is a premature optimization.
String title;
String text;
if (actionShowSnoozing) {
if (!alarm.isSnoozed()) {
throw new IllegalStateException("Can't show snoozing notif. if alarm not snoozed!");
}
title = alarm.getLabel().isEmpty() ? context.getString(R.string.alarm) : alarm.getLabel();
text = context.getString(R.string.title_snoozing_until,
formatTime(context, alarm.snoozingUntil()));
} else {
// No intent action required for default behavior
title = context.getString(R.string.upcoming_alarm);
text = formatTime(context, alarm.ringsAt());
}
Intent dismissIntent = new Intent(context, UpcomingAlarmReceiver.class)
.setAction(ACTION_DISMISS_NOW)
.putExtra(EXTRA_ALARM, ParcelableUtil.marshall(alarm));
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
PendingIntent piDismiss = PendingIntent.getBroadcast(context, (int) id,
dismissIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mBuilder
.setSmallIcon(R.drawable.ic_alarm_24dp)
.setContentTitle(title)
.setContentText(text)
.addAction(R.drawable.ic_dismiss_alarm_24dp,
context.getString(R.string.dismiss_now), piDismiss);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CHANNEL_NAME, importance);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setSound(null, null);
notificationChannel.setShowBadge(false);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
assert nm != null;
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
nm.createNotificationChannel(notificationChannel);
}
Objects.requireNonNull(nm).notify(TAG, (int) id, mBuilder.build());
} else if (ACTION_CANCEL_NOTIFICATION.equals(intent.getAction())) {
Objects.requireNonNull(nm).cancel(TAG, (int) id);
} else if (ACTION_DISMISS_NOW.equals(intent.getAction())) {
new AlarmController(context, null).cancelAlarm(alarm, false, true);
}
}
}
Above is my Java class where I am implementing the code for Notifications. Please help me out or give me some suggestions how can I resolve this error.

In api level 27 google changed the notification methods now in api 27 or upper level you need to create notification channel to send notification.
Channel is categories all types of notifications learn more about notification channel
check this for notification channel
**if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String id = "id_product";
// The user-visible name of the channel.
CharSequence name = "Product";
// The user-visible description of the channel.
String description = "Notifications regarding our products";
int importance = NotificationManager.IMPORTANCE_MAX;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// Configure the notification channel.
mChannel.setDescription(description);
mChannel.enableLights(true);
// Sets the notification light color for notifications posted to this
// channel, if the device supports this feature.
mChannel.setLightColor(Color.RED);
notificationManager.createNotificationChannel(mChannel);
}**

Change your NotificationCompat.Builder constructor:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
adding the channel id:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)

Related

FirebaseMessagingService push notification creation - how to set icon?

I want to set icon for my push notification which is created by FirebaseMessagingService. Problem is that these notifications are created by system internally (probably in function onStartCommand() which is final and I don't have access to it. I don't know from which source is icon for this notification set. Normally if you create notification you can set icon by NotificationManager, but this process is done internally by Firebase. Reason why I want to change icon is because my icon for app has transparent background (its vector drawable (.svg). But for some reason it is shown as square.
Is there any way how to modify notification icon inside FirebaseMessagingService?
Use this Function for display notification
public void showNotificationMessage(final String title, final String message,Intent intent) {
Random random = new Random();
NotificationManager notifManager = null;
if (notifManager == null) {
notifManager = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
}
NotificationCompat.Builder mBuilder=null;
if (TextUtils.isEmpty(message))
return;
final int icon = R.mipmap.ic_launcher;
String notificationId = String.format("%04d", random.nextInt(10000));
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
Integer.parseInt(notificationId),
intent,
PendingIntent.FLAG_CANCEL_CURRENT
);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = notifManager.getNotificationChannel("Test");
if (mChannel == null) {
mChannel = new NotificationChannel("Test", title, importance);
mChannel.enableVibration(true);
notifManager.createNotificationChannel(mChannel);
}
mBuilder = new NotificationCompat.Builder(mContext, "Test");
}else{
mBuilder = new NotificationCompat.Builder(mContext, "Test");
}
Notification notification;
notification = mBuilder.setTicker(title)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
//.setStyle(inboxStyle)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Integer.parseInt(notificationId), notification);
}

Bad notification for startForeground for Android 9 [duplicate]

After upgrading my phone to 8.1 Developer Preview my background service no longer starts up properly.
In my long-running service I've implemented a startForeground method to start the ongoing notification which is called in on create.
#TargetApi(Build.VERSION_CODES.O)
private fun startForeground() {
// Safe call, handled by compat lib.
val notificationBuilder = NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.build()
startForeground(101, notification)
}
Error message:
11-28 11:47:53.349 24704-24704/$PACKAGE_NAMEE/AndroidRuntime: FATAL EXCEPTION: main
Process: $PACKAGE_NAME, PID: 24704
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=My channel pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x42 color=0x00000000 vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
invalid channel for service notification, apparently my old channel the DEFAULT_CHANNEL_ID is no longer appropriate for API 27 I assume. What would be the proper channel? I've tried to look through the documentation
After some tinkering for a while with different solutions i found out that one must create a notification channel in Android 8.1 and above.
private fun startForeground() {
val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel("my_service", "My Background Service")
} else {
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
""
}
val notificationBuilder = NotificationCompat.Builder(this, channelId )
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build()
startForeground(101, notification)
}
#RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(channelId: String, channelName: String): String{
val chan = NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_NONE)
chan.lightColor = Color.BLUE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(chan)
return channelId
}
From my understanding background services are now displayed as normal notifications that the user then can select to not show by deselecting the notification channel.
Update:
Also don't forget to add the foreground permission as required Android P:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Java Solution (Android 9.0, API 28)
In your Service class, add this:
#Override
public void onCreate(){
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
private void startMyOwnForeground(){
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.icon_1)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
UPDATE: ANDROID 9.0 PIE (API 28)
Add this permission to your AndroidManifest.xml file:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
The first answer is great only for those people who know kotlin, for those who still using java here I translate the first answer
public Notification getNotification() {
String channel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
channel = createChannel();
else {
channel = "";
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channel).setSmallIcon(android.R.drawable.ic_menu_mylocation).setContentTitle("snap map fake location");
Notification notification = mBuilder
.setPriority(PRIORITY_LOW)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
return notification;
}
#NonNull
#TargetApi(26)
private synchronized String createChannel() {
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
String name = "snap map fake location ";
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = new NotificationChannel("snap map channel", name, importance);
mChannel.enableLights(true);
mChannel.setLightColor(Color.BLUE);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(mChannel);
} else {
stopSelf();
}
return "snap map channel";
}
For android, P don't forget to include this permission
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Works properly on Andorid 8.1:
Updated sample (without any deprecated code):
public NotificationBattery(Context context) {
this.mCtx = context;
mBuilder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle(context.getString(R.string.notification_title_battery))
.setSmallIcon(R.drawable.ic_launcher)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setChannelId(CHANNEL_ID)
.setOnlyAlertOnce(true)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setWhen(System.currentTimeMillis() + 500)
.setGroup(GROUP)
.setOngoing(true);
mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_view_battery);
initBatteryNotificationIntent();
mBuilder.setContent(mRemoteViews);
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (AesPrefs.getBooleanRes(R.string.SHOW_BATTERY_NOTIFICATION, true)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, context.getString(R.string.notification_title_battery),
NotificationManager.IMPORTANCE_DEFAULT);
channel.setShowBadge(false);
channel.setSound(null, null);
mNotificationManager.createNotificationChannel(channel);
}
} else {
mNotificationManager.cancel(Const.NOTIFICATION_CLIPBOARD);
}
}
Old snipped (it's a different app - not related to the code above):
#Override
public int onStartCommand(Intent intent, int flags, final int startId) {
Log.d(TAG, "onStartCommand");
String CHANNEL_ONE_ID = "com.kjtech.app.N1";
String CHANNEL_ONE_NAME = "Channel One";
NotificationChannel notificationChannel = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
notificationChannel = new NotificationChannel(CHANNEL_ONE_ID,
CHANNEL_ONE_NAME, IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setShowBadge(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
}
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Notification notification = new Notification.Builder(getApplicationContext())
.setChannelId(CHANNEL_ONE_ID)
.setContentTitle(getString(R.string.obd_service_notification_title))
.setContentText(getString(R.string.service_notification_content))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(icon)
.build();
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
notification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
startForeground(START_FOREGROUND_ID, notification);
return START_STICKY;
}
In my case, it's because we tried to post a notification without specifying the NotificationChannel:
public static final String NOTIFICATION_CHANNEL_ID_SERVICE = "com.mypackage.service";
public static final String NOTIFICATION_CHANNEL_ID_TASK = "com.mypackage.download_info";
public void initChannel(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_SERVICE, "App Service", NotificationManager.IMPORTANCE_DEFAULT));
nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_INFO, "Download Info", NotificationManager.IMPORTANCE_DEFAULT));
}
}
The best place to put above code is in onCreate() method in the Application class, so that we just need to declare it once for all:
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
initChannel();
}
}
After we set this up, we can use notification with the channelId we just specified:
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID_INFO);
.setContentIntent(pi)
.setWhen(System.currentTimeMillis())
.setContentTitle("VirtualBox.exe")
.setContentText("Download completed")
.setSmallIcon(R.mipmap.ic_launcher);
Then, we can use it to post a notification:
int notifId = 45;
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(notifId, builder.build());
If you want to use it as foreground service's notification:
startForeground(notifId, builder.build());
Thanks to #CopsOnRoad, his solution was a big help but only works for SDK
26 and higher. My app targets 24 and higher.
To keep Android Studio from complaining you need a conditional directly around the notification. It is not smart enough to know the code is in a method conditional to VERSION_CODE.O.
#Override
public void onCreate(){
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
private void startMyOwnForeground(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(AppSpecific.SMALL_ICON)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
}
This worked for me. In my service class, I created the notification channel for android 8.1 as below:
public class Service extends Service {
public static final String NOTIFICATION_CHANNEL_ID_SERVICE = "com.package.MyService";
public static final String NOTIFICATION_CHANNEL_ID_INFO = "com.package.download_info";
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_SERVICE, "App Service", NotificationManager.IMPORTANCE_DEFAULT));
nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_INFO, "Download Info", NotificationManager.IMPORTANCE_DEFAULT));
} else {
Notification notification = new Notification();
startForeground(1, notification);
}
}
}
Note: Create the channel where you are creating the Notification for Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
Alternative answer: if it's a Huawei device and you have implemented requirements needed for Oreo 8 Android and there are still issues only with Huawei devices than it's only device issue, you can read https://dontkillmyapp.com/huawei
I had the same issue. The problem occurred when I used same channel id and notification id for two apps. So try with a unique notification id and channel id.
this maybe old but, incase someone had the same situation as I did.
for some reason, on Android 11 OnePlus Nord
Notification.Builder().Build()
crashes,
NotificationCompat.Builder().Build()
works fine.
Consider migrating to androidx.core.app.NotificationCompat.
If you're working with VPN library, these code will be help, I placed this inside onCreate(savedInstanceState: Bundle?)
NotificationChannelManager.createNotificationChannelIfNeeded(
activity,
channelName = "Chanel Name",
channelDescription = "Channel description"
)
Here is my solution
private static final int NOTIFICATION_ID = 200;
private static final String CHANNEL_ID = "myChannel";
private static final String CHANNEL_NAME = "myChannelName";
private void startForeground() {
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
getApplicationContext(), CHANNEL_ID);
Notification notification;
notification = mBuilder.setTicker(getString(R.string.app_name)).setWhen(0)
.setOngoing(true)
.setContentTitle(getString(R.string.app_name))
.setContentText("Send SMS gateway is running background")
.setSmallIcon(R.mipmap.ic_launcher)
.setShowWhen(true)
.build();
NotificationManager notificationManager = (NotificationManager) getApplication().getSystemService(Context.NOTIFICATION_SERVICE);
//All notifications should go through NotificationChannel on Android 26 & above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(NOTIFICATION_ID, notification);
}
Hope it will help :)

How to set NotificationChannel importance to urgent by program?

I want to implement chat notification() like whatsapp (Whatsapp don't know how but reset the Group Message channel importance (Android O) to Urgent).
All going good only i am not able to set NotificationChannel importance to Urgent programmatically.
Here is my work for the Notifications.
NotificationManager mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(Const.Type.KEY, Const.Type.NOTIFICATION);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, "alert_001")
.setSmallIcon(R.drawable.ic_stat_s)
.setWhen(System.currentTimeMillis())
.setContentTitle("Booking Request")
.setContentText(content)
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(pendingIntent)
.setOngoing(false)
.setAutoCancel(true);
if (mNotificationManager != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(Const.Channel.Id.ALERT_001,
Const.Channel.Name.BOOKING_ALERT,
NotificationManager.IMPORTANCE_HIGH);
/* Here is no constant like NotificationManager.IMPORTANCE_URGENT
* and i can't even put the another integer value, It not obeying the rules*/
mNotificationManager.createNotificationChannel(channel);
mBuilder.setChannelId(channel.getId());
}
mNotificationManager.notify(1, mBuilder.build());
}
While i am changing the, JSON response for notification like below,
{
priority=high,
message=msgmsg,
source_lat=22.751552,
source_lng=75.895745,
user_detail={},
}
At least it is working like NotificationManager.IMPORTANCE_HIGH, But not like URGENT.
I don't know how whatsapp implemented that can override the URGENT importance even if user changes it manually.
There is a hack:
private String ensureChannelAudibility(String channelMainId, String channelName, Uri soundUri) {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(App.instance);
List<NotificationChannel> channels = notificationManager.getNotificationChannels();
NotificationChannel existingChanel = null;
int count = 0;
for (NotificationChannel channel : channels) {
String fullId = channel.getId();
if (fullId.contains(channelMainId)) {
existingChanel = channel;
String[] numbers = extractRegexMatches(fullId, "\\d+");
if (numbers.length > 0) {
count = Integer.valueOf(numbers[0]);
}
break;
}
}
if (existingChanel != null) {
if (existingChanel.getImportance() < NotificationManager.IMPORTANCE_DEFAULT) {
notificationManager.deleteNotificationChannel(existingChanel.getId());
existingChanel = null;
}
}
if (existingChanel == null) {
String newId = channelMainId+'_'+(count+1);
NotificationChannel notificationChannel = new NotificationChannel(newId, channelName, NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(notificationChannel);
return newId;
} else {
return existingChanel.getId();
}
}
//Show the notification with channel id returned by the method above
public String[] extractRegexMatches(String source, String regex) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(source);
ArrayList<String> matches = new ArrayList<>();
while (matcher.find()) {
matches.add(matcher.group());
}
String[] result = new String[matches.size()];
matches.toArray(result);
return result;
}
Normally you can only set channel importance when creating it. Once the user changes it, you can not change it back programmatically. The code above tricks the system. It detects if channels importance is lower than needed and if it is, it deletes it and creates another one with a different id. Thus the system things that it's a different channel needed for something else.
So let's say you have a channel with "channelMainId" = wolf. A (wolf_1) channel will be created. Once the user changes it's settings, next channel will be (wolf_2), then
wolf_3, wolf_4 ... wolf_xxxxxxxxxxxx.
Please try this:
String channelId = "YOUR_CHANNEL_ID";
String channelName = "YOUR_CHANNEL_NAME";
int importance = NotificationManager.IMPORTANCE_HIGH;
final NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(
this,channelId)
.setContentTitle("APP_NAME")
.setSmallIcon(//set any Icon)
.setContentText("TEXT")
.setAutoCancel(true);
final NotificationManager notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
// for oreo-notification
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelName, importance);
notificationManager.createNotificationChannel(mChannel);
}
Thanks

startForeground fail after upgrade to Android 8.1

After upgrading my phone to 8.1 Developer Preview my background service no longer starts up properly.
In my long-running service I've implemented a startForeground method to start the ongoing notification which is called in on create.
#TargetApi(Build.VERSION_CODES.O)
private fun startForeground() {
// Safe call, handled by compat lib.
val notificationBuilder = NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.build()
startForeground(101, notification)
}
Error message:
11-28 11:47:53.349 24704-24704/$PACKAGE_NAMEE/AndroidRuntime: FATAL EXCEPTION: main
Process: $PACKAGE_NAME, PID: 24704
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=My channel pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x42 color=0x00000000 vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
invalid channel for service notification, apparently my old channel the DEFAULT_CHANNEL_ID is no longer appropriate for API 27 I assume. What would be the proper channel? I've tried to look through the documentation
After some tinkering for a while with different solutions i found out that one must create a notification channel in Android 8.1 and above.
private fun startForeground() {
val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel("my_service", "My Background Service")
} else {
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
""
}
val notificationBuilder = NotificationCompat.Builder(this, channelId )
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build()
startForeground(101, notification)
}
#RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(channelId: String, channelName: String): String{
val chan = NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_NONE)
chan.lightColor = Color.BLUE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(chan)
return channelId
}
From my understanding background services are now displayed as normal notifications that the user then can select to not show by deselecting the notification channel.
Update:
Also don't forget to add the foreground permission as required Android P:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Java Solution (Android 9.0, API 28)
In your Service class, add this:
#Override
public void onCreate(){
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
private void startMyOwnForeground(){
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.icon_1)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
UPDATE: ANDROID 9.0 PIE (API 28)
Add this permission to your AndroidManifest.xml file:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
The first answer is great only for those people who know kotlin, for those who still using java here I translate the first answer
public Notification getNotification() {
String channel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
channel = createChannel();
else {
channel = "";
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channel).setSmallIcon(android.R.drawable.ic_menu_mylocation).setContentTitle("snap map fake location");
Notification notification = mBuilder
.setPriority(PRIORITY_LOW)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
return notification;
}
#NonNull
#TargetApi(26)
private synchronized String createChannel() {
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
String name = "snap map fake location ";
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = new NotificationChannel("snap map channel", name, importance);
mChannel.enableLights(true);
mChannel.setLightColor(Color.BLUE);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(mChannel);
} else {
stopSelf();
}
return "snap map channel";
}
For android, P don't forget to include this permission
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Works properly on Andorid 8.1:
Updated sample (without any deprecated code):
public NotificationBattery(Context context) {
this.mCtx = context;
mBuilder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle(context.getString(R.string.notification_title_battery))
.setSmallIcon(R.drawable.ic_launcher)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setChannelId(CHANNEL_ID)
.setOnlyAlertOnce(true)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setWhen(System.currentTimeMillis() + 500)
.setGroup(GROUP)
.setOngoing(true);
mRemoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_view_battery);
initBatteryNotificationIntent();
mBuilder.setContent(mRemoteViews);
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (AesPrefs.getBooleanRes(R.string.SHOW_BATTERY_NOTIFICATION, true)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, context.getString(R.string.notification_title_battery),
NotificationManager.IMPORTANCE_DEFAULT);
channel.setShowBadge(false);
channel.setSound(null, null);
mNotificationManager.createNotificationChannel(channel);
}
} else {
mNotificationManager.cancel(Const.NOTIFICATION_CLIPBOARD);
}
}
Old snipped (it's a different app - not related to the code above):
#Override
public int onStartCommand(Intent intent, int flags, final int startId) {
Log.d(TAG, "onStartCommand");
String CHANNEL_ONE_ID = "com.kjtech.app.N1";
String CHANNEL_ONE_NAME = "Channel One";
NotificationChannel notificationChannel = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
notificationChannel = new NotificationChannel(CHANNEL_ONE_ID,
CHANNEL_ONE_NAME, IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setShowBadge(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
}
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Notification notification = new Notification.Builder(getApplicationContext())
.setChannelId(CHANNEL_ONE_ID)
.setContentTitle(getString(R.string.obd_service_notification_title))
.setContentText(getString(R.string.service_notification_content))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(icon)
.build();
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
notification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
startForeground(START_FOREGROUND_ID, notification);
return START_STICKY;
}
In my case, it's because we tried to post a notification without specifying the NotificationChannel:
public static final String NOTIFICATION_CHANNEL_ID_SERVICE = "com.mypackage.service";
public static final String NOTIFICATION_CHANNEL_ID_TASK = "com.mypackage.download_info";
public void initChannel(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_SERVICE, "App Service", NotificationManager.IMPORTANCE_DEFAULT));
nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_INFO, "Download Info", NotificationManager.IMPORTANCE_DEFAULT));
}
}
The best place to put above code is in onCreate() method in the Application class, so that we just need to declare it once for all:
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
initChannel();
}
}
After we set this up, we can use notification with the channelId we just specified:
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID_INFO);
.setContentIntent(pi)
.setWhen(System.currentTimeMillis())
.setContentTitle("VirtualBox.exe")
.setContentText("Download completed")
.setSmallIcon(R.mipmap.ic_launcher);
Then, we can use it to post a notification:
int notifId = 45;
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(notifId, builder.build());
If you want to use it as foreground service's notification:
startForeground(notifId, builder.build());
Thanks to #CopsOnRoad, his solution was a big help but only works for SDK
26 and higher. My app targets 24 and higher.
To keep Android Studio from complaining you need a conditional directly around the notification. It is not smart enough to know the code is in a method conditional to VERSION_CODE.O.
#Override
public void onCreate(){
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
private void startMyOwnForeground(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(AppSpecific.SMALL_ICON)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
}
This worked for me. In my service class, I created the notification channel for android 8.1 as below:
public class Service extends Service {
public static final String NOTIFICATION_CHANNEL_ID_SERVICE = "com.package.MyService";
public static final String NOTIFICATION_CHANNEL_ID_INFO = "com.package.download_info";
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_SERVICE, "App Service", NotificationManager.IMPORTANCE_DEFAULT));
nm.createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID_INFO, "Download Info", NotificationManager.IMPORTANCE_DEFAULT));
} else {
Notification notification = new Notification();
startForeground(1, notification);
}
}
}
Note: Create the channel where you are creating the Notification for Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
Alternative answer: if it's a Huawei device and you have implemented requirements needed for Oreo 8 Android and there are still issues only with Huawei devices than it's only device issue, you can read https://dontkillmyapp.com/huawei
I had the same issue. The problem occurred when I used same channel id and notification id for two apps. So try with a unique notification id and channel id.
this maybe old but, incase someone had the same situation as I did.
for some reason, on Android 11 OnePlus Nord
Notification.Builder().Build()
crashes,
NotificationCompat.Builder().Build()
works fine.
Consider migrating to androidx.core.app.NotificationCompat.
If you're working with VPN library, these code will be help, I placed this inside onCreate(savedInstanceState: Bundle?)
NotificationChannelManager.createNotificationChannelIfNeeded(
activity,
channelName = "Chanel Name",
channelDescription = "Channel description"
)
Here is my solution
private static final int NOTIFICATION_ID = 200;
private static final String CHANNEL_ID = "myChannel";
private static final String CHANNEL_NAME = "myChannelName";
private void startForeground() {
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
getApplicationContext(), CHANNEL_ID);
Notification notification;
notification = mBuilder.setTicker(getString(R.string.app_name)).setWhen(0)
.setOngoing(true)
.setContentTitle(getString(R.string.app_name))
.setContentText("Send SMS gateway is running background")
.setSmallIcon(R.mipmap.ic_launcher)
.setShowWhen(true)
.build();
NotificationManager notificationManager = (NotificationManager) getApplication().getSystemService(Context.NOTIFICATION_SERVICE);
//All notifications should go through NotificationChannel on Android 26 & above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(NOTIFICATION_ID, notification);
}
Hope it will help :)

On Android 8.1 API 27 notification does not display

I get Toast on Android 8.1 API 27:
Developer warning for package "my_package_name"
Failed to post notification on ...
Logcat includes next strings:
Notification: Use of stream types is deprecated for operations other
than volume control
W/Notification: See the documentation of setSound() for what to use
instead with android.media.AudioAttributes to qualify your playback
use case
E/NotificationService: No Channel found for pkg=my_package_name
The full information in the Toast and in Logcat can help in the localization this problem.
If you get this error should be paid attention to 2 items and them order:
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
builder = new NotificationCompat.Builder(context, id);
Also NotificationManager notifManager and NotificationChannel mChannel are created only once.
There are required setters for Notification:
builder.setContentTitle() // required
.setSmallIcon() // required
.setContentText() // required
See example:
private NotificationManager notifManager;
public void createNotification(String aMessage, Context context) {
final int NOTIFY_ID = 0; // ID of notification
String id = context.getString(R.string.default_notification_channel_id); // default_channel_id
String title = context.getString(R.string.default_notification_channel_title); // Default Channel
Intent intent;
PendingIntent pendingIntent;
NotificationCompat.Builder builder;
if (notifManager == null) {
notifManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = notifManager.getNotificationChannel(id);
if (mChannel == null) {
mChannel = new NotificationChannel(id, title, importance);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
notifManager.createNotificationChannel(mChannel);
}
builder = new NotificationCompat.Builder(context, id);
intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
builder.setContentTitle(aMessage) // required
.setSmallIcon(android.R.drawable.ic_popup_reminder) // required
.setContentText(context.getString(R.string.app_name)) // required
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setTicker(aMessage)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
}
else {
builder = new NotificationCompat.Builder(context, id);
intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
builder.setContentTitle(aMessage) // required
.setSmallIcon(android.R.drawable.ic_popup_reminder) // required
.setContentText(context.getString(R.string.app_name)) // required
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setTicker(aMessage)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400})
.setPriority(Notification.PRIORITY_HIGH);
}
Notification notification = builder.build();
notifManager.notify(NOTIFY_ID, notification);
}
Andy's answer is working however I wanted to avoid to deprecated Builder and follow the FireBase Quickstart Project. I just added code before notify from manager.
String channelId = "default_channel_id";
String channelDescription = "Default Channel";
// Since android Oreo notification channel is needed.
//Check if notification channel exists and if not create one
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = notificationManager.getNotificationChannel(channelId);
if (notificationChannel == null) {
int importance = NotificationManager.IMPORTANCE_HIGH; //Set the importance level
notificationChannel = new NotificationChannel(channelId, channelDescription, importance);
notificationChannel.setLightColor(Color.GREEN); //Set if it is necesssary
notificationChannel.enableVibration(true); //Set if it is necesssary
notificationManager.createNotificationChannel(notificationChannel);
}
}
//notificationManager.notify as usual
Edit:
They removed the channel exist check from example I am not sure why.
I have set channel id, but notification still not shown.
Finally i found my problem is had not invoke "setContentText()" method.
It was really help me that #Andy Sander mentioned "required setters"!
here are required setters for Notification on Android 8 Oreo API 26 and later:
builder.setContentTitle() // required
.setSmallIcon() // required
.setContentText() // required
.setChannelId(id) // required for deprecated in API level >= 26 constructor .Builder(this)
Also don't forget to bind your channel_id to your notification builder. After binding it, my problem gone.
notificationBuilder.setChannelId(channelId)
or
NotificationCompat.Builder(Context context, String channelId)

Categories

Resources