Android AlarmManager在某些设备中未调用BroadcastReceiver

时间:2016-12-02 17:14:31

标签: android alarm

我正在使用AlarmManager创建警报,以便在几天内准确发出警报,但由于某些原因,在某些设备中,它在第一天之后无法正常工作。

以下方法用于向AlamManager添加每日警报,其中在开始日期和结束日期之间每天添加一个警报:

public void setDailyALarm(GCMReminderModel reminder) {
    Intent alarmIntent = manageAlarmIntent(reminder);

    Calendar startDate = getStartDateValid(reminder);
    Calendar endDate = getEndDateValid(reminder);

    //Alarm start like a date start from gcm
    Calendar alarm = (Calendar) startDate.clone();

    do {
        for(Hour hour : reminder.getHours()) {
            String hourString = hour.getByDayOfWeek(alarm.get(Calendar.DAY_OF_WEEK));

            if(hourString.isEmpty()) {
                continue;
            } else {
                final String[] hourArray = hourString.split(":");
                final int hourOfDay = Integer.parseInt(hourArray[0]);
                final int minuteOfDay = Integer.parseInt(hourArray[1]);

                alarm.set(Calendar.HOUR_OF_DAY, hourOfDay);
                alarm.set(Calendar.MINUTE, minuteOfDay);
            }

            if ((getMidnightDate().before(alarm) && endDate.after(alarm)) &&
                    reminder.getSendDate().before(alarm.getTime())) {
                LogHelper.logEvent("SCHEDULE ALARM");
                scheduledAlarm(context, alarmIntent, alarm, reminder);
            }
        }

        LogHelper.logEvent("ALARM AFTER - " + alarm.getTime().toString());

        alarm.add(Calendar.DAY_OF_MONTH, 1);

        //Percorre pela semana agendando os alarmes enquanto a data do alarme for menor que a data de fim
    } while (endDate.after(alarm));
}

public void scheduledAlarm(Context context, Intent intent, Calendar alarmHour, GCMReminderModel reminder) {

    Realm realm = Realm.getDefaultInstance();
    realm.beginTransaction();

    long primaryKeyValue = 0;
    if (realm.where(NotificationModel.class).findAll().size() > 0) {
        primaryKeyValue = (realm.where(NotificationModel.class).max(Constants.NOTIFICATION_IDENTIFIER).longValue() + 1);
    }

    NotificationModel notification = realm.createObject(NotificationModel.class);
    notification.setIdentifier(primaryKeyValue);

    switch (reminder.getMessageType()) {
        case Constants.MESSAGE:
            notification.setIdMessage(reminder.getIdReminder());
            break;
        case Constants.QUESTION:
            notification.setIdQuestion(reminder.getIdReminder());
            break;
        case Constants.QUESTIONLEVEL:
            notification.setIdQuestionLevel(reminder.getIdReminder());
            break;
        case Constants.QUESTIONALTERNATIVE:
            notification.setIdQuestionAlternative(reminder.getIdReminder());
            break;
    }

    notification.setTimeMillis(alarmHour.getTimeInMillis());
    notification.setIdType(reminder.getMessageType());

    realm.commitTransaction();

    intent.putExtra(Constants.NOTIFICATION_IDENTIFIER, notification.getIdentifier());

    addNewAlarm(context, alarmHour.getTimeInMillis(), notification, intent);

    LogHelper.logEvent("---------------------------------------------------------------------------------------------");
    LogHelper.logEvent("ALARM SCHEDULED FOR : " + alarmHour.getTime() + " (NOW IS = " + new Date() + ")" + " - ID: " + notification.getIdentifier().intValue());
    LogHelper.logEvent("---------------------------------------------------------------------------------------------");
}

public void addNewAlarm(Context context, long timeInMills, NotificationModel notification, Intent intent) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).
                setExactAndAllowWhileIdle(
                        AlarmManager.RTC_WAKEUP,
                        timeInMills,
                        PendingIntent.getBroadcast(context,
                                notification.getIdentifier().intValue(),
                                intent,
                                PendingIntent.FLAG_UPDATE_CURRENT)
        );

        LogHelper.logEvent("ENTROU NO SET_EXACT_AND_ALLOW_WHILE_IDLE");
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE))
                .setExact(
                        AlarmManager.RTC_WAKEUP,
                        timeInMills,
                        PendingIntent.getBroadcast(context,
                                notification.getIdentifier().intValue(),
                                intent,
                                PendingIntent.FLAG_UPDATE_CURRENT)
                );
    } else {
        ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE))
                .set(AlarmManager.RTC_WAKEUP,
                        timeInMills,
                        PendingIntent.getBroadcast(context,
                                notification.getIdentifier().intValue(),
                                intent,
                                PendingIntent.FLAG_UPDATE_CURRENT)
                );
    }
}

检查转储日志,可以看到警报已添加到AlarmManager

RTC_WAKEUP #3: Alarm{42043900 type 0 <package>} 
type=0 when=+20h25m42s217ms repeatInterval=0 count=0
operation=PendingIntent{41b48800: PendingIntentRecord{420437a0 <package> broadcastIntent}}

在某些设备中,与Android 6.0的Moto G2一样,只调用第一天设置的闹钟,而在其他设备中,如Xiomi Redmi PRO和Android 6.0,所有闹钟都被正确调用。起初我认为这可能是因为权限,考虑到Android Marshmallow对待它的方式,但在其他设备上使用Android M正在工作(如Redmi PRO)。

有没有人有可能造成这种情况的想法?我检查了Developers页面,所有必需的配置和类都是有序的。

0 个答案:

没有答案