A beginner to android and have been struggling for a while on this problem now. There is an on going notification that I would like to update frequently. Possibly every second. I know this should be possible because I have seen other apps do it like Toggle. But whenever it's updated and there is some other notification on the page, they will keep fighting each other to be on the top. I have researched but haven't found anything that was able to help me on this.
I believe I have followed these rules in hoping of avoiding this issue:
Use the same notification object, and not a new one for every update
Use the same Id on each notify()
Use the .setwhen which was recommended by another post
Video to the problem
private NotificationManager mNotificationManagerupdate;
private NotificationCompat.Builder mBuilderupdate;
/**
* Notification system that is used for this app. All we need to do is call this function
* when we need to trigger a notification.
*/
private void notification() {
times = System.currentTimeMillis();
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.iss_2011);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setAutoCancel(false)
.setOnlyAlertOnce(true)
.setOngoing(true)
.setContentTitle("ISS Tracker")
.setContentText("ISS is about an hour away!")
.setSmallIcon(R.drawable.iss_2011)
.setLargeIcon(icon)
.setSound(soundUri)
.setWhen(times);
Intent resultIntent = new Intent(context, Locations.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(Locations.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1234, mBuilder.build());
mBuilderupdate = mBuilder;
mNotificationManagerupdate = mNotificationManager;
}
/**
* Continuously updates a notification that will display live results.
*
* #param time The difference between ISS' location to user's location
*/
private void updatemanager(final long time) {
timerupdate = new Timer();
timerupdate.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
notificationupdate(time);
}
}, 0, 1000);
}
/**
* Updates the manager and finishes off when time reaches zero.
*
* #param time The difference between ISS' location to user's location
*/
private void notificationupdate(long time) {
int finalseconds = (int) (time / 1000) - loop++;
if (finalseconds > 0) {
mBuilderupdate.setContentText("ISS is about " + finalseconds + " seconds away!");
} else if (finalseconds > -11) {
mBuilderupdate.setContentText("ISS is at your location! Ending in (" + (10 - Math.abs(finalseconds)) + ")");
} else {
timerupdate.cancel();
timerupdate.purge();
timerupdate = null;
loop = 0;
endnotification = true;
}
mBuilderupdate.setWhen(times);
Log.d(TAG, "When = " + times);
mNotificationManagerupdate.notify(1234, mBuilderupdate.build());
if (endnotification) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager nMgr = (NotificationManager) context.getSystemService(ns);
nMgr.cancel(1234);
}
}
Related
I have a foreground service that I set up a notification channel as required for Android API 26 and beyond, but I'm not able to dynamically set the sound for this notification. Let me explain:
As the service starts, it creates an initial notification using startForeground as required of a foreground service. What I'm trying to accomplish is to reuse this persistent notification that is already in the notification tray, updating the message to provide a visual status update. This much I can already achieve. In one particular case, I'd like to also update either the notification or notification channel to provide a new notification sound and display the notification to the user. The notification always uses the same sound that was initially established when the service was first started and never becomes immediately visible to the user without sliding the notification tray down from the top of the screen.
What does seem to work is that I create a separate notification channel for this one case, but then I have two different notification items in the tray. Another way that appears to work is shown on YouTube # https://www.youtube.com/watch?v=3Je9ZEAAjfA where the author uses NotificationManager.deleteNotificationChannel to remove, then NotificationManager.createNotificationChannel however, they said the OS will eventually delete my app if I keep re-creating the notification channel as some form of spam prevention.
Is there some way to reuse the original notification channel to dynamically change the sound and make it visible?
I'll go out on a limb and show the solution I chose. The createNotificationChannels method gets called during onCreate, then createNotification gets called once at onStartCommand to satisfy the 5 second limit for calling startForeground. Then I call createNotification, as needed, to select which of the 3 different channels to display and set the title/body contents. I'd sure rather be able to dynamically set the sound.
private int CHANNEL_NOTIFICATION_ID = 666;
public static final String TARGET_MESSAGING_GROUP_ID = "TargetMessagingGroupID";
public static final String TARGET_MESSAGING_GROUP_NAME = "Target Messaging Group";
public static final String WAITING_NEW_TARGET_CHANNEL_ID = "WaitingNewTargetChannelID";
public static final String WAITING_NEW_TARGET_CHANNEL_NAME = "Waiting for New Target Channel";
public static final String NAVIGATING_TO_TARGET_CHANNEL_ID = "NavigatingToTargetChannelID";
public static final String NAVIGATING_TO_TARGET_CHANNEL_NAME = "Navigating To Target Channel";
public static final String TARGET_ARRIVAL_CHANNEL_ID = "TargetArrivalChannelID";
public static final String TARGET_ARRIVAL_CHANNEL_NAME = "Target Arrival Channel";
// --------------------------------------------------------------------
// Method: createNotificationChannels
//
// Purpose: Called once at startup so we have the notification channels
// ready to go when we need them
// --------------------------------------------------------------------
protected void createNotificationChannels()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
// use the same audio attributes for each channel
AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build();
// configure the group
NotificationChannelGroup targetMessagingGroup = new NotificationChannelGroup(TARGET_MESSAGING_GROUP_ID, TARGET_MESSAGING_GROUP_NAME);
// configure the first channel
Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + parentContext.getPackageName() + "/" + R.raw.elevatording);
NotificationChannel waitingNewTargetChannel = new NotificationChannel(WAITING_NEW_TARGET_CHANNEL_ID, WAITING_NEW_TARGET_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
waitingNewTargetChannel.setDescription(WAITING_NEW_TARGET_CHANNEL_NAME);
waitingNewTargetChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
waitingNewTargetChannel.setSound(soundUri, audioAttributes); // This is IMPORTANT
waitingNewTargetChannel.enableLights(true);
waitingNewTargetChannel.setLightColor(Color.RED);
waitingNewTargetChannel.enableVibration(false);
waitingNewTargetChannel.setGroup(TARGET_MESSAGING_GROUP_ID);
// configure the second channel
soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + parentContext.getPackageName() + "/" + R.raw.beep);
NotificationChannel navigatingToTargetChannel = new NotificationChannel(NAVIGATING_TO_TARGET_CHANNEL_ID, NAVIGATING_TO_TARGET_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
navigatingToTargetChannel.setDescription(NAVIGATING_TO_TARGET_CHANNEL_NAME);
navigatingToTargetChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
navigatingToTargetChannel.setSound(soundUri, audioAttributes);
navigatingToTargetChannel.enableLights(false);
navigatingToTargetChannel.setLightColor(Color.RED);
navigatingToTargetChannel.enableVibration(false);
navigatingToTargetChannel.setGroup(TARGET_MESSAGING_GROUP_ID);
// configure the third channel
soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + parentContext.getPackageName() + "/" + R.raw.purge_siren_loud);
NotificationChannel targetArrivalChannel = new NotificationChannel(TARGET_ARRIVAL_CHANNEL_ID, TARGET_ARRIVAL_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
targetArrivalChannel.setDescription(TARGET_ARRIVAL_CHANNEL_NAME);
targetArrivalChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
targetArrivalChannel.setSound(soundUri, audioAttributes); // This is IMPORTANT
targetArrivalChannel.enableLights(true);
targetArrivalChannel.setLightColor(Color.RED);
targetArrivalChannel.enableVibration(true);
targetArrivalChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
targetArrivalChannel.setGroup(TARGET_MESSAGING_GROUP_ID);
// finally, register the group and associated channels with the OS
NotificationManager notificationManager = (NotificationManager) getSystemService(NotificationManager.class);
notificationManager.createNotificationChannelGroup(targetMessagingGroup);
notificationManager.createNotificationChannel(waitingNewTargetChannel);
notificationManager.createNotificationChannel(navigatingToTargetChannel);
notificationManager.createNotificationChannel(targetArrivalChannel);
}
}
// --------------------------------------------------------------------
// Method: createNotification
//
// Purpose: Called whenever changing the displayed notification is
// required. Must call this with requestedNotificationType
// of NOTIFY_TYPE_WAITING_FOR_TARGET from onStartCommand
// in order to call startForeground within the 5 second limit
// for a foreground service.
// --------------------------------------------------------------------
protected void createNotification(LocationService.LocationNotifyType requestedNotificationType, Bitmap notificationBitmap, Uri soundUri, String title, String message)
{
Intent notificationIntent = new Intent(parentContext, signalledClass);
PendingIntent pendingIntent = null;
Notification notification = null;
int notification_id = CHANNEL_NOTIFICATION_ID;
switch (requestedNotificationType)
{
default:
{
Log.d("LocationHandler", "Unknown LocationNotifyType, NOT changing notification");
break;
}
case NOTIFY_TYPE_WAITING_FOR_TARGET:
{
pendingIntent = PendingIntent.getActivity(parentContext, 0, notificationIntent, 0);
notification = new NotificationCompat.Builder(parentContext, WAITING_NEW_TARGET_CHANNEL_ID)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(notificationBitmap)
.setPriority(NotificationCompat.PRIORITY_HIGH) // only affects API 25 and below
.setStyle(new NotificationCompat.BigTextStyle().setSummaryText("Waiting").setBigContentTitle(title).bigText(message))
.setContentIntent(pendingIntent)
.setTicker(getText(R.string.ticker_text))
.setAutoCancel(false)
.setOnlyAlertOnce(true)
.setSound(soundUri)
.build();
if (notification != null)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
startForeground(notification_id, notification);
}
else
{
NotificationManagerCompat.from(parentContext).notify(notification_id, notification);
}
}
break;
}
case NOTIFY_TYPE_NAVIGATING:
{
pendingIntent = PendingIntent.getActivity(parentContext, 0, notificationIntent, 0);
notification = new NotificationCompat.Builder(parentContext, NAVIGATING_TO_TARGET_CHANNEL_ID)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(notificationBitmap)
.setPriority(Notification.PRIORITY_HIGH) // only affects API 25 and below
.setStyle(new NotificationCompat.BigTextStyle().setSummaryText("Navigating").setBigContentTitle(title).bigText(message))
.setContentIntent(pendingIntent)
.setTicker(getText(R.string.ticker_text))
.setAutoCancel(false)
.setOnlyAlertOnce(true)
.setSound(soundUri)
.build();
NotificationManagerCompat.from(parentContext).notify(notification_id, notification);
break;
}
case NOTIFY_TYPE_ARRIVAL:
{
notificationIntent.setAction("ArrivalNotification");
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
notificationIntent.putExtra(AllConstants.APP_WAKEUP_TYPE, AllConstants.APP_WAKEUP_TARGET_ARRIVAL);
pendingIntent = PendingIntent.getActivity(parentContext, notification_id, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification = new NotificationCompat.Builder(parentContext, TARGET_ARRIVAL_CHANNEL_ID)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(notificationBitmap)
.setPriority(NotificationCompat.PRIORITY_HIGH) // only affects API 25 and below
.setStyle(new NotificationCompat.BigTextStyle().setSummaryText("Arrival").setBigContentTitle(title).bigText(message))
.setContentIntent(pendingIntent)
.setAutoCancel(false)
.setSound(soundUri)
.setWhen(System.currentTimeMillis())
.build();
NotificationManagerCompat.from(parentContext).notify(notification_id, notification);
break;
}
}
}
My app sets a notification with the following code:
private void defineAndLaunchNotification(String apppack,String title, String ContentText)
{
Context context = getApplicationContext();
PackageManager pm = context.getPackageManager();
Intent LaunchIntent = null;
String name=null;
try {
if (pm != null)
{
ApplicationInfo app = context.getPackageManager().getApplicationInfo(apppack, 0);
name = (String) pm.getApplicationLabel(app);
LaunchIntent = pm.getLaunchIntentForPackage(apppack);
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
Intent intent = LaunchIntent;
if (ContentText.equals("filesystemfullnotification"))
{
intent.putExtra("start", "fullsystem");
}
else
{
intent.putExtra("start","incorrecttime");
}
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
NotificationCompat.Builder builder=null;
NotificationChannel notificationChannel=null;
int NOTIFICATION_ID = 12345;
if (Build.VERSION.SDK_INT<26) {
builder =
new NotificationCompat.Builder(getBaseContext())
.setSmallIcon(R.drawable.notification_icon)
.setAutoCancel(true)
.setContentTitle("title
)
.setContentText("Content Text");
}
else
{
int importance=NotificationManager.IMPORTANCE_HIGH;
notificationChannel=new NotificationChannel("mychannel", "channel", importance);
builder =
new NotificationCompat.Builder(getBaseContext(),"mychannel")
.setSmallIcon(R.drawable.notification_icon)
.setAutoCancel(true)
//.setStyle(new NotificationCompat.BigTextStyle().bigText(StaticMethods.giveStringAccordingtoLanguage(title,language)))
.setContentTitle(StaticMethods.giveStringAccordingtoLanguage(title, language))
.setContentText(StaticMethods.giveStringAccordingtoLanguage(ContentText, language));
}
builder.addAction(R.drawable.notification_icon, "OK", pIntent);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
builder.setVibrate(new long[]{0, 1000, 1000, 1000, 1000});
builder.setContentIntent(pIntent);
NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT>=26) {
nManager.createNotificationChannel(notificationChannel);
}
nManager.notify( (int) ((new Date().getTime() +Math.round(Math.random()*5000) / 1000L) % Integer.MAX_VALUE), builder.build());
}
That code sucessfully shows a notification whenever is called, but problem is that if the notification is tapped twice (or more) times it will open as many instances of my application as that number of times.
This happens even though I have defined in my AndroidManifest.xml my application tag with android:launchMode="singleInstance".
What could I do so the notificacion just reacts to the first tap or only one instance of the app appears?
The way you have build the intent you passed into your pending intent could be the problem. Consider building your intent this way:
Intent intent = new Intent(context.getApplicationContext(), <Activity to launch>.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("start", "fullsystem");
By your code you're actually calling to launch the whole application that is why its creating several instances of the application.
You are supposed to launch a particular part of your application, an entry activity to your application.
#Override
public void onMessageReceived(String from, Bundle data) {
dbhelper = DatabaseHelper.getInstance(this);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
if (from.startsWith("/topics/teta")) {
if (message != null) {
final Alert alert = new Gson().fromJson(message, Alert.class);
Log.d(TAG, alert.getDesc() + " " + alert.getLink() + " " + alert.getTimeStamp() + " " + alert.getTitle());
dbhelper.addAlertsToDB(alert, DatabaseHelper.NEW);
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(AppPreferences.NEW_ALERT_RECIEVED));
boolean notifPref = sharedPreferences.getBoolean(AppPreferences.PREFERENCE_RECIEVE_NOTIFICATION, false);
if (notifPref) {
sendNotification("You Have A New Job Notification.", alert.getTitle());
Log.d(TAG, "Notifications turned " + notifPref + " ...User will be notified");
} else {
Log.d(TAG, "Notifications turned " + notifPref);
}
}
}
}
private void sendNotification(String message, String title) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setColor(ContextCompat.getColor(this, R.color.colorPrimary))
.setSmallIcon(R.drawable.ic_notifications_active_white_24dp)
.setContentTitle(getResources().getString(R.string.app_name))
.setContentText(message)
.setSubText(title)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(notificationBuilder);
//Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
String strRingtonePreference = sharedPreferences.getString(AppPreferences.PREFERENCE_SOUND, "");
Uri defaultSoundUri = Uri.parse(strRingtonePreference);
notificationBuilder.setSound(defaultSoundUri);
boolean vibrate = sharedPreferences.getBoolean(AppPreferences.PREFERENCE_VIBRATE, false);
if (vibrate) {
long[] pattern = {0, 200};
notificationBuilder.setVibrate(pattern);
}
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
So my problem is to notify user about new messages without annoying him if the user has not already checked the old notification in status bar. I am not able to persist notification id and notification builder.
My server sends new alerts in a continuous stream of 5-10 alerts at once, but each item arrives separately asynchronously often one after other with a split second difference.
So it becomes very annoying for the user since he has not dismissed/viewed the old one.
I wish to update the content of previous notification in the status bar without notifying user....just like Gmail does.
First, add an ID to each notification. It can be a hashcode of the message title for example.
Second, each time you want to post a notification, use 'getActiveNotifications()' to get the array of active notifications. And if you find one with an equal ID, update it passing the existing ID.
And, if you don't want the sound, vibration and ticker to be played again, use the 'setOnlyAlertOnce(true)' option.
When the iconIndex of my notification = 0, it looks for the name in the array on position 0, and returns "ic_alert", which is the name of the icon. But only when this icon is chosen, it doesn't want to play the notification sound, even though isPlaySound() returns true, so weird... Other icons work fine
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.e("ALARMRECEIVER","ONRECEIVE");
//Create a notification
long notificationId = intent.getLongExtra("id", -1);
if(notificationId == -1)
{
Log.e("AlarmReceiver","id went missing");
}
else
{
NotificationRepository repository = NotificationRepository.getInstance(context);
Notification notification = repository.getNotification(notificationId);
if(notification != null)
{
String[] icons = context.getResources().getStringArray(R.array.icons);
int iconId = context.getResources().getIdentifier(context.getPackageName()
+ ":drawable/" + icons[notification.getIconIndex()], null, null);
String icon = icons[notification.getIconIndex()];
//create the android notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(iconId)
.setContentTitle(notification.getTitle())
.setContentText(notification.getSubtitle())
.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
if(notification.isPlaySound())
{
mBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
Log.e("ALARMRECEIVER", "SOUND");
}
else Log.e("ALARMRECEIVER","NO SOUND");
if (notification.isVibrate())
{
mBuilder.setVibrate(new long[]{1000, 1000});
}
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify((int) notificationId, mBuilder.build());
//Delete the notification from the database
repository.removeNotification(notificationId);
Intent i = new Intent("dvanack.gmail.com.NOTIFY");
context.sendBroadcast(i);
Log.w("ONRECEIVE","ENDED");
}
I don't have this problem with other devices than the One Plus one running Cyanogenmod, this was fixed the day after with an update ...
I have a repeating notification in a broadcast receiver. I will like to replace the content text dynamically. The notification will show the user a different message the next time the notification is shown. I want to know if its possible. If yes, how ?
below is the class of my broadcast receiver
public class TimeAlarm extends BroadcastReceiver {
NotificationManager nm;
long pattern[] = {500, 500};
private Uri notifsound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
private NotificationCompat.BigTextStyle contentStyle;
#Override
public void onReceive(Context context, Intent intent) {
String msg = "Drivers who sit higher feel as if they're driving slower. " +
"Thus, SUV drivers, who are already piloting the vehicles most prone to " +
"roll, drive faster because they feel like they're creeping along. " +
"So lower your seat to get the sensation of more speed.";
contentStyle = new android.support.v4.app.NotificationCompat.BigTextStyle();
contentStyle.bigText(msg);
contentStyle.setBigContentTitle("Lower Your Seat");
contentStyle.setSummaryText("AutoKit");
NotificationCompat.Builder builder;
builder = (NotificationCompat.Builder) new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("AutoKit")
.setContentText("Tip of the Day")
.setTicker("Daily Tip")
.setStyle(contentStyle)
.setSound(notifsound)
.setAutoCancel(true)
.setVibrate(pattern);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(1, builder.build());
}
}
here is the method is called in my mainactivity and ties the broadcast receiver to an alarm manager
public void setRepeatingAlarm(){ //user receives notifications every 24 hours at 7am
am = (AlarmManager)this.getSystemService(this.ALARM_SERVICE);
Intent intent = new Intent(this, TimeAlarm.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 07);
calendar.set(Calendar.MINUTE, 00);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pi);
}
Modify a Notification
To set up a notification so it can be updated, issue it with a notification ID by calling NotificationManager.notify(ID, notification). To update this notification once you've issued it, update or create a NotificationCompat.Builder object, build a Notification object from it, and issue the Notification with the same ID you used previously.
The following snippet demonstrates a notification that is updated to reflect the number of events that have occurred. It stacks the notification, showing a summary:
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
// Because the ID remains unchanged, the existing notification is
// updated.
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
...
Taken from developer site. please refer, http://developer.android.com/training/notify-user/managing.html
here the changes I made in the broadcast receiver class.
public class TimeAlarm extends BroadcastReceiver {
NotificationManager nm;
long pattern[] = {500, 500};
private Uri notifsound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
private NotificationCompat.BigTextStyle contentStyle;
private List contentTexts, contentTitles;
#Override
public void onReceive(Context context, Intent intent) {
contentTexts = new ArrayList<String>();
contentTitles = new ArrayList<String>();
prepareContentTitles();
prepareContentTexts();
SharedPreferences prefs = context.getSharedPreferences("notification_count", context.MODE_PRIVATE);
int count = prefs.getInt("notification_count", 0);
contentStyle = new android.support.v4.app.NotificationCompat.BigTextStyle();
contentStyle.bigText((CharSequence) contentTexts.get(count));
contentStyle.setBigContentTitle((CharSequence) contentTitles.get(count));
contentStyle.setSummaryText("AutoKit");
NotificationCompat.Builder builder;
builder = (NotificationCompat.Builder) new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("AutoKit")
.setContentText("Tip of the Day")
.setTicker("Daily Tip")
.setStyle(contentStyle)
.setSound(notifsound)
.setAutoCancel(true)
.setVibrate(pattern);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(1, builder.build());
if (count == contentTexts.size() - 1) {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("notification_count", 0);
editor.commit();
}
else {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("notification_count", count + 1);
editor.commit();
}
}
public void prepareContentTexts() {
contentTexts.add("Drivers who sit higher feel as if they're driving slower. " +
"Thus, SUV drivers, who are already piloting the vehicles most prone to " +
"roll, drive faster because they feel like they're creeping along. " +
"So lower your seat to get the sensation of more speed.");
contentTexts.add("Manufacturers recommend replacing your blades every three months. " +
"Keep a spare set in your trunk. A product such as Rain Clear can also help " +
"minimize the work of your wipers; spray it onto the glass every few weeks. " +
"In some light rains, it makes the wipers almost unnecessary");
contentTexts.add("At the BMW Performance Driving School, instructor Jim Clark says " +
"these four words over and over: \"Slow in, fast out.\" When taking a corner," +
" you need to scrub as much of that speed as you can while the car is braking" +
" in a straight line, then you can accelerate out of the curve. The converse " +
"is \"Fast in, maybe no out.\"");
}
public void prepareContentTitles() {
contentTitles.add("Lower Your Seat");
contentTitles.add("Rainproof Your Windshield");
contentTitles.add("Maneuver Tight Corners ");
}
}
The notification displays different content texts every time it is fired