I need to create a persistent notification - even on new Android versions.
I use a foreground service with (START_STICKY) to display the notification. The notification is created in the method onCreate() and from time to time I start again the foreground service - just in case it was killed.
This is how I create the notification:
String CHANNEL_ID = MainActivity.packageName+".notification";// The id of the channel.
CharSequence name = getString(R.string.app_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
mChannel.setSound(null, null);
notificationManager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this, MainActivity.packageName+".notification");
Intent main = new Intent(this, MainActivity.class);
main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, main, PendingIntent.FLAG_UPDATE_CURRENT);
// set intent so it does not start a new activity
Notification notification = nBuilder
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.icon)
.setWhen( System.currentTimeMillis())
.setContentTitle("my app")
.setContentText("my msg")
.setOngoing(true)
.setChannelId(MainActivity.packageName+".notification")
.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
//notificationManager.notify(StaticMembers.notifId, notification);
startForeground(StaticMembers.notifId+1, notification);
The notification is shown but on some phone models, after a few days the notification is not shown anymore, even if the service is still running.
What should I do? Is there something wrong with how I create the notification?
Should I check when the service runs if the notification is displayed and if not recreate it?
Thanks
Related
This is the weirdest thing I ever met in Android development. I want to show a simple notification from a service, the notification is successfully shown when I run it on a virtual device in android studio, but when I run it on my own phone the notification doesn't show at all.
Notification shows on AVD test
I make sure that the notification is allowed on my phone, I can even see the channel information
on the notification settings page, which means the channel is successfully built, but the notification just does not show.
Channel information
No notification on phone test
The following is my code:
public int onStartCommand(final Intent intent, int flags, int startId) {
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("test")
.setContentText("test")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentIntent(pendingIntent)
.setAutoCancel(false);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(001, builder.build());
return super.onStartCommand(intent, flags, startId);
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
channel.setShowBadge(true);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
By the way, the AVD I used is in API level 29 and my phone is a Huawei phone on HarmonyOS 2.0 but still API level 29.
I send a simple notification to the user when they open the app. When I swipe the notification away from the status bar, the notification is also deleted.
I just want the notification to stay on the status bar even if I close the app like whats app Instagram and some other apps.
This is how I send notification
Context context = getActivity();
Intent intent1 = new Intent(context,MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent1, 0);
Notification.Builder builder = new Notification.Builder(context)
.setTicker("Notification")
.setContentTitle("Important Message")
.setContentText("This is an example of a push notification using a Navigation Manager")
.setSmallIcon(R.drawable.ic_add)
.setContentIntent(pIntent);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
//These are necessary for the notification to pop up
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O){
builder.setPriority(Notification.PRIORITY_MAX);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
builder.setLights(Color.BLUE, 500, 500);
}
//after android O we must use notification channels
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
String channelId = "Your_channel_id";
NotificationChannel channel = new NotificationChannel(
channelId,
"Reminder to remind to review your notes",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("Hello Dear friends"); //this is to test what this is
notificationManager.createNotificationChannel(channel);
builder.setChannelId(channelId);
}
Notification notification = builder.build();
notification.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
P.S1: I don't want the notification to persist like in foreground services. I just want to not go away when the app is swiped away, but the user can get rid of the notification anytime they want.
P.S2: I am not using any services, just a simple notification. Like e.g.letting the user know that they collected some badges today.
I have an calendar app where the info is downloaded online and there is a recyclerView of events and I want to notify the user when there is a calendar event for today, and notify with the event name or names. I have done some googling but haven't been able to figure this out.
In my MainActivity.java this is the method I created as a test from a page online
private void addNotification() {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setSmallIcon(R.drawable.ic_check);
mBuilder.setContentTitle("Notification Alert, Click Me!");
mBuilder.setContentText("Hi, This is Android Notification Detail!");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(contentIntent);
// Add as notification
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, mBuilder.build());
}
But when I call this method nothing is happening, what am I doing wrong?
I think you are missing the channel of the notification
I have a different solution, try this one (I checked it on my phone)
calling the function:
showSmallNotification(R.drawable.ic_launcher_background, "title","message");
Function code
private void showSmallNotification( int icon, String title, String message){
String CHANNEL_ID = "Channel_01";
String CHANNEL_NAME = "Notification";
// I removed one of the semi-colons in the next line of code
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine(message);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// I would suggest that you use IMPORTANCE_DEFAULT instead of IMPORTANCE_HIGH
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
channel.enableVibration(true);
channel.setLightColor(Color.BLUE);
channel.enableLights(true);
//channel.canShowBadge();
// Did you mean to set the property to enable Show Badge?
channel.setShowBadge(true);
notificationManager.createNotificationChannel(channel);
}
Intent mainIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, mainIntent, 0);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
.setVibrate(new long[]{0, 100})
.setPriority(Notification.PRIORITY_MAX)
.setLights(Color.BLUE, 3000, 3000)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.setStyle(inboxStyle)
.setContentText(message);
// Don't forget to set the ChannelID!!
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
notificationBuilder.setChannelId(CHANNEL_ID);
}
notificationManager.notify(CHANNEL_ID, 1, notificationBuilder.build());
}
Edit
In order to check if there are any events every day you will need to use AlarmManager as from it's name you can schedule an event every day
You can see a solution (or at least it will give a direction) once you did that I think the next step would be to send the intent to a service which will check if there are any events available in current day. If there are any just show the notification/s
alarm manager link
I have a group of notifications in Android App.
I need my application to know if the app was opened when the user clicked on the notification.
I have used a pending intent and it works brilliantly. But how can I check if the user has clicked on the notification group? It shows no links, no notifications sounds, nothing. I found no information in the documentation. Please help.
You can add flag in intent like isFromNotification boolean and then pass that intent to pending intent and then notify user.
Now in activity check intent has this parameter then the user has come from notification.
(simple like that)
Sample code
Intent notificationIntent = new Intent(this, TargetActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
String channel_Id = "app_channel_01";
notificationIntent.putExtra(AppConstants.INTENTDATA.ISFROMNOTIFICATION,
true);
PendingIntent pendingIntent = PendingIntent.getActivity(MyApplication.getInstance(),
0, notificationIntent,
0);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(MyApplication.getInstance(), channel_Id)
.setSmallIcon(R.mipmap.ic_launcher)
.setColor(MyApplication.getInstance().getResources().getColor(android.R.color.white))
.setContentTitle(getResources().getString(R.string.app_name))
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis());
NotificationManager notificationManager =
(NotificationManager) MyApplication.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create or update.
NotificationChannel channel = new NotificationChannel(channel_Id,
"General Notifications",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(notificationId, notificationBuilder.build());
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
intent = new Intent(context, AlertDialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); // added new line
intent.putExtra("STARTED_BY_RECEIVER", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
String CHANNEL_ID = "channel id";// The id of the channel.
CharSequence name = "Channel";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
Notification notification = new Notification.Builder(context)
.setContentIntent(pendingIntent)
.setContentText("Some Text")
.setContentTitle("Notification")
.setAutoCancel(true)
.setOngoing(true)
.setSmallIcon(R.drawable.ic_notification_praying)
.setChannelId(CHANNEL_ID)
.build();
notificationManager.createNotificationChannel(mChannel);
notificationManager.notify(100 , notification);
} else {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
intent = new Intent(context, AlertDialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); // added new line
intent.putExtra("STARTED_BY_RECEIVER", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = (NotificationCompat.Builder) new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_notification_praying)
.setContentIntent(pendingIntent)
.setContentText("Some Text")
.setContentTitle("Notification")
.setAutoCancel(true)
.setOngoing(true);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
notificationManager.notify(100, builder.build());
}
}
I've made an application which show notification on time that user chose in main activity and Notification should disappear only when user tap on notification otherwise not..and it was working fine unless I've updated my phone to android Oreo (8.0) now notification show at time but auto disappear after sometime.. How to make notification not auto disappear (in android Oreo) but only when user tap on it?
alright I figure this out.. it was battery optimize option which was killing my application so that's why notification was disappearing.. I removed my application from auto optimize now it's working fine.