-1

I want to reboot device on particular time so i am using alarm manager for that.below is the code of my activity.

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);
    }
}

and this is my receiver

 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();

    }
}

Yes code is working fine but not on the exact date.for example if i run the same code now. alarm not triggers if i change the date it triggers. i am not getting what is the problem with code and there is 10 seconds delay in triggering alarm. any help

Gowthaman M
  • 8,057
  • 8
  • 35
  • 54
Gaju Kollur
  • 2,046
  • 5
  • 23
  • 47
  • did you check it ? - https://stackoverflow.com/questions/41197416/alarmmanager-not-working-after-phone-reboot – Adil May 29 '18 at 06:27
  • @AD10 that is not my problem i have another issue – Gaju Kollur May 29 '18 at 06:28
  • Possible duplicate of [Android AlarmManager not working on some devices when the app is closed](https://stackoverflow.com/questions/39739669/android-alarmmanager-not-working-on-some-devices-when-the-app-is-closed) – Gowthaman M May 29 '18 at 06:35

2 Answers2

2

There are two problems with your code:

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

    Here you're setting HOUR_OF_DAY and MINUTE but the SECOND field still has its initial value, so the alarm won't be triggered exactly on the minute (unless you called calendar.setTimeInMillis(System.currentTimeMillis()) exactly on the minute, which is quite unlikely).

    Should be something like this:

    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() is inexact and doesn't work with Doze.

    For exact trigger times you should use exact alarms, check this answer for an example.

earthw0rmjim
  • 19,027
  • 9
  • 49
  • 63
1

This is from the documentation

Note: 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 {@code targetSdkVersion} is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.

Repeating alarms are always inexact so that they wont consume much battery. They may be fired a bit later than the expected time. If you want your alarm to exact, don't make it repeating. Set it again once you receive the alarm

Suhaib Roomy
  • 2,501
  • 1
  • 16
  • 22