Android AlarmManager RTC_WAKEUP неточно? - PullRequest
1 голос
/ 02 мая 2020

Я пытаюсь найти способ выполнить некоторый код в определенное время. Для этого я сейчас пытаюсь просто использовать то, что дает android: AlarmManger. При установке времени оно выполняется, но не совсем так, как когда я установил время -> Всегда есть задержка, которая кажется больше, когда время больше от текущего. Как я могу это исправить? И важно, чтобы коды запускались, когда пользователь не находится в приложении, но не закрывал его с помощью диспетчера задач.

(извините за форматирование; D)

MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {</p>

<pre><code>    private final String tag = "MainActivity";

    private TimePicker timePicker;
    private Button button;

    private boolean isRunning;
    private PendingIntent servicePI;
    private AlarmManager alarmManager;

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

    @Override
    public void onClick(View v) {
        if (isRunning) {
            Log.d(tag, "Stop service");

            alarmManager.cancel(servicePI);
            setState(false);
        }else {
            Log.d(tag, "Start service");

            int[] alarmTime = new int[2];
            if (Build.VERSION.SDK_INT < 23) {
                alarmTime[0] = timePicker.getCurrentHour();
                alarmTime[1] = timePicker.getCurrentMinute();
            }else {
                alarmTime[0] = timePicker.getHour();
                alarmTime[1] = timePicker.getMinute();
            }

            Calendar c = Calendar.getInstance();
            c.set(Calendar.HOUR_OF_DAY, alarmTime[0]);
            c.set(Calendar.MINUTE, alarmTime[1]);
            c.set(Calendar.SECOND, 0);

            alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), servicePI);
            setState(true);
        }
    }

    private void setState(boolean state) {
        isRunning = state;
        if (state)
            button.setText("Stop");
        else
            button.setText("Start");
    }

    private void init() {
        timePicker = findViewById(R.id.timePicker);
        button = findViewById(R.id.button_power);
        button.setOnClickListener(this);

        setState(false);

        Intent service = new Intent(getApplicationContext(), MyService.class);
        servicePI = PendingIntent.getService(getApplication(), 0, service,0);
        alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    }
}
</code>

</p> <p>MyService: public class MyService extends Service {</p> private final String tag = "MyService"; @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(tag, "Start"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { return null; } }

1 Ответ

0 голосов
/ 04 мая 2020

Звонки на AlarmManager.set() неточны. Это позволяет Android оптимизировать энергопотребление устройства. Если вам нужна точная доставка, вам нужно использовать setExact() или setExactAndAllowWhileIdle(). См. ПРИМЕЧАНИЕ в документации .

...