Naveen Kumar Mishra
Naveen Kumar Mishra

Reputation: 351

Alarm Manager not triggering on time when app is closed

I want to set an alarm at 9am that will execute only once in a day and with this alarm i want to execute one BroadcastReciver and through that BroadcastReciver i want to execute Service. I am Using the following code but in this code following are problems 1)Alarm is not execute at exact 9am. 2)When it execute it execute more than one times

Please help me to resolve this problems.Any help will be appreciable.

=========================================================== The value of breakfastflag is boolean which i am taking from this activity when user press on the click to customize b

     if(breakfastflag){
        Intent myIntent = new Intent(SplashScreenActivity.this, MyBreakfastReciver.class);
          System.out.println("getting Breakfast Reminder");
        pendingIntent = PendingIntent.getBroadcast(SplashScreenActivity.this, 0, myIntent,0);
        // Set the alarm to start at approximately 9:00 a.m.
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 9);
        AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
        // With setInexactRepeating(), you have to use one of the AlarmManager interval
        // constants--in this case, AlarmManager.INTERVAL_DAY.
         alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
    }



   BreakfastReciever.java

  ==============================
 public class MyBreakfastReciver extends BroadcastReceiver
 {

@Override
 public void onReceive(Context context, Intent intent)
{
   Intent service1 = new Intent(context, MyBreakfastAlarmService.class);
   context.startService(service1);

  }

}

  MyBreakfastAlarmService.java

 ===================================

        public class MyBreakfastAlarmService extends Service 

       {
      private NotificationManager mManager;

      @Override
     public IBinder onBind(Intent arg0)
    {
   // TODO Auto-generated method stub
    return null;
    }

   @Override
   public void onCreate() 
   {
   // TODO Auto-generated method stub  
   super.onCreate();
    }

   @SuppressWarnings("static-access")
   @Override
   public void onStart(Intent intent, int startId)
   {  

   DatabaseHandler db=new DatabaseHandler(getApplicationContext());
   HashMap<String,String> user = new HashMap<String,String>();
   String abc="Breakfast";
   user= db.getUserCalDetails();
   String userid=user.get("userid");

    final Calendar c = Calendar.getInstance();
    int  mYear = c.get(Calendar.YEAR);
    int   mMonth = c.get(Calendar.MONTH);
    int   mDay = c.get(Calendar.DAY_OF_MONTH);
     String day="";
     String month="";
     mMonth=mMonth+1;

    if(mMonth<=9){

        month="0"+mMonth;

    }
    else{

        month=""+month;
    }

   if(mDay<=9){

        day="0"+mDay;

    }
    else{

        day=""+mDay;
    }

     String year=mYear+"";

    String finalDate=year+"-"+month+"-"+day;   
    int ab=db.getMealDettailsForRemider(userid,abc ,finalDate);

    if(ab==0) 
   {


     showNotification(this); 
   }


   }



   @SuppressLint("NewApi") private void showNotification(Context context) {
    NotificationCompat.Builder mBuilder =
           new NotificationCompat.Builder(context)
           .setSmallIcon(R.drawable.capture)
           .setAutoCancel(true)
           .setContentTitle("DietGuru")
           .setContentText("You haven't logged your Breakfast for today.")
           .setSubText("Would you like to do it now?")


           ;



  // Creates an explicit intent for an Activity in your app
   Intent resultIntent = new Intent(context, SplashScreenActivity.class);

   // The stack builder object will contain an artificial back stack for the
   // started Activity.
   // This ensures that navigating backward from the Activity leads out of
   // your application to the Home screen.
   TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
   // Adds the back stack for the Intent (but not the Intent itself)
   stackBuilder.addParentStack(SplashScreenActivity.class);

   // Adds the Intent that starts the Activity to the top of the stack
   stackBuilder.addNextIntent(resultIntent);


   PendingIntent resultPendingIntent =
           stackBuilder.getPendingIntent(
               0,
               PendingIntent.FLAG_UPDATE_CURRENT
           );
   mBuilder.setContentIntent(resultPendingIntent);
   mBuilder.setContentIntent(resultPendingIntent);
   mBuilder.setDefaults(Notification.DEFAULT_ALL);

   NotificationManager mNotificationManager =
           (NotificationManager)  context.getSystemService(Context.NOTIFICATION_SERVICE);
   // mId allows you to update the notification later on.

 mNotificationManager.notify(1, mBuilder.build());

  }

 @Override
 public void onDestroy() 
 {

     super.onDestroy();
  }

  }

Upvotes: 0

Views: 761

Answers (1)

Yash Sampat
Yash Sampat

Reputation: 30611

You should use setRepeating() instead of setInexactRepeating().

EDIT:

I have noticed two more mistakes in your code:

1. You have called mBuilder.setContentIntent(resultPendingIntent) twice. You should call it only once. I think this is why the alarm may be coming more than once.

2. You have written month=""+month;. It should be month=""+mMonth;

Try this. This should work.

EDIT 2:

According to the docs:

as of API 19, all repeating alarms are inexact. If your application needs 
precise delivery times then it must use one-time exact alarms, rescheduling 
each time as described above. Legacy applications whose targetSdkVersion is 
earlier than API 19 will continue to have all of their alarms, including 
repeating alarms, treated as exact.

To get the exact time, the only way is to use setExact() which needs to be set each time the alarm rings, because it doesn't repeat.

Upvotes: 1

Related Questions