我试图编写一段代码,每天必须唤醒几次并通知服务器。我试图使用警报意图和广播接收器,但接收器正在无限快速触发,我似乎无法阻止它。
我的所有代码都在一个文件中。流程很简单。 在启动时唤醒,检查我们是否应该通信,尝试通信其他设置两个等待条件之一,激活警报。 唤醒警报,尝试通信,必要时重新激活警报,否则将其杀死。
当我在我的设备上构建和部署此apk时,会发生以下流程:
重启
接收器接收启动意图就好了
警报得到预定
警报意图在80秒后按预期触发
然后在接下来的80秒后,
然后log-cat显示广播接收器被非常快速地触发。
每秒几次好像被垃圾邮件一样。
我完全不知道为什么它的表现如此
private PendingIntent pendingIntent;
/**
* Receive a signal, in our case, the device has booted up
* @param context The Context in which the receiver is running.
* @param intent The Intent being received.
*/
@SuppressLint("UnsafeProtectedBroadcastReceiver")
@Override
public void onReceive(Context context, Intent intent) {
Log.d("autostart", "broadcast received");
if(intent.getAction()==null)return;
Intent alarmIntent = new Intent(context, autostart.class);
alarmIntent.setAction("device.activation.alarm");
pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);//cancel flag seems to be ignored
cancel(context);//cancel command seems to be ignored
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
// Set the alarm here.
Log.d("autostart","We have booted");
RegisterActivation registerActivation = new RegisterActivation(context);
if(registerActivation.AlreadyActivated())
return;//no need
if(registerActivation.ActivationPending()){
//perform regular activation
return;
}
if(registerActivation.canComplete()){
boolean success = registerActivation.sendActivation();//talk to server
if(success) {
registerActivation.markCompleted();
cancel(context);
}
else {
registerActivation.markFileWaiting();
startPending(context);
}
return;
}
if(registerActivation.shouldWait()){//if can complete fails, then shouldWait will immediately return true
Log.d("autostart", "waiting");
registerActivation.markFileSimWait();
startWait(context);
return;
}
}
if(intent.getAction().equals("device.activation.alarm")){
Log.d("autostart","alarm triggered");
cancel(context);
RegisterActivation registerActivation = new RegisterActivation(context);
if(registerActivation.AlreadyActivated()){//for now always false
cancel(context);
return;
}
if(registerActivation.ActivationPending()){//for now always false
//same as before
return;
}
if(registerActivation.canComplete()){//glitch happens here
if(registerActivation.sendActivation()){
registerActivation.markCompleted();
cancel(context);
}else{
registerActivation.markFileWaiting();
startPending(context);//this immediatly triggers the broadcast recieve
}
return;
}
if(registerActivation.shouldWait()){
registerActivation.markFileSimWait();
startWait(context);
}
}
}
public void startPending(Context context) {
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
int interval = 80000;//will later become 4 hours
manager.set(AlarmManager.RTC_WAKEUP,interval,pendingIntent);
Log.d("autostart", "alarm activated");
}
public void startWait(Context context) {//same function but different time interval
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
int interval = 90000;// will later become 12 hours
manager.set(AlarmManager.RTC_WAKEUP, interval, pendingIntent);
}
public void cancel(Context context) {
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
manager.cancel(pendingIntent);
}
答案 0 :(得分:0)
谢谢Mike M. https://stackoverflow.com/users/2850651/mike-m
我会将您的评论标记为答案,但您只是评论
我从
开始manager.set(AlarmManager.RTC_WAKEUP,interval,pendingIntent);
为:
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+interval, interval, pendingIntent);
我必须将间隔添加到intervalMillis参数中 经过测试,manager.set(...)函数实际上并没有像我想要的那样做得很好,所以我只需要在开始时触发取消。
再次感谢迈克:)