I have the following code to make a notification when the network state changes.
but when i change the network state the app stops working !
please help me with making notification.
I am sure the problem is in addMyNotification function . but dont know how to fix it.
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent broadcast) {
addMyNotification("hi","hello",1,context);
}
private void addMyNotification(String title,String message,int id ,Context context ) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(context)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true);
Intent notificationIntent = new Intent(context, SendFood.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, id, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
// Add as notification
NotificationManager manager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
manager.notify(id, builder.build());
}
Related
I am working on a simple Water Reminder app. One of the final things that are left to implement is adding "Remind me later" option when the reminder notification pops. I've searched in many similar questions and articles but I didn't find solution. The thing is that I dont even know what i'm supposed to do...Start some activity, or send something to broadcast receiver or something else. I don't even know how to start trying different approaches. I will be very thankfull if someone helps me! Below is the code. What can I add to the code to implement this function?
public class ReminderManager {
public void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Uri soundUri = Uri.parse(Constants.PATH_TO_NOTIFICATION_RINGTONE);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build();
NotificationChannel notificationChannel = new NotificationChannel
(Constants.NOTIFICATION_CHANNEL_ID, "WaterReminderChannel", NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setSound(soundUri, audioAttributes);
notificationChannel.setDescription("Channel for Water Reminder");
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(notificationChannel);
}
}
public void setReminder() {
Intent intent = new Intent(context, ReminderBroadcastReceiver.class);
PendingIntent pendingIntentForBroadcast = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + MainActivity.reminderTime, pendingIntentForBroadcast);
}
public class ReminderBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent i) {
if (MainActivity.reminderTime > 0 && !MainActivity.dayFinished) {
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
Uri soundUri = Uri.parse(Constants.PATH_TO_NOTIFICATION_RINGTONE);
Notification notification = new NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.mipmap.water)
.setContentTitle("Water Reminder")
.setContentText("It's time to drink something!")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSound(soundUri)
.setDefaults(Notification.DEFAULT_VIBRATE)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(1, notification);
}
}
If I understand you correctly, I believe the simplest way to handle this is to use Notification “action buttons.” See https://developer.android.com/training/notify-user/build-notification for more detail.
Thanks. Your information helped me to solve the problem. I've made it and want to share my code because it's very simple and maybe will save someone's time instead of searching alot of complicated solutions like I did.
So, below is the code that set alarm for specified by the user time, then after that time occurs the BroadcastReceiver gets triggered even when the phone is in idle state thanks to "AlarmManagerCompat.setExactAndAllowWhileIdle" (works for older and newer Android versions). Then the receiver checks by which action is triggered - SNOOZE or REMINDER. If it's SNOOZE, it calls the setReminder() method of my custom ReminderManager class to reset the alarm and then calls notificationManager.cancelAll() to remove the previous notification banner. If it's REMINDER then it calls the showNotification() method which build the notification and show it to the user (I don't find the need to build the notification before the time when the AlarmManager is set to trigger the receiver).
In my ReminderManager class I have createNotificationChannel() method which is needed for newer Android versions and I call it in onCreate of MainActivity. The setReminder() method is called from places that it needs the reminder to be set (when the user sets notification and from the BroadcastReciever as described above) and the showNotification() method is called from BroadcastReciever as described above.
public class BroadcastReceiver extends android.content.BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ReminderManager reminderManager = new ReminderManager(context);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
if (intent.getAction().equals(Constants.SNOOZE_ACTION)) {
reminderManager.setReminder();
notificationManager.cancelAll();
} else if (intent.getAction().equals(Constants.REMINDER_ACTION)) {
reminderManager.showNotification();
}
}
}
public class ReminderManager {
private final Context context;
public ReminderManager(Context context) {
this.context = context;
}
public void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build();
NotificationChannel notificationChannel = new NotificationChannel
(Constants.NOTIFICATION_CHANNEL_ID, "WaterReminderChannel",
NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setSound
(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), audioAttributes);
notificationChannel.setDescription("Channel for Water Reminder");
NotificationManager notificationManager =
context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(notificationChannel);
}
}
public void setReminder() {
Intent intent = new Intent(context, BroadcastReceiver.class);
intent.setAction(Constants.REMINDER_ACTION);
PendingIntent pendingIntentForBroadcast =
PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP,
System.currentTimeMillis()
+ MainActivity.reminderTime, pendingIntentForBroadcast);
}
public void showNotification() {
Intent maniActivityIntent = new Intent(context, MainActivity.class);
PendingIntent mainActivityPendingIntent =
PendingIntent.getActivity(context, 0, maniActivityIntent, 0);
Intent snoozeIntent = new Intent(context, BroadcastReceiver.class);
snoozeIntent.setAction(Constants.SNOOZE_ACTION);
PendingIntent snoozePendingIntent =
PendingIntent.getBroadcast(context, 0, snoozeIntent, 0);
Notification notification = new NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.mipmap.water)
.setContentTitle("Water Reminder")
.setContentText("It's time to drink something!")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setDefaults(Notification.DEFAULT_VIBRATE)
.setContentIntent(mainActivityPendingIntent)
.addAction(android.R.drawable.ic_lock_idle_alarm, "Remind me later", snoozePendingIntent)
.setAutoCancel(true)
.build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(0, notification);
}
}
I am a newbie in android developement.I have set an alarm at an 5 seconds interval.
So once the alarm is triggered, I have set a notification.But when I select notification,I configured the page to move some other activity .But nothing is happen.
public class Snooze extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1=new Intent(context,NotificaitonPage.class);
intent1.putExtra("notify","SNOOZE") ;
intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Push notification alerts")
.setContentText("This for alaram notification")
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setStyle(new NotificationCompat.BigTextStyle().bigText("This for alaram notification")) ;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
}
}
So, Please help me to solve the problem.
Advance Thanks.
When you create PendingIntent you should use PendingIntent.getActivity() instead of PendingIntent.getBroadcast. See more link
Add the following flag to your intent1:
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
As pointed out by #Alexander in another answer, you also need to setup your PendingIntent as:
pendingIntent.getActivity();
i have a notification which i'm calling from a service. I want to call the service again on notification click. But the notification click is not able to get inside the method.
Intent intent = new Intent(this, MyService.class).setAction(ACTION_1);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.food)
.setContentTitle("notification")
.setContentText("near by you!");
NotificationManager mNotificationManager =(NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE);
Method that i want to call is
if (ACTION_1.equals(resultPendingIntent)) {
getRecommendation();
}
mBuilder.setContentIntent(resultPendingIntent);
mNotificationManager.notify(id, mBuilder.build());
i have tried following link but not able to resolve my problem.
How to execute a method by clicking a notification
You can specify a Broadcast in your Service and launch that via a PendingIntent in your notification.
Intent stopIntent = new Intent("my.awersome.string.name");
PendingIntent stopPi = PendingIntent.getBroadcast(this, 4, stopIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Then, in your notification builder:
NotificationCompat.Builder builder;
builder = new NotificationCompat.Builder(context)
...
.setContentIntent(stopPi);
In your Service you can setup a BroadcastReceiver as:
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Code to run
}
};
You register this receiver in your Service (possibly in onStartCommand()) only using:
registerReceiver(myReceiver, new IntentFilter("my.awersome.string.name"));
Your Service MUST be running for this to work.
Better option is to try How to execute a method by clicking a notification ..but be careful because of the static class
I want to auto cancel my notification when user clicks on notification. The following code works good in all the devices except Android lollipop device. In Lollipop device, notification goes only when user swipes it off.
#SuppressWarnings("deprecation")
public void sendNotification(int id){
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Test")
.setContentText("Jump to next screen")
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true);
mBuilder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONLY_ALERT_ONCE;
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, NextActivity.class);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
resultIntent, 0);
//PendingIntent.FLAG_UPDATE_CURRENT
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// id, if there is a need to update the notification later on.
mNotificationManager.notify(id, mBuilder.build());
Log.v(TAG, "Notification ID value " + id);
//mNotificationManager.cancel(id);
}
What is missing in this code?
Looks good to me. My auto cancel still works on 5.0.2. Let me give you a portion of my code:
public static void notif(int id, String title, String text, Context context, Class activity) {
// get an instance of the NotificationManager service
if (mNotifyMgr == null)
mNotifyMgr = (NotificationManager) context.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(context, activity);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.launcher)
.setContentTitle(title)
.setContentText(text)
.setContentIntent(notifIntent);
mNotifyMgr.notify(id, mBuilder.build());
}
modify following:
setAutoCancel(true) -> setAutoCancel(false);
then on action activity do the following
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
if you want to set special condition you can set by
intent.putExtra("key", "value")
I have created a custom layout notification using remoteview. Problem I'm facing is, How to autoCancel the notification once the user touches it.
I did try few things, but none is giving desired result.
Find Code below:
RemoteViews remoteView = new RemoteViews(this.getPackageName(), R.layout.notification_layout);
NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
builder.setSmallIcon(R.drawable.ic_launcher);
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this, RQST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);
remoteView.setOnClickPendingIntent(R.id.btnNotification, pIntent);
builder.setAutoCancel(true);
builder.setContent(remoteView);
Notification notify = builder.build();
notify.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager notiManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notiManager.notify(NOTY_ID, notify);
For others who have a custom layout and want auto cancel to work,
If clicking anywhere on notification is ok, then don't use remoteView.setOnClickPendingIntent. Because any view with OnClick Listener overrides the notification main OnClick Listener.
Use setContentIntent instead:
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentTitle("title");
builder.setContentText("contect");
builder.setSmallIcon(#smallicon);
builder.setWhen(#when);
builder.setContent(remoteViews);
builder.setContentIntent(onClickPendingIntent); // use this
builder.setAutoCancel(true);
The way I achieved this is by creating BroadcastReceiver which controls button clicks from Notification. Create something like this :
public class NotificationButtonListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int action = intent.getIntExtra("mode", -1);
switch (action) {
// do some things depending on action if there are more stuff to do
}
}
}
Don't forget to add your BroadcastListener to your manifest file:
<receiver android:name=".NotificationButtonListener">
And you can create a helper class for creating and cancelling notification:
public class NotificationHelper {
private static final int NOTIFICATION_ID = 5;
private static NotificationManager mNotificationManager = null;
public static void showNotification(Context context) {
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.custom_notification_layout);
contentView.setOnClickPendingIntent(R.id.btn_close, closePendingIntent);
Intent mMainIntent = new Intent(context, MainActivity.class);
mMainIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent mMainPendingIntent = PendingIntent.getActivity(context, 555, mMainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setTicker("Playing")
.setContent(contentView)
.setAutoCancel(false)
.setOngoing(true)
.setSmallIcon(R.drawable.ic_av_play)
.setContentIntent(mMainPendingIntent);
Notification notification = mBuilder.build();
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
public static void cancelNotification() {
if (mNotificationManager != null) {
mNotificationManager.cancelAll();
}
}
}
And using that class in your NotificationButtonListener you can call NotificationHelper.cancelNotification(); .
Hope this helps you!