I start to combine alarm manager and notification manager on android, and this is my code:
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setReminderAlarm();
}
public void setReminderAlarm() {
Intent intent = new Intent(MainActivity.this, ReminderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ReminderReceiver.NOTIF_ID, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 59);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 86400000L, pendingIntent);
}
ReminderReceiver.java
public static int NOTIF_ID = 101;
#Override
public void onReceive(Context context, Intent intent) {
showAlarmNotification(context);
}
public void showAlarmNotification(Context context) {
Intent intentClick = new Intent(context, MainActivity.class);
PendingIntent pendingClick = PendingIntent.getActivity(context, 0, intentClick, 0);
NotificationManager notificationManagerCompat = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.cinema)
.setContentTitle(title)
.setContentIntent(pendingClick)
.setContentText(message)
.setColor(ContextCompat.getColor(context, android.R.color.transparent))
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
.setSound(alarmSound)
.setAutoCancel(true);
notificationManagerCompat.notify(NOTIF_ID, builder.build());
}
Every time I run the application, the notification always appears even though I have set the time. How do I prevent that?
Thank you.
The issue is you are setting the time to current day. So if you are opening your app after 6:00, your alarm manager will immediately fire.
You need to check whether the time is over 6:00 for the current day, if yes you need to change the date to the next day:
public void setReminderAlarm() {
Intent intent = new Intent(MainActivity.this, ReminderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ReminderReceiver.NOTIF_ID, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int curHr = calendar.get(Calendar.HOUR_OF_DAY);
// Checking whether current hour is over 6
if (curHr >= 6)
{
// Since current hour is over 6, setting the date to the next day
calendar.add(Calendar.DATE, 1);
}
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 59);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 86400000L, pendingIntent);
}
Related
I'm using alarmmanager class to schedule notification for the user to lunch every day in a certain time but when th time comes it force stop the application
this is the setAlarm() method that i call onCreate of the main activity
public void setAlarm() {
// TODO Auto-generated method stub
AlarmManager alarmMgr;
PendingIntent alarmIntent;
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
// Set the alarm to start at approximately 8:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 17);
// With setInexactRepeating(), you have to use one of the AlarmManager
// interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
alarmIntent);
}
and that's the the BroadcastReceiver Class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
creatNotification(context, "Times Up", "5 Seconds Passed", "Alert");
}
private void creatNotification(Context context, String MSG, String MSgText, String MSGAlert) {
PendingIntent NotifIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context);
notifBuilder.setContentTitle("title").setContentText("Content")
.setTicker("Ticker").setSmallIcon(R.drawable.ic_launcher);
notifBuilder.setContentIntent(NotifIntent);
notifBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
notifBuilder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notifBuilder.build());
}
any Ideas ??
Did you define your Broadcast receiver on Manifest file?
I need to show a notification at 3 AM everyday. It is working fine and sending notification around 3 AM. But when I test in my phone the notification comes immediately. I read that if the time is already crossed it will show the notification. I am fine with this.
Issue: When i click the notification it opens my activity correctly. But after few seconds it is loading another notification. If i click that again it is closing the notification and creating a new one after few seconds.
Here is the code:
1. In the activity onCreate()
Calendar calendar = Calendar.getInstance();
// calendar.set(Calendar.MONTH, 10);
// calendar.set(Calendar.YEAR, 2014);
// calendar.set(Calendar.DAY_OF_MONTH, 13);
calendar.set(Calendar.HOUR_OF_DAY, 3);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
Intent myIntent = new Intent(LitCalActivity.this, MyReceiver.class);
pendingIntent = PendingIntent.getBroadcast(LitCalActivity.this, 0, myIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
In My service Class
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// Code to notification setup
Intent litrcalintent = new Intent(this, LitCalActivity.class);
Bundle bundle = new Bundle();
bundle.putString("FromNotify", "YES");
litrcalintent.putExtras(bundle);
PendingIntent pIntent = PendingIntent.getActivity(this, 0,
litrcalintent, PendingIntent.FLAG_UPDATE_CURRENT);
SimpleDateFormat format = new SimpleDateFormat("MMMM dd yyyy");
String today = format.format(currentDate);
String todayDetails = getLitCalDetails();
Notification notification = new Notification.Builder(this)
.setContentTitle("Liturgical Calendar for " + today)
.setContentText(todayDetails)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.setOngoing(false)
.addAction(R.drawable.ic_launcher, "more...", pIntent).build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
So I don't know why this code is not working. I wanted to make an "alarm" notification that would go off once a day. Just wanted to say im new to android. Thanks.
Edit: Changed up the code a bit. Alarm method executes and the notification does too, but I get this error message:
-248/? D/PowerManagerService﹕ releaseWakeLock flags=0x1 tag=AlarmManager W/ActivityManager﹕ Unable to start service Intent { flg=0x4 cmp=com.example.polakken.test/.lol (has extras) }: not found 06-13 00:00:00.825 231-267/? D/PowerManagerService﹕ acquireWakeLock flags=0x1 tag=AlarmManager 06-13 00:00:00.825 231-248/? D/PowerManagerService﹕ releaseWakeLock flags=0x1 tag=AlarmManager –
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
int i = preferences.getInt("numberoflaunches", 1);
if (i < 2) {
alarmMethod();
i++;
editor.putInt("numberoflaunches", i);
editor.commit();
}
if (savedInstanceState == null) {
splashMethod();
}
}
//...
private void alarmMethod() {
Intent intentbro = new Intent(this, lol.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intentbro, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.add(Calendar.DAY_OF_MONTH, 1);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pendingIntent);
Toast.makeText(MainActivity.this, "start alarm", Toast.LENGTH_LONG).show();
}
//notification class
public class lol extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NotificationCompat.Builder b = new NotificationCompat.Builder(this);
Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 1, intent1, 0);
b.setContentText("lol");
b.setContentTitle("Default notification");
b.setSmallIcon(R.drawable.iconography_small_size);
b.setContentIntent(pIntent);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, b.build());
}
}
You are adding an extra day to your alarm. It should look like this:
...
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR_OF_DAY, 1);
calendar.set(Calendar.AM_PM, Calendar.AM);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
...
You are calling PendingIntent pendingIntent = PendingIntent.getService(this, 0, intentbro, 0);
However, you need to declare this Service in your AndroidManifest like this:
<service android:name=".Lol" />
Also, classes in Java should be capitalized, but your Intent calls a lower-case class:
Intent intentbro = new Intent(this, lol.class);
I suggest you run static analysis on your code to see how to improve it!
I'm using the AlarmManager to fire a notification daily in specific time which is selected via time picker. The notification fired correctly in the same day but doesn't repeat correctly every day!!!
This is the method for setting the notification using setRepeating():
public void witer_reminder(View view)
{
am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, Witer_Notification.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
Calendar calSet = (Calendar) cal.clone();
calSet.set(Calendar.HOUR_OF_DAY, picker.getCurrentHour());
calSet.set(Calendar.MINUTE, picker.getCurrentMinute());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
if(calSet.compareTo(cal) <= 0)
{
// Today Set time passed, count to tomorrow
calSet.add(Calendar.DATE, 1);
}
am.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
24 * 60 * 60 * 1000, pendingIntent);
}
and this is the BroadcastReciver class:
public class Witer_Notification extends BroadcastReceiver
{
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent)
{
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
PendingIntent actiontIntent = PendingIntent.getActivity(context, 0,
new Intent(context, Suggestion.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("")
.setStyle(new NotificationCompat.BigTextStyle().bigText(""));
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
// mBuilder.setStyle(new NotificationCompat.InboxStyle());
NotificationManager mNotificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
BTW, the application target is SDK 19.
I found that the setExact() replacing to set()
Correct.
it's not applicable for intervalAtMilis as a parameter
Not directly. But, when you get control in your BroadcastReceiver from the setExact() event, call setExact() again to schedule the next event.
I didn't find anything for setRepeating()
There is no simple solution, because Google is trying to point out to you that this is bad for the battery. Using setExact() as described above is your only option for exact repeating.
I have this code:
set alarm:
public void setAlarm()
{
Calendar Calendar_Object = Calendar.getInstance();
Calendar_Object.add (Calendar.DAY_OF_YEAR, 1);
Calendar_Object.set(Calendar.HOUR_OF_DAY, 0);
Calendar_Object.set(Calendar.MINUTE, 0);
Calendar_Object.set(Calendar.SECOND, 1);
Intent myIntent = new Intent(Main.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Main.this,
0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, Calendar_Object.getTimeInMillis(),1000*60*60*24, pendingIntent);
}
Broadcast receiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, NotificationService.class);
context.startService(myIntent);
}
}
the service:
public class NotificationService extends Service {
private NotificationManager mManager;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#SuppressWarnings("deprecation")
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
mManager = (NotificationManager) this.getApplicationContext()
.getSystemService( this.getApplicationContext().NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(), ABC.class);
Notification notification = new Notification(R.drawable.ic_launcher,
"xxx", System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(
this.getApplicationContext(), 0, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(this.getApplicationContext(),
"abc", "xyz",
pendingNotificationIntent);
mManager.notify(0, notification);
}
}
after setting the alarm at 00:00:01 everything is perfect but the next time the problem is happening. the PendingIntent triggers like 6 to 8 times between the 24 hours interval. I don't remember if the time is the same for each trigger but I want it one time each day. What is wrong with the code?
This will create an alarm that will go off every day at 00:05, the important part is the AlarmManager.INTERVAL_DAY
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 5);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.HOUR, 24);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
mgr.cancel(pi);
mgr.setRepeating(AlarmManager.RTC, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
Also, don't forget to always cancel previous similar alarms, when re-setting a new one, or else they'll all go off, old set alarms, and the new one, see above mgr.cancel(pi);