服务开始后而不是设定时间发出警报

Alarm fires after service start instead of set time

我试图在每天早上 5 点设置一个触发器,让 phone 为 USER_PRESENT 广播做好准备,但一旦服务启动,触发器就会关闭。通过主电源上的开关关闭和打开服务 (PAService) activity 使用 stopServicestartService。此代码在 模拟器但不是实际的 Android phone.

public class PAService extends Service {

static boolean is_ready_to_speak = false;
PendingIntent pendingIntent;

public PAService() {

}

public class ScreenReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if(is_ready_to_speak)
        {
            PASpeak paspeak = new PASpeak();
            paspeak.sayit(getApplicationContext(),"You're using your phone for the first time this morning");
           is_ready_to_speak = false;
        }
    }
}


public static class AlarmReceiver extends BroadcastReceiver {

    public AlarmReceiver()
    {
        Log.d("AlarmReceiver func called","alarm receiver func called");
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("RECEIVED BROADCAST", "Sometype of ALARM Broadcast received");
        PASpeak paspeak = new PASpeak();
        paspeak.sayit(context.getApplicationContext(),"ALARM ALARM ALARM");
        is_ready_to_speak = true;
    }

}



@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT);
    BroadcastReceiver mReceiver = new ScreenReceiver();
    registerReceiver(mReceiver, filter);

    PASpeak paspeak = new PASpeak();
    paspeak.sayit(getApplicationContext(),"process has started");

    Intent alarmIntent = new Intent(PAService.this, AlarmReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(PAService.this, 1, alarmIntent, 0);

    // Set the alarm to start at 5:00 AM
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 5);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);

    AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    manager.setRepeating(AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, // for repeating
            // in every 24
            // hours
            pendingIntent);

    return Service.START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("Not yet implemented");
}

}

manager.setRepeating(AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, // for repeating
            // in every 24
            // hours
            pendingIntent);

2nd parameter触发时间,如果calendar.getTimeInMillis()过去,则立即触发报警。所以发生的事情是你可能在晚上 7 点打开应用程序。您预计闹钟会在第二天早上 5 点响起,但是您的 calendar.getTimeInMillis() 当天早上 5 点。所以你需要为此添加一个检查:

Calendar calendar = Calendar.getInstance();
// calendar.setTimeInMillis(System.currentTimeMillis()); // YOU DON'T NEED THIS LINE
calendar.set(Calendar.HOUR_OF_DAY, 5);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);

Calendar current = Calendar.getInstance();

int curTime = current.getTimeInMillis();
int alarmTime = calendar.getTimeInMillis();

if (alarmTime >= curTime){
   manager.setRepeating(AlarmManager.RTC_WAKEUP,
        alarmTime, AlarmManager.INTERVAL_DAY, // for repeating
        // in every 24
        // hours
        pendingIntent);
}else{
   calendar.add(Calendar.DAY_OF_MONTH, 1);
   int alarmTime = calendar.getTimeInMillis();
   manager.setRepeating(AlarmManager.RTC_WAKEUP,
        alarmTime, AlarmManager.INTERVAL_DAY, // for repeating
        // in every 24
        // hours
        pendingIntent);
}