I need to add an alarm to mobile's clock app for which I'm sending user a notification. When user clicks on notification a new alarm should be added with given time.
Below is the code:
//Create intent
Intent alarmIntent = new Intent(AlarmClock.ACTION_SET_ALARM);
alarmIntent.putExtra(AlarmClock.EXTRA_MESSAGE, event.getEventName());
Calendar alarmTime = new GregorianCalendar();
alarmTime.setTime(new Date(event.getAlarmTime()));
alarmIntent.putExtra(AlarmClock.EXTRA_HOUR, alarmTime.get(Calendar.HOUR_OF_DAY));
alarmIntent.putExtra(AlarmClock.EXTRA_MINUTES, alarmTime.get(Calendar.MINUTE));
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
//Create and show notification
NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel("MyAppsAlarm",
"MyAppsAlarmNotifications",
NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("Channel to show notifs");
mNotificationManager.createNotificationChannel(channel);
NotificationCompat.Builder builder = new NotificationCompat.Builder(main.getApplicationContext(), "Zzzzz")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Alarm Helper")
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(alarmPendingIntent);
mNotificationManager.notify(0, builder.build());
When I click on notification nothing happens. Notification stays as it is while the notification drawer closes automatically.
I tried to fire the intent using startActivity(alarmIntent); and it works as expected but from notification .setContentIntent(alarmPendingIntent); seems to be doing nothing.
If you want to set an alarm using AlarmClock.ACTION_SET_ALARM then you have to use PendingIntent.getActvity() instead of PendingIntent.getBroadcast(). AlarmClock.ACTION_SET_ALARM is an Activity ACTION.
If you don't want the UI of the alarm clock to be shown, you can add this to the Intent:
alarmIntent.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
You have to use broadcast receiver in your app to receive broadcast when the user clicks on notification.
Let your broadcast receiver is NotifBroadCastReceiver
public class NotifBroadCastReceiver extends BroadcastReceiver{
#override
void onReceive(Context context, Intent intent){
//you can extract info using intent.getStringExtra or any other method depending on your send data type. After that set alarm here.
}
}
So when create pending intent you can do
Intent intent = new Intent(context, BroadcastReceiver.class);
//set all the info you needed to set alarm like time and other using putExtra.
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Now when user click on notification, you will receive the broadcast in onReceive of NotifBroadCastReceiver.
NOTE You have to register your broadcast receiver in manifest like
<receiver
android:name="your broadcast receiver"
android:enabled="true"
android:exported="false" />
Related
I am trying to run a Retry routine upon notification action click, for this, I have created a BroadcastReceiver and also registered it in the AndroidManifest file.
While creating the notification with action I am using PendingIntent and setting that pending intent with the notification action.
When the app is running or in the background (not removed from the recent apps list) then the broadcast receiver is received instantly upon clicking the notification action. But after killing the app (removing it from the recent app list) the broadcast receiver takes some to fire.
Below are the code snippets for different components.
AndroidManifest file
<receiver android:name=".Receiver.RetryStatusBroadcastReceiver" android:enabled="true" android:exported="false"/>
Broadcast receiver
public class RetryStatusBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
Notification firing code
Intent retryIntent = new Intent(this, RetryStatusBroadcastReceiver.class);
PendingIntent retryPendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), uniqueId + 1, retryIntent, 0);
NotificationCompat.Action retryAction = new NotificationCompat.Action(R.drawable.ic_retry, "Retry", retryPendingIntent);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, getString(R.string.background_syncing_notification_channel_id))
.setSmallIcon(R.drawable.app_logo)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(Notification.DEFAULT_ALL)
.setContentTitle(notificationTitle)
.setContentText(notificationMessage)
.setStyle(new NotificationCompat.BigTextStyle().bigText(notificationMessage))
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.addAction(retryAction);
Intent intent = new Intent(this, HomeActivity.class);
PendingIntent activityPendingIntent = PendingIntent.getActivity(this, uniqueId, intent, PendingIntent.FLAG_ONE_SHOT);
notificationBuilder.setContentIntent(activityPendingIntent);
notificationBuilder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.notify(uniqueId, notificationBuilder.build());
}
I have also tried extending my BroadcastReceiver from WakefulBroadcastReceiver but the result is the same.
I have also tried removing android:enabled and android:exported tags but nothing seems to work here.
Would you please help me with the issue below?
I created a simple app that shows a notification for a incoming SMS. On that notification, I added a button to delete the SMS thru the notification.
Since I have a Samsung Gear S2, that Delete button is displayed on the Smart Watch and I can delete the SMS using my Gear S2.
Main problem is that when I delete the SMS using the Gear S2, the screen is wakening up. When I test using Gmail, same scenario just delete the email and keep the screen off.
So, could you please, help me to undestand why the screen is turning on?
Here, is how I create the notification (after receiving a SMS).
// Intent used to delete the SMS
Intent deleteIntent = new Intent(context, MessagingService.class);
deleteIntent.putExtra("notiID", id);
deleteIntent.putExtra("address", address);
deleteIntent.putExtra("date", date);
deleteIntent.putExtra("body", body);
PendingIntent deletePendingIntent = PendingIntent.getService(
context,
id,
deleteIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Intent used to start the app
Intent clickIntent = new Intent(context, MainActivity.class);
PendingIntent clickPendingIntent = PendingIntent.getActivity(
context,
id + 1,
clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Notification
NotificationCompat.Builder notiBuilder = new NotificationCompat.Builder(context);
notiBuilder.setSmallIcon(R.drawable.ic_message_white_32dp)
.setContentTitle(address)
.setContentText(body)
.setContentIntent(clickPendingIntent)
.addAction(R.drawable.ic_delete_white_32dp, context.getString(R.string.delete), deletePendingIntent)
.setLights(Color.BLUE, 3000, 3000);
Notification mNotificationBar = notiBuilder.build();
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, mNotificationBar);
What I tested:
For now, I move the "SMS Deletion" code to a Service. That's why I'm using:
Intent deleteIntent = new Intent(context, MessagingService.class);
PendingIntent deletePendingIntent = PendingIntent.getService(....);
But I also tried to delete the SMS using the BroadcastReceiver (same result):
Intent deleteIntent = new Intent(context, SmsReceiver.class);
deleteIntent.setAction("com.test.simplesms.DELETE_MESSAGE");
PendingIntent deletePendingIntent = PendingIntent.getBroadcast(....);
So, I'm not sure why the action configured by deletePendingIntent is turning the screen on.
Eventually, I could fix the error and I'm sharing here for future reference.
After debugging and researching, I discovered that I should extend my notification for wearable devices via WearableExtender.
This way, addAction() add the actions to Notification Bar while extend() add an WearableExtender which configure the actions that can be performed by the smartwatch (and this way, you can configure different stuff for Notification Bar and the Smartwatch)
// Intent used to delete the SMS
Intent deleteIntent = new Intent(context, SmsReceiver.class);
deleteIntent.putExtra("notiID", id);
deleteIntent.putExtra("address", address);
deleteIntent.putExtra("date", date);
deleteIntent.putExtra("body", body);
PendingIntent deletePendingIntent = PendingIntent.getBroadcast(
context,
id,
deleteIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Intent used to start the app
Intent clickIntent = new Intent(context, MainActivity.class);
PendingIntent clickPendingIntent = PendingIntent.getActivity(
context,
id + 1,
clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// ADD THIS
// Add a wearable extender.. an wearable action
NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender();
wearableExtender.addAction(new NotificationCompat.Action(R.drawable.ic_delete_white_32dp, context.getString(R.string.delete), deletePendingIntent));
// Notification
NotificationCompat.Builder notiBuilder = new NotificationCompat.Builder(context);
notiBuilder.setSmallIcon(R.drawable.ic_message_white_32dp)
.setContentTitle(address)
.setContentText(body)
.setContentIntent(clickPendingIntent)
.extend(wearableExtender) // ----> ADD THE WEARABLE HERE
.addAction(R.drawable.ic_delete_white_32dp, context.getString(R.string.delete), deletePendingIntent)
.setLights(Color.BLUE, 3000, 3000);
Notification mNotificationBar = notiBuilder.build();
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, mNotificationBar);
I think your SmsReceiver class extends from WakefulBroadcastReceiver
I have been searching for a few hours, but could not find any solution to my problem. Does anyone know how to make heads-up notification buttons call a broadcast? My code:
Alarm Receiver Notification Builder:
NotificationCompat.Builder builder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.alarmicon)
.setContentTitle("Alarm for " + timeString)
.setContentText(MainActivity.alarmLabel.getText().toString())
.setDefaults(Notification.DEFAULT_ALL) // must requires VIBRATE permission
.setPriority(NotificationCompat.PRIORITY_HIGH); //must give priority to High, Max which will considered as heads-up notification
//set intents and pending intents to call service on click of "dismiss" action button of notification
Intent dismissIntent = new Intent(context, notificationButtonAction.class);
dismissIntent.setAction(DISMISS_ACTION);
PendingIntent piDismiss = PendingIntent.getBroadcast(context, 0, dismissIntent, 0);
builder.addAction(R.drawable.alarmoff, "Dismiss", piDismiss);
//set intents and pending intents to call service on click of "snooze" action button of notification
Intent snoozeIntent = new Intent(context, notificationButtonAction.class);
snoozeIntent.setAction(SNOOZE_ACTION);
PendingIntent piSnooze = PendingIntent.getBroadcast(context, 0, snoozeIntent, 0);
builder.addAction(R.drawable.snooze, "Snooze", piSnooze);
// Gets an instance of the NotificationManager service
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//to post your notification to the notification bar with a id. If a notification with same id already exists, it will get replaced with updated information.
notificationManager.notify(0, builder.build());
notificationButtonAction:
public static class notificationButtonAction extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("notificationButtonAction Started");
String action = intent.getAction();
if (SNOOZE_ACTION.equals(action)) {
stopAlarm();
System.out.println("Alarm Snoozed");
MainActivity ma = new MainActivity();
ma.setAlarm(true);
}
else if (DISMISS_ACTION.equals(action)) {
stopAlarm();
System.out.println("Alarm Dismissed");
}
}
}
My print lines in notificationButtonAction do not print, not even the "notificationButtonAction Started."
I followed the tutorial from Brevity Software (http://www.brevitysoftware.com/blog/how-to-get-heads-up-notifications-in-android/), but their code didn't seem to work.
Any help is appreciated! Thanks!
Turns out, I didn't add the class to the manifest. My code was fine.
I am building a simple android app for java tutorial in which i want to keep one read later option using which the user can schedule a time for reading and at the specified time my app should give a notification to the user. Even if my app is not opened at that time he should get the notification in notifications bar.I am a newbie in android and have no idea about how to do this.Can someone please help me out?As a i am a newbie a detailed explanation can be more helpful.Thanks in advance :-)
To schedule a delayed notification, you
1) Create a BroadcastReceiver that will receive the event:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//you might want to check what's inside the Intent
if(intent.getStringExtra("myAction") != null &&
intent.getStringExtra("myAction").equals("notify")){
NotificationManager manager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.yourIcon)
//example for large icon
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setContentTitle("my title")
.setContentText("my message")
.setOngoing(false)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);
Intent i = new Intent(context, YourTargetActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(
context,
0,
i,
PendingIntent.FLAG_ONE_SHOT
);
// example for blinking LED
builder.setLights(0xFFb71c1c, 1000, 2000);
builder.setSound(yourSoundUri);
builder.setContentIntent(pendingIntent);
manager.notify(12345, builder.build());
}
}
}
Don't forget to declare it in the Manifest:
<receiver
android:name="your.package.name.MyReceiver"
android:exported="false" />
2) Schedule the action (assumed you do it from an Activity):
//will fire in 60 seconds
long when = System.currentTimeMillis() + 60000L;
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyReceiver.class);
intent.putExtra("myAction", "mDoNotify");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
am.set(AlarmManager.RTC_WAKEUP, when, pendingIntent);
3) You're done
//Disclaimer: haven't compiled the code, typos possible. The rest is your homework ;)
Use AlarmManager to solve your problem. And when alarm is received, you can send a notification too.
See this sample app in android's tutorial for implementing the alarms.
Hi I am new to notifications,
I wrote this code for notifications.
PendingIntent pendingIntent = PendingIntent.getActivity(context, leadidforstatus,
myIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.noti)
.setContentTitle("LMS notification")
.setContentIntent(pendingIntent)
.setContentText(intent.getStringExtra("messagenotify"))
.setAutoCancel(true);
i = (int) System.currentTimeMillis();
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(i, mBuilder.build());
In that I set one list of notifications. In that some displayed and some not displayed. But I want to cancel all un shown notifications.
I used mNotificationManager.cancleAll() but that is cancel only shown notifications.
thanks in advance.
I think the problem here is that The Notification is launched immediately after creating it and your not using the AlarmManager to schedule this Notification.
Solution Should be to schedule Alarms via an AlarmManager which will trigger the Notification Code above.
This requires 3 parts:
Register a BroadCastReceiver & Build a Notification when its triggered:
public class UtilityReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// .. Here is where you really want to build the notification and notify
// This will be triggered by the AlarmManager from the Code below
PendingIntent pendingIntent = PendingIntent.getActivity(context, leadidforstatus, myIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.noti)
.setContentTitle("LMS notification")
.setContentIntent(pendingIntent)
.setContentText(intent.getStringExtra("messagenotify"))
.setAutoCancel(true);
i = (int) System.currentTimeMillis();
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(i, mBuilder.build());
}
Schedule an Alarm with the AlarmManager to send a BroadCast which the Receiver above is listening for:
// Create an Intent to Launch
Intent notificationIntent = new Intent(context, UtilityReceiver.class);
// Use a Pending Intent to Launch the Alarm
PendingIntent notificationPendingIntent = PendingIntent.getBroadcast(context,
PendingIntent.FLAG_ONE_SHOT, notificationIntent, Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, timeForAlarmInMillis, notificationPendingIntent);
Then when you encounter the situation when you no longer want notifications to show for your app, you tell the AlarmManager to remove them from its queue of Alarms by Rebuilding the pending Intent and using AlarmManager to Cancel it.
// Create an Intent to Launch
Intent notificationIntent = new Intent(context, UtilityReceiver.class);
// Use a Pending Intent to Launch the Alarm
PendingIntent notificationPendingIntent = PendingIntent.getBroadcast(context,
PendingIntent.FLAG_ONE_SHOT, notificationIntent, Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// *********Important this will cancel all the Matching PendingIntents
alarmManager.cancel(notificationPendingIntent);
Good Luck, and be sure to register your Receiver in your Activity or Manifest.
NotificationManager maintains list of all notification mNotificationList and performs cancel or cancelAll operations on this list
I tried searching in Google source code of NotificationManager.java and NotificationManagerService.java in notify(),enqueueNotificationWithTag() and cancelAllNotification() But there is no implementation to cancel previously unshown notification
As per your comment, if your user is deleted and his notification arrives then user is already deleted so notification has no meaning
i = (int) System.currentTimeMillis();
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(i, mBuilder.build());
// i should be Id for this notification, i think you want to pass
// time in mili second here
I think you are searching similar to this,
How to dismiss notification after action has been clicked
Just check the answer on that post. Use the id to cancel that particular Notification
I think the id part in your code is this,
i = (int) System.currentTimeMillis();