Android 报警时间过长,无法触发

Android 报警时间过长,无法触发,android,android-alarms,Android,Android Alarms,我有一个工作正常的闹钟,除了一个方面:我为闹钟设置的触发时间并不总是它触发的时间 我想了一会儿,也许警报是在几秒钟内发出的,而不是几毫秒。在重新阅读文档之后,这个想法被驳回了 在我进一步解释之前,我现在将发布重要的代码: BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) {

我有一个工作正常的闹钟,除了一个方面:我为闹钟设置的触发时间并不总是它触发的时间

我想了一会儿,也许警报是在几秒钟内发出的,而不是几毫秒。在重新阅读文档之后,这个想法被驳回了

在我进一步解释之前,我现在将发布重要的代码:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        startAlarm(findViewById(R.id.reset));
        Log.d("test", "reseting");
    }
};

public void startAlarm(View view) {
    //setup
    EditText nameInput = (EditText) this.findViewById(R.id.nameInput);
    EditText firstAlertInput = (EditText) this.findViewById(R.id.firstAlertInput);
    EditText intervalInput = (EditText) this.findViewById(R.id.intervalInput);
    EditText descriptionInput = (EditText) this.findViewById(R.id.descriptionInput);
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = sp.edit();
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

    //Need to parse and format the offset now, before intent is created, then attach it to the intent.
    //HERE I NEED TO GET THE OFFSET AND CONVERT INTO MILLISECONDS
    EditText hoursInput = (EditText) this.findViewById(R.id.hoursInput);
    EditText minutesInput = (EditText) this.findViewById(R.id.minutesInput);
    EditText secondsInput = (EditText) this.findViewById(R.id.secondsInput);
    int hours = 0;
    int minutes = 0;
    int seconds = 0;
    try {
        hours = Integer.parseInt(hoursInput.getText().toString()) * 3600000;
        minutes = Integer.parseInt(minutesInput.getText().toString()) * 60000;
        seconds = Integer.parseInt(secondsInput.getText().toString()) * 1000;
    } catch(NumberFormatException e) {

    }
    int offsetMillis = hours + minutes + seconds;
    //HERE: Randomly Generate the offset, add or subtract it when alarm is set. Make sure to attach the opposite to the PI so that the next alarm will trigger at te correct default time
    int offsetRandomMillis = 0;

    if(offsetMillis != 0){
        Random offsetRandom = new Random();
        int oneOrNegativeOne = (offsetRandom.nextBoolean()) ? 1 : -1;
        offsetRandomMillis = offsetRandom.nextInt(offsetMillis) * oneOrNegativeOne;
    }

    //Creates new offset alarm structure
    Intent intent = new Intent(this, AlarmReciever.class);
    intent.putExtra("name", nameInput.getText().toString());
    intent.putExtra("description", descriptionInput.getText().toString());
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    //Creates new recursion alarm structure
    Intent intent2 = new Intent("RESET_ALARM");
    PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this.getApplicationContext(), 000, intent2, PendingIntent.FLAG_UPDATE_CURRENT);


    //Stores old offset alarm details
    editor.putString("oldName", nameInput.getText().toString());
    editor.putString("oldDescription", descriptionInput.getText().toString());
    editor.apply();

    //Finishes new offset alarm details
    int[] times = parseTime(firstAlertInput.getText().toString());
    times[0] = times[0] * 3600000;
    times[1] = times[1] * 60000;
    long millis = times[0] + times[1];
    int[] intervalTimes = parseTime(intervalInput.getText().toString());
    intervalTimes[0] = intervalTimes[0] * 3600000;
    intervalTimes[1] = intervalTimes[1] * 60000;
    long intervalMillis = intervalTimes[0] + intervalTimes[1];

    //New offset alarm set
    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + millis + intervalMillis + offsetRandomMillis, pendingIntent);
    //New Recursion alarm set
    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + millis + intervalMillis, pendingIntent2);

    Log.d("test", "OFFSET: " + String.valueOf((System.currentTimeMillis() + millis + intervalMillis + offsetRandomMillis) / 1000));
    Log.d("test", "NOOFFSET: " + String.valueOf((System.currentTimeMillis() + millis + intervalMillis) / 1000));
}

private int[] parseTime(String input){
    int[] times = new int[2];
    String[] split = input.split(":");
    for(int i = 0; i < times.length; i++){
        times[i] = Integer.parseInt(split[i]);
    }
    return times;
}
BroadcastReceiver=new BroadcastReceiver(){
@凌驾
公共void onReceive(上下文、意图){
startAlarm(findViewById(R.id.reset));
日志d(“测试”、“重置”);
}
};
公共void startAlarm(视图){
//设置
EditText nameInput=(EditText)this.findViewById(R.id.nameInput);
EditText firstAlertInput=(EditText)this.findViewById(R.id.firstAlertInput);
EditText intervalInput=(EditText)this.findViewById(R.id.intervalInput);
EditText descriptionInput=(EditText)this.findViewById(R.id.descriptionInput);
SharedReferences sp=PreferenceManager.GetDefaultSharedReferences(此);
SharedReferences.Editor=sp.edit();
AlarmManager AlarmManager=(AlarmManager)getSystemService(报警服务);
//在创建意图之前,现在需要解析和格式化偏移量,然后将其附加到意图。
//这里我需要得到偏移量并转换成毫秒
EditText hoursInput=(EditText)this.findViewById(R.id.hoursInput);
EditText minutesInput=(EditText)this.findViewById(R.id.minutesInput);
EditText secondsInput=(EditText)this.findViewById(R.id.secondsInput);
整小时=0;
整数分钟=0;
整数秒=0;
试一试{
小时=整数.parseInt(hourInput.getText().toString())*3600000;
分钟数=整数.parseInt(minutesInput.getText().toString())*60000;
秒=Integer.parseInt(secondsInput.getText().toString())*1000;
}捕获(数字格式){
}
int offsetMillis=小时+分钟+秒;
//此处:随机生成偏移量,在设置报警时加或减。确保将相反的偏移量附加到PI,以便在正确的默认时间触发下一个报警
int offsetRandomMillis=0;
如果(偏移毫秒!=0){
Random offsetRandom=新的Random();
int-oneOrNegativeOne=(offsetRandom.nextBoolean())?1:-1;
offsetRandomMillis=offsetRandom.nextInt(offsetMillis)*一个或负一个;
}
//创建新的偏移报警结构
意向意向=新意向(此为AlarmReceiver.class);
intent.putExtra(“name”,nameInput.getText().toString());
intent.putExtra(“description”,descriptionInput.getText().toString());
PendingEvent PendingEvent=PendingEvent.getBroadcast(this.getApplicationContext(),2343243,intent,PendingEvent.FLAG_UPDATE_CURRENT);
//创建新的递归报警结构
意图2=新意图(“重置报警”);
PendingEvent PendingEvent2=PendingEvent.getBroadcast(this.getApplicationContext(),000,intent2,PendingEvent.FLAG_UPDATE_CURRENT);
//存储旧的偏移报警详细信息
putString(“oldName”,nameInput.getText().toString());
putString(“oldscription”,descriptionInput.getText().toString());
editor.apply();
//完成新的偏移报警详细信息
int[]times=parseTime(firstAlertInput.getText().toString());
次数[0]=次数[0]*3600000;
次[1]=次[1]*60000;
长毫秒=次[0]+次[1];
int[]intervalTimes=parseTime(intervalInput.getText().toString());
间隔时间[0]=间隔时间[0]*3600000;
间隔时间[1]=间隔时间[1]*60000;
长间隔毫秒=间隔时间[0]+间隔时间[1];
//新的偏移报警装置
alarmManager.set(alarmManager.RTC_唤醒,系统.currentTimeMillis()+millis+间隔millis+OffsetRandomillis,挂起内容);
//新的递归报警集
alarmManager.set(alarmManager.RTC_唤醒,系统.currentTimeMillis()+毫秒+间隔毫秒,PendingEnt2);
Log.d(“测试”,“偏移量:”+String.valueOf((System.currentTimeMillis()+millis+intervalMillis+offsetRandomMillis)/1000));
Log.d(“test”,“NOOFFSET:”+String.valueOf((System.currentTimeMillis()+millis+intervalMillis)/1000));
}
私有int[]解析时间(字符串输入){
int[]次=新int[2];
String[]split=input.split(“:”);
for(int i=0;i
注意:它们都在同一个类中,我排除了同一个类中不相关的部分

现在发生的是:在我清除所有警报并设置新警报后,这些警报会在正确的时间触发。当broadcastReceiver设置新警报时,这些警报会延迟5-20秒触发。它设置的所有后续警报也会延迟触发,但触发时间比之前的警报晚5-20秒。正如您所看到的,警报最终触发的次数远远少于正常情况下的触发次数

另外,请注意,此实验的测试间隔值为1分钟,这意味着每个警报应在设置后1分钟触发。我知道也有确定和解析偏移量的代码,但我没有为此设置值,所以它不会影响时间。我在许多其他值中打印了这个值,所以我知道这是可行的

我很沮丧,因为我看不出失败的原因。我发布的代码中当前的log.d语句只是为了显示何时设置了一个新警报以及两个警报应该关闭的时间(一个警报应该触发一个通知,这个警报添加了偏移量。另一个警报在没有偏移量的情况下触发并设置新警报。如果我把您弄糊涂了,很抱歉)。这些值是正确的,因此这不是问题

我现在的怀疑来自我做的另一个实验。我不停地点击第一个运行startAlarm的按钮