Android notifications not getting posted when scheduled with AlarmManager - java

am trying to post notifications from my game after a certain interval. I call PostNotification() function from onReceive() method of my BroadcastReciever class to post the notification after 1 minute of starting the game.
BroadcastReceiver
public class NotificationReciever extends BroadcastReceiver
{
private static int count=0;
#Override
public void onReceive(Context context, Intent intent)
{
try
{
Bundle bundle = intent.getExtras();
String message = bundle.getString("message");
int id = bundle.getInt("id");
PostNotification(message, id);
}
catch (Exception e)
{
e.printStackTrace();
}
wl.release();
}
public void PostNotification(String notif, int id)
{
Notification notify=new Notification(R.drawable.icon,
notif,
System.currentTimeMillis());
Intent intent = new Intent(MyUtil.getInstance().context, MyActivity.class);
PendingIntent i=PendingIntent.getActivity(MyUtil.getInstance().context, 0, intent, 0);
notify.setLatestEventInfo(MyUtil.getInstance().context, "Title", notif, i);
MyActivity.notifyMgr.notify(id, notify);
}
}
}
I am calling ScheduleNotification() from onCreate() of MyActivity
public void ScheduleNotification()
{
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(MyUtil.getInstance().context, NotificationReciever.class);
intent.putExtra("id", NOTIFY_ID);
intent.putExtra("message", "message");
PendingIntent sender = PendingIntent.getBroadcast(MyUtil.getInstance().context, NOTIFY_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
}
But i do not recieve any notification and get the following error in my logcat
01-11 19:28:32.455: W/System.err(20661): java.lang.NullPointerException
01-11 19:28:32.475: W/System.err(20661): at android.content.ComponentName.<init>(ComponentName.java:75)
01-11 19:28:32.475: W/System.err(20661): at android.content.Intent.<init>(Intent.java:2893)
01-11 19:28:32.475: W/System.err(20661): at com.games.TestGame.NotificationReciever.PostNotification(NotificationReciever.java:41)
01-11 19:28:32.475: W/System.err(20661): at com.games.TestGame.NotificationReciever.onReceive(NotificationReciever.java:27)
I know that i am doing something wrong when creating intent for notification. I get notification correctly when i call is directly from my activity but something goes wrong when i call it through alarm
Intent intent = new Intent(MyUtil.getInstance().context, MyActivity.class);
Can anyone please tell me where i am going wrong.

The when parameter to the Notification constructor used by you is simply for display purposes. It won't delay the display of your Notification.
How about using an Alarm? It'll only accept an Intent, though.

It is total mistake of understanding. Look at the details of public Notification (int icon, CharSequence tickerText, long when). It is like below:
icon The resource id of the icon to put in the status bar.
tickerText The text that flows by in the status bar when the notification first activates.
when The time to show in the time field. In the System.currentTimeMillis timebase.
That means that it is just for show in the Notification Massage, not for the time of notification. If you want to give the notification at certain future time, you have to set an AlermManager for that time. The AlermManager will call the BroadcastReceiver. So you have to create a BroadcastReceiver also, in which you have to set the Notification.You can go through this link.

Related

Show alert instead of scheduled notification if the app is currently opened

I have an app that schedules a bunch of notifications (user has to answer questionnaires) locally using AlarmManager. The notification should show at certain points in the future.
I schedule the notifications like this:
private void scheduleNotification(Notification notification, int delay, int scheduleId, int notificationId) {
Intent notificationIntent = new Intent(context, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, notificationId);
notificationIntent.putExtra(NotificationPublisher.INTENT, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, scheduleId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, delay);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
The intent is received by a BroadcastReceiver that calls notify on the notification attached to the intent.
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String INTENT = "notification";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra(INTENT)) {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
Notification notification = intent.getParcelableExtra(INTENT);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}
}
This works fine so far. The problem that I'm facing is that I only want to show the notification if the app is currently not open/shown. If it's open I want to show an AlertDialog instead.
I know that it might be a better idea to put only the plain content of the notification into the intent and only build it when it should be displayed and I want to refactor that later on.
My main problem is, how do I determine in the onReceive of my broadcast receiver if the app is currently showing to decide if a notification or an alert should be displayed?
Or is there an entirely different approach that might work better (for example using WorkManager)?
I think you can handle it on your BroadcastReceiver
public void onReceive(Context context, Intent intent) {
if (isForeground(context))
// AlertDialog
else
// Notification
}
public boolean isForeground(Context mContext) {
ActivityManager activityManager = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.AppTask> tasks = activityManager.getAppTasks();
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).getTaskInfo().topActivity;
return topActivity.getPackageName().equals(mContext.getPackageName());
}
return true;
}

BroadcastReceiver received more than once

I am getting a problem with my reminder APP.
When I add first reminder broadcast is received once for second time broadcast is received twice for third time it is received thrice.
I tried many different solutions on StackOverfolow but none of them are working
Kindly help me out with detailed answer.
Link to Project
. code is given below:
Function to set Reminder:
public void startAlarm(Calendar c) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, number, intent, PendingIntent.FLAG_ONE_SHOT);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
Class receiving Broadcast:
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, intent.getAction(), Toast.LENGTH_LONG).show();
MediaPlayer mediaPlayer = MediaPlayer.create(context, Settings.System.DEFAULT_NOTIFICATION_URI);
mediaPlayer.start();
}
}
I see that you are setting the alarm inside Adapters onBindViewHolder. This is not the right place to setting alarm. Because when you call notifyDataSetChanged it will call onBindViewHolder again and it will set same alarm over and over.

Pop up window after the alarm signal - Android

I would like to know - how to show pop up window when AlarmManager will call? I've already created AlarmManager now I need to create something what will show popup window to cancel this Alarm.
My code:
public void setAlarm(long timeInMillis){
if(Build.VERSION.SDK_INT >= 23){
mCalendar.set(
mCalendar.get(Calendar.MONTH),
mCalendar.get(Calendar.YEAR),
mCalendar.get(Calendar.DAY_OF_YEAR),
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE)
);
}
final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarm.class);
intent.setData(currentUri);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.setExact(AlarmManager.RTC, timeInMillis, pendingIntent);
}
and
public class MyAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
MediaPlayer mediaPlayer = MediaPlayer.create(context, Settings.System.DEFAULT_RINGTONE_URI);
mediaPlayer.start();
}
}
onReceive(context, intent) {
/*show the dialog in this method. set the onclick so it can dismiss the alarm,
get the value for the alarm from the bundle. I may be wrong about this
but i think alarmManager has a cancel(PendingIntent operation) method that u can
just send in the intent and your done.
Call a stopMedia(context) method after the cancel in order to stop the media
that is playing
*/
showDialog(context, intent)
//Extract the play media code to a method for readability
playMedia(context)
}
That should solve your problem
Before the code was posted:
We can either use the pending intent and have an activity that handles the pending intent. or use the handler to execute the code.
In either case, create a dialog fragment and then use the appropriate context to show it. setOnClickListener { alarmManager.cancel } for the dialog fragment button.
A little more explanation may be required depending on how the alarm manager is setup

Java Android create canvas that will pop-up automatically at a specified date

I am developing a simple android app that manages events(An event contains a name, a description, and a date). For example: Somebody's birthday or something like that.
I want a canvas to pop up by itself at the specified date(even if I'm not in the application). I managed to create a Toast using AlarmManager and BroadcastReceiver which pop ups automatically at the specified date. But I can only write text to a Toast.
Is there any way to create a canvas that will pop up similar to a Toast?
My alarm manager:
AlarmManager alarms = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
IntentFilter filter = new IntentFilter("ALARM_ACTION");
registerReceiver(receiver, filter);
Intent intent = new Intent("ALARM_ACTION");
intent.putExtra("param", "It's your mom's birthday!");
PendingIntent operation = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarms.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000,operation) ;
And my Receiver class:
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//I want to replace the Toast with a canvas.
Toast.makeText(context, intent.getStringExtra("param"), Toast.LENGTH_SHORT).show();
}
}

Multiple notification on same intent

I am writing an application and in this application I need to set multiple notification with same intent just like open my application whenever user tap on any notification.
All the notification comes on different time and date without having any data but the problem is, if I set two notification for 03:27 PM and 03:28 PM then the first notification (03:27 PM) is canceled (Overwritten by second) and second is working correctly.
I am currently using this code for achieving this goal:
this method is used to set notification from Activity:
public static void setNotificationOnDateTime(Context context, long fireTime)
{
int requestID = (int) System.currentTimeMillis();
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, NotificationReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, requestID, i, 0);
am.set(AlarmManager.RTC_WAKEUP, fireTime, pi);
}
and my NotificationReceiver class look like this:
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
Log.w("TAG", "Notification fired...");
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent;
Bundle bundle = intent.getExtras().getBundle("NotificationBundle");
if(bundle == null)
{
contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, SplashScreen.class), 0);
}
else
{
contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MenuScreen.class)
.putExtra("NotificationBundle", bundle), 0);
}
Notification notif = new Notification(R.drawable.ic_launcher,
"Crazy About Android...", System.currentTimeMillis());
notif.setLatestEventInfo(context, "Me", "Message test", contentIntent);
notif.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(1, notif);
}
I alerady spend a lot time on googling and found some solutions but they didn't work for me here is the link of some of them:
android pending intent notification problem
Multiple notifications to the same activity
If any one knows how to do this please help me.
Quote:
Post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.
But you're always using 1 for the id parameter. Use a unique ID when you post several notifications.
Update If that doesn't help, you can still create Intents which do not compare as being equal, while having an equal effect.
this may be helpful
notif.flags |= Notification.FLAG_ONGOING_EVENT;
the notification will never close...
Try to set as below :
contentIntent=PendingIntent.getActivity(p_context, i, new Intent(context, MenuScreen.class),PendingIntent.FLAG_CANCEL_CURRENT);
It might help you.

Categories

Resources