我只是很难理解AlarmManager系统,与未来的通知等相关。我似乎无法让AlarmManager以正确的频率设置闹钟。
我也不确定我应该在哪里制作闹钟,以及哪种类型最适合我的需要。
更新基于偏好设置,详情如下。
启动我的应用程序时,会在创建FragmentActivity时调用该服务。在onCreate()中,我有以下内容:
Intent mServiceIntent = new Intent(this, ServiceUpdater.class);
if(startService(mServiceIntent)==null)
startService(mServiceIntent);
发生了很多其他的事情并且显示了片段等,但这主要是为了确保服务正在运行。注意,我也将它设置为在系统启动时调用BroadcastReceiver。
public class ServiceUpdater extends IntentService{
private SharedPreferences defaultPrefs;
private SharedPreferences userPrefs;
private SharedPreferences.Editor editor;
// Alarm Service
private AlarmManager alarmManager;
private PendingIntent alarmIntent;
public ServiceUpdater() {
super("MyService");
}
@Override
protected void onHandleIntent(Intent intent) {
defaultPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
userPrefs = getSharedPreferences("user", Context.MODE_PRIVATE);
long updateFrequency = (Long.parseLong(defaultPrefs.getString("updateFrequencyPref", "24")))*1000*60*60;
// in hours = 1000*60*60*'24'
long thirtySecondsAfterWake = SystemClock.elapsedRealtime() + 30*1000; // 30 seconds after the device boots
Intent intent1 = new Intent(this, UpdateReceiver.class);
alarmIntent = PendingIntent.getBroadcast(this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, thirtySecondsAfterWake, updateFrequency, alarmIntent);
if(defaultPrefs.getBoolean("updatePref", true))
new Update().execute();
}
private class Update extends AsyncTask<Void, Void, Integer>{
private int newNumber;
@Override
protected Integer doInBackground(Void... params) {
newNumber= new HttpServices().getNewNumber();
return newNumber;
}
@Override
protected void onPostExecute(Integer noJobs){
if(newNumber > 0){ //userPrefs.getInt("oldNumber", 0)){
editor = userPrefs.edit();
editor.putInt("oldNumber", newNumber);
editor.commit();
if(!FragActivity.active)
new MyNotif(getApplicationContext(), "NewData");
}
}
} // end Async
} // end service class
public class UpdateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent updater = new Intent(context, ServiceUpdater.class);
context.startService(updater);
}
}
我的猜测是当闹钟呼叫接收器时,它会创建一个新的闹钟,然后更新旧闹钟,将下一个更新时间设置为30秒;这解释了为什么HTTP请求正在发生(我每30秒左右收到一次通知。
即使应用程序未运行,我也希望确保警报运行。
我的目标是执行以下操作。
我在哪里正确设置闹钟,以便每次服务都不会重新创建 - 但即使应用程序没有运行也能正确运行?
感谢您提前提供任何帮助。
答案 0 :(得分:1)
但这主要是为了确保服务正在运行
我不知道你为什么要两次启动这项服务。
ServiceUpdater.class
我不知道你为什么在AsyncTask
内使用IntentService
。这在几个层面都很糟糕。 onHandleIntent()
已在后台线程上调用,我希望您的应用在尝试在后台线程上创建AsyncTask
时会崩溃。只需将所有后台逻辑移动到onHandleIntent()
(或onHandleIntent()
调用的方法)。
我的猜测是当闹钟呼叫接收器时,它会创建一个新的闹钟,然后更新旧闹钟,将下一个更新时间设置为30秒;这解释了为什么HTTP请求正在发生(我每30秒左右收到一次通知。
我不知道你为什么要在每次跑步中设置重复闹钟。
我在哪里正确设置警报,以便每次服务时都不会重新创建 - 但即使应用程序未运行也能正确运行?
您需要执行设置AlarmManager
计划的代码:
首次运行你的应用程序(因为你还没有机会设置闹钟)
用户强制停止您的应用程序设置(因为您之前安排的警报已被清除)
重新启动后(因为您之前安排的警报被清除)
处理前两个问题的典型模式是跟踪上次运行警报代码的时间,例如SharedPreference
。然后,在自定义Application
或应用的可能入口点(例如,启动器活动)中,检查上次警报运行时间的SharedPreference
值:
如果没有值,则表示这是您应用的首次运行,因此您可以安排闹钟
如果有值,并且它显着长于您的轮询周期,则表示您的应用已强制停止,因此您安排了警报
否则,有一个合理的值,所以你假设你的闹钟工作正常
处理重启方案是为了响应AlarmManager
广播而运行ACTION_BOOT_COMPLETED
调度逻辑。
请注意,您使用的是ELAPSED_REALTIME
,这意味着如果设备处于睡眠模式,闹钟将会延迟。
另请注意,您正在使用setInexactRepeating()
,这意味着闹钟将在轮询期间的某个时间关闭,但不会以精确的间隔关闭。