警报未在同一日期触发

时间:2018-05-29 06:22:29

标签: android alarmmanager

我想在特定时间重启设备,所以我正在使用报警管理器。下面是我活动的代码。

public class MainActivity extends AppCompatActivity {

    private static int timeHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
    private static int timeMinute = Calendar.getInstance().get(Calendar.MINUTE);
    AlarmManager alarmManager;
    private PendingIntent pendingIntent;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 11);
        calendar.set(Calendar.MINUTE, 02);
        alarmManager.cancel(pendingIntent);
//        if(Calendar.getInstance().after(calendar)){
//            // Move to tomorrow
//            calendar.add(Calendar.DATE, 1);
//        }
      alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, pendingIntent);

//
//        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
//                SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY,
//                AlarmManager.INTERVAL_DAY, pendingIntent);
    }
}

这是我的接收器

 public class AlarmReceiver extends BroadcastReceiver {

    public static void rebootDevice() {
        try {
            Process process = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(process.getOutputStream());
            os.writeBytes("reboot \n");
        } catch (Throwable t) {

            t.printStackTrace();
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        Toast.makeText(context, "Triggered", Toast.LENGTH_SHORT).show();
        Log.d("Gajanand", "onReceive: Triggered");

        rebootDevice();

    }
}

是的代码工作正常,但没有在确切的日期。例如,如果我现在运行相同的代码。如果我更改触发日期,则不会触发警报。我没有得到代码的问题,触发报警有10秒的延迟。任何帮助

2 个答案:

答案 0 :(得分:2)

您的代码存在两个问题:

  • Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 11);
    calendar.set(Calendar.MINUTE, 02);
    

    您要设置HOUR_OF_DAYMINUTE,但SECOND字段仍有初始值,因此警报不会在分钟时触发 (除非你在一分钟内完全调用calendar.setTimeInMillis(System.currentTimeMillis()),这是不太可能的。)

    应该是这样的:

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 11);
    calendar.set(Calendar.MINUTE, 2);
    calendar.set(Calendar.SECOND, 0); // setting seconds to 0
    
  • setRepeating()不准确且无法与Doze合作。

    对于确切的触发时间,您应该使用确切的警报,请查看this答案。

答案 1 :(得分:1)

这是来自文档

  

       注意:从API 19开始,所有重复警报都不准确。如果你的        应用程序需要精确的交付时间,然后必须使用一次性        确切的警报,每次重新安排,如上所述。遗留应用程序       其{@code targetSdkVersion}早于API 19将继续拥有所有        他们的警报,包括重复警报,被视为准确。

重复警报总是不准确,因此它们不会消耗太多电池。它们可能比预期时间晚一点开火。如果您希望闹钟准确无误,请不要重复。收到警报后再次设置