如何每天每小时在Android上提供背景通知(例如,上午7:00,8:00,9:00 am)

时间:2017-02-13 17:51:33

标签: java android

我正在为我的大学做一个时间表项目,我希望在每个小时使用AlarmManager生成通知,我几乎得到了解决方案,但是警报在随机时间内被触发,例如在几小时之间。我想要的是在每天的每个小时触发警报管理器消息,例如每天早上7点,早上8点等等。我的代码如下。

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;

    }

我花了一个多星期的时间来解决这个问题,希望有人能提供帮助。 提前谢谢。

2 个答案:

答案 0 :(得分:1)

如在AlarmManager的描述中那样:

  

注意:从API 19(KITKAT)开始,警报传递是不准确的:操作系统   将移动警报以最小化唤醒和电池使用。那里   是支持需要严格交付的应用程序的新API   担保;请参阅setWindow(int,long,long,PendingIntent)和   setExact(int,long,PendingIntent)。应用程序   targetSdkVersion早于API 19将继续看到   以前的行为,其中所有警报都在何时传递   请求。

我建议在准确的时间使用setExact代替setRepeating

另外,请查看此处所述的JobSchedulerAndroid AlarmManager setExact() is not exact

答案 1 :(得分:-1)

而不是:

x <- as.POSIXct( "2017-01-15")
format(x, "%a")
[1] "Sun"
format(x, "Week of the year: %W")
[1] "Week of the year: 02"

您需要通过实际时间来唤醒,而不是alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),AlarmManager.INTERVAL_HOUR,pendingIntent);

类似

System.currentTimeMillis()

试试这个。我改为Calendar calendar = Calendar.getInstance(); Date newDate = calendar.setTime(date2); alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,calendar.getTimeInMillis(),AlarmManager.INTERVAL_HOUR,pendingIntent);