0

I am doing a time table project for my college, in which I want to generate notification on each hour using AlarmManager, I almost got the solution, but the alarm gets triggered during random time, like between hours. What I want is to trigger alarm manger messages on exactly each hour, like 7.00am,8.00am, and so on on everyday. My code is given below.

MainActivity.java

    public class MainActivity extends AppCompatActivity {

DatabaseHelper2 db = new DatabaseHelper2(this);

private PendingIntent pendingIntent;
private AlarmManager alarmManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    Cursor resService = db.getAllData();
    int pref = 0;
    if(resService.getCount()!=0){

        Date date2 = new Date();
        int h=date2.getHours();
        int m = date2.getMinutes();
        int s = date2.getSeconds();

        Intent alarmIntent = new Intent(this,AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(this,0,alarmIntent,0);
        alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        //int interval = 60 * 60 * 10000;
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),AlarmManager.INTERVAL_HOUR,pendingIntent);
        Toast.makeText(this,"Alarm set at "+h+" : "+m+" : "+s,Toast.LENGTH_LONG).show();
    }


}

AlarmReciever.java

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Date d = new Date();
        Toast.makeText(context,"Broadcast message triggered at "+d.getHours()+":"+d.getMinutes()+":"+d.getSeconds() ,Toast.LENGTH_SHORT).show();
        Intent service1 = new Intent(context, MyService.class);
        context.startService(service1);
    }
}

MyService.java

public class MyService extends Service {
    DatabaseHelper2 db = new DatabaseHelper2(this);
    String sub;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Date date = new Date();
        int now=date.getHours();
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
        String dayOfWeek = sdf.format(date);
        Cursor resNow = db.getNowSub(now,dayOfWeek);

        if(resNow.getCount()!=0){
            if(resNow.moveToNext()){
                sub = resNow.getString(3);
            }
            NotificationManager notif = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
            Notification notify =  new Notification.Builder
                    (getApplicationContext()).setContentTitle("NowSub").setContentText("Now:"+sub+ " at "+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds()).setContentTitle("currenet subject").setSmallIcon(R.mipmap.ic_launcher).build();
            notify.flags |= Notification.FLAG_AUTO_CANCEL;
            notif.notify(0, notify);

        }



        return START_STICKY;

    }

I spent more than a week for this particular problem, hope someone will help. Thanks in advance.

Arshad
  • 37
  • 9

2 Answers2

1

As in the description of AlarmManager:

Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.

I suggest to use setExact instead of setRepeating to be waked up at an exact time.

Also, check out JobScheduler as stated here: Android AlarmManager setExact() is not exact

Community
  • 1
  • 1
JFPicard
  • 5,029
  • 3
  • 19
  • 43
-1

Instead of this:

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),AlarmManager.INTERVAL_HOUR,pendingIntent);

You need to pass an actual time when you want this to wake up, not System.currentTimeMillis()

So something like

Calendar calendar = Calendar.getInstance();
Date newDate = calendar.setTime(date2);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,calendar.getTimeInMillis(),AlarmManager.INTERVAL_HOUR,pendingIntent);

Try this instead. I change to AlarmManager.ELAPSED_REALTIME

Renats Stozkovs
  • 2,549
  • 10
  • 22
  • 26