Android AlarmManager RTC_WAKEUP 不准确?
Android AlarmManager RTC_WAKEUP inprecise?
我正在尝试找到一种在特定时间执行某些代码的方法。为此,我目前正在尝试仅使用 Android 提供的内容:AlarmManger。当设置它被执行的时间时,但不完全是我设置时间的时间 -> 总是有一个延迟,当时间离当前更远时,延迟似乎更长。我该如何解决?当用户不在应用程序中但没有使用任务管理器关闭它时,代码运行很重要。
(抱歉格式化)
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
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);
}
}
MyService:
public class MyService extends Service {
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;
}
}
对 AlarmManager.set()
的调用不准确。这允许 Android 优化设备的电源使用。如果您需要准确交付,您需要使用 setExact()
或 setExactAndAllowWhileIdle()
。请参阅 documentation.
中的注释
我正在尝试找到一种在特定时间执行某些代码的方法。为此,我目前正在尝试仅使用 Android 提供的内容:AlarmManger。当设置它被执行的时间时,但不完全是我设置时间的时间 -> 总是有一个延迟,当时间离当前更远时,延迟似乎更长。我该如何解决?当用户不在应用程序中但没有使用任务管理器关闭它时,代码运行很重要。
(抱歉格式化)
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
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);
}
}
MyService:
public class MyService extends Service {
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;
}
}
对 AlarmManager.set()
的调用不准确。这允许 Android 优化设备的电源使用。如果您需要准确交付,您需要使用 setExact()
或 setExactAndAllowWhileIdle()
。请参阅 documentation.