Android notifications avoid unnecessary notification update - java

I'm using a service which are being called every single minute in the background. It fetches data using a HTTP Request and then notifies the user about the data via an Notification. The problem is that I don't want an notification to be created if it contains the same data that was already fetched and shown the last time.
I've tried to set like static variables and store the data from the latest request to compare it to the newest fetched data and in that way know if it's the same or not and wherever show the notification or not.
This is what some of my notification code looks like:
Intent notificationIntent = new Intent(NotificationService.this, MainMenu.class);
PendingIntent contentIntent = PendingIntent.getActivity(NotificationService.this, NOTIFICATION_REQUESTS_KEY, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);;
if (!powerManager.isScreenOn())
{
mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK |PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.ON_AFTER_RELEASE, "NotificationWakeLock");
mWakeLock.acquire(10000);
WakeLock mWakeLockCPU = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NotificationCPUWakeLock");
mWakeLockCPU.acquire(10000);
}
nm.notify(NOTIFICATION_REQUESTS_KEY, notification);

Save contentText locally, every time you get the data from the server, before notifying the user, make sure if it's a different contentText. If it's the same do not notify.

Related

Notification in Android Studio Not Coming on Time

I am currently developing an app on android studio using java where I want the user to be able to receive notifications from calendar events that they create. However, my notifications are not coming on time as they are either lagging or just not showing.
Here is my coding for the alarm receiver which sets up the notification:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String event = intent.getStringExtra("event");
String time = intent.getStringExtra("time");
int notId = intent.getIntExtra("id", 0);
Intent activityIntent = new Intent(context, CalendarActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, activityIntent, PendingIntent.FLAG_ONE_SHOT);
String channelId = "channel_id";
CharSequence name = "channel_name";
String description = "description";
NotificationChannel channel = new NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_HIGH);
channel.setDescription(description);
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentTitle(event)
.setContentText(time)
.setDeleteIntent(pendingIntent)
.setGroup("Group_calendar_view")
.build();
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
notificationManagerCompat.notify(notId,notification);
}
}
Here is my CustomCalendarView Activity that sets up the alarm:
private void setAlarm(Calendar calendar, String event, String time, int RequestCode){
Intent intent = new Intent(context.getApplicationContext(), AlarmReceiver.class);
intent.putExtra("event",event);
intent.putExtra("time",time);
intent.putExtra("id",RequestCode);
#SuppressLint("UnspecifiedImmutableFlag") PendingIntent pendingIntent = PendingIntent.getBroadcast(context,RequestCode,intent,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager)context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() ,pendingIntent);
}
For example: When I set an alarm for 10:20 am, the notification either doesn't pop up or pops up really late like at 10:22 am. Please help! Let me know if I need to provide any more information.
You should use exact alarms for firing alarm on time,
use alarmManager.setExact() instead of alarmManager.set().
setExact() method is like set(), but does not permit the OS to adjust the delivery time. The alarm will be delivered as nearly as possible to the requested trigger time.
Put setExact() instead of set
alarmManager.setExact(...);
But with different devices and interface updates, the performance of the application work differed from one device to another, in this case you must put some settings in your application such as Disable Software Battery Optimizations, make the application run in the background even after closing, give Permissions Autostart, turn on all notifications and display them etc. Finally, call the functions in the onStop() event of the Activity.
Yes, correct. You should ask user to allow Battery Optimization and in Android 12 or higher you should ask user to enable Alarms & Reminders permission as well.
But, when your app wants to fire alarms exactly on time you have to use exact alarms.

How to make a GPS foreground service which not being stopped when phone screen is turned off?

I'm trying to make a foreground service that will track the user running path
I want to this server run and track user location until the user closed but now it works fine with location tracking and path but the only problem is that when I service and put phone in pocket then after some time the service is being destroyed. but i put it on table then service run all over the night
Here is the code for starting the
java startForegroundService(new Intent(this, GoogleService.class));
Here is the code for the timer which starts when service is being started
mTimer.schedule(new TimerTaskToGetLocation(), 10,1000 );```
in TimerTasktoGetLocation
```java sendNotification_pause(getString(R.string.app_name)+" mp service",utils.convertSecondsToHMmSs(total_time),distance);
This the code for showing notification
RemoteViews notificationLayout = null;
notificationLayout= new RemoteViews(getPackageName(), R.layout.custom_notification_location);
Intent intent = new Intent(getApplicationContext(), GoogleService.class);
PendingIntent pendIntentapp_oopen = PendingIntent.getActivity(this, 0, new Intent(context, DrawerActivity.class).setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT), 0);
PendingIntent pending_intent_end = PendingIntent.getService(this, 0, intent.setAction(Actions.SERVICE_STOP), 0);
notificationLayout.setTextViewText(R.id.custom_notification_distance, "Distanz: "+Utils.distance_with_unite(distance));
notificationLayout.setTextViewText(R.id.custom_notification_duration, "Dauer: "+duration);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "CANNEL01")
.setSmallIcon(R.drawable.login_logo)
.setAutoCancel(false)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(notificationLayout)
.setOnlyAlertOnce(true)
.addAction(new NotificationCompat.Action(R.drawable.ic_close_black_24dp,"End",pending_intent_end))
.setContentIntent(pendIntentapp_oopen);
builder.setOngoing(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
#SuppressLint("WrongConstant") NotificationChannel channel = new NotificationChannel("CANNEL01", "Location", importance);
channel.setDescription("All the different interval tones");
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
startForeground(101,builder.build());
}else {
startForeground(101,builder.build());
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
}
I want to this server run and track user location until the user closed but now it works fine with location tracking and path but the only problem is that when I service and put phone in pocket then after some time the service is being destroyed. one more thing when i keep it on a table then service runs all over the night.
I'm wondering how why this happens
for an example https://play.google.com/store/apps/details?id=com.runtastic.android&hl=en
this app does not request any special permission and track the path, it will be also a good i get a clue how this kind of service works ?

Android: Is it possible to implement a notification with custom controls using NotificationCompat with API 10?

My specific issue is that I am trying to construct a custom notification layout using NotificationCompat.Builder, and using setOnClickPendingIntent to send actions to a service running as part of my app.
Basically I can get as far as applying a specific RemoteViews object to the notification, which is all good, but when I try to call setOnClickPendingIntent() for a widget inside the RemoteViews object (say, an ImageButton) it creates a malformed notification which is caught as an IllegalArgumentException in logcat.
When I try to set these onClickPendingIntents for API > 10, it works with no real trouble but with Gingerbread it breaks the notification. (It allows me to build the layout but the onClick pending intents don't work), just as described in on of the comments on this issue:
https://code.google.com/p/android/issues/detail?id=30495
In a previous SO response, CommonsWare says "The functionality was never there in the first place" as of two years ago.
(Android: setOnClickPendingIntent in a statusbar notification on Gingerbread)
Is that still true? If I want to put notification buttons in a layout that works with API 10, am I basically SOL?
Try this :
private void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
String appname = context.getResources().getString(R.string.app_name);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
Notification notification;
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, myactivity.class), 0);
// To support 2.3 os, we use "Notification" class and 3.0+ os will use
// "NotificationCompat.Builder" class.
if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
notification = new Notification(icon, message, 0);
notification.setLatestEventInfo(context, appname, message,
contentIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context);
notification = builder.setContentIntent(contentIntent)
.setSmallIcon(icon).setTicker(appname).setWhen(0)
.setAutoCancel(true).setContentTitle(appname)
.setContentText(message).build();
notificationManager.notify(0 , notification);
}
}
Hope this helps.

List all the available Notifications Ringtones in Android

I'm trying to change the default sound of the Notification and I do like this:
private void showNotification(Context context, String reminderid, String title, String shortinfo, String longinfo)
{
mNM = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
NOTIFICATION=Integer.parseInt(reminderid);
Notification notification = new Notification(R.drawable.icon, title,
System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, RemindersActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
notification.setLatestEventInfo(context, shortinfo,
longinfo, contentIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
notification.defaults |= Notification.DEFAULT_VIBRATE;
mNM.notify(NOTIFICATION, notification);
}
But you can notice that I'm giving number the ID "6" for the URI.withAppendedPath(), I need to list all the available Notifications Ringtones for the user and let him choose, and I will pass the ID of what he choose instead of "6".
Here Google says:
In this case, the exact ID of the media file ("6") is known and appended to the content Uri. If you don't know the exact ID, you must query all the media available in the MediaStore with a ContentResolver. See the Content Providers documentation for more information on using a ContentResolver.
How can I do what they say (note that I never worked with content providers or resolvers)? and give the user the option to choose the ringtone for notification like choosing it in phone settings?
Thanks in advance.
You can add sound to your raw folder, initialize it
MediaPlayer mpSplash = MediaPlayer.create(this, R.raw.slow);
and call it where ever required
mpSplash.start();

Android: Managing Multiple Notifications

I am trying to create multiple notifications in my application. To identify each notification uniquely, i have given them an unique identificationId. Following is my code:
private void updateNotification(int notificationId, int clockStatusID, CharSequence text) {
//notificationManager.cancel(notificationId);
// throws up an ongoing notification that the timer is running
Log.i("TIMERCOUNT", "Notification id: " + notificationId);
Notification not = new Notification(clockStatusID, // the
// icon
// for
// the
// status
// bar
text, // the text to display in the ticker
System.currentTimeMillis() // the timestamp for the
// notification to appear
);
Intent intent = new Intent();
intent.putExtra("notificationID", notificationId);
intent.setAction("actionstring" + System.currentTimeMillis());
intent.setClassName("com.chander.time.android.activities",
"com.chander.time.android.activities.Tabs");
not.setLatestEventInfo(self,
getText(R.string.timer_notification_title),
getText(R.string.timer_on_notification_text), PendingIntent
.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT));
not.flags += Notification.FLAG_ONGOING_EVENT;
not.flags += Notification.FLAG_NO_CLEAR;
notificationManager.notify(notificationId, not);
}
Problem:
When a notification is selected, Tabs activity is called passing the intent. I want to access the unique notificationId of the notification that was selected in Tabs. I tried intent.putExtra() to save the notificationId in the intent. But, for multiple notifications its overwriting the notificationId and returns the latest one. I dont understand as to why this is happening and how can i avoid this overwriting of notificationId.
Thanks,
Chander
I got the answer. The intents were getting cached in. To, make a new intent, just add the following piece of code:
saveCallIntent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
This makes the intent unique.
Also, someone suggested me the following piece of code to make the intent unique:
saveCallIntent.setAction("actionstring" + System.currentTimeMillis());
It didnt help me, but might be of help to someone else.
--Chander
just place the notificationId instead of 0 in pendingIntent.
PendingIntent.getActivity(this, notificationId, intent,PendingIntent.FLAG_UPDATE_CURRENT));
The user must also update the following code together with the above one to get it working.
mNotificationManager.notify(notificationId, mBuilder.build());

Categories