应用程序关闭时警报管理器未按时触发

Alarm Manager not triggering on time when app is closed

我想在早上 9 点设置一个闹钟,一天只执行一次,并且 这个警报我想执行一个 BroadcastReciver 并通过那个 BroadcastReciver 我想执行服务。 我正在使用以下代码,但在此代码中以下是问题 1) 闹钟不是在早上 9 点准时执行。 2)当它执行时,它会执行多次

请帮我解决这个问题 problems.Any 帮助会很大。

============================================= ============== breakfastflag 的值是布尔值,当用户点击自定义 b

时,我从这个 activity 中获取
     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();
  }

  }

你应该使用 setRepeating() instead of setInexactRepeating().

编辑:

我注意到您的代码中还有两个错误:

1. 您已调用 mBuilder.setContentIntent(resultPendingIntent) 两次。你应该只调用一次。我认为这就是警报可能不止一次出现的原因。

2. 你写了month=""+month;。应该是month=""+mMonth;

试试这个。这应该有效。

编辑 2:

根据文档:

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.

要获得准确的时间,唯一的方法是使用setExact(),每次闹钟响时都需要设置,因为它不会重复。