报警管理器有时会在错误的时间点火

时间:2015-06-14 21:46:24

标签: java android service broadcastreceiver alarmmanager

我制作的应用每天在不同时间发出5种不同的通知。它运行得很完美,但经过beta测试后,一些用户抱怨说有些警报在错误的时间再次发出警报我以前还没有遇到过这个问题而且我不知道如何追踪问题所以我可以解决它。这就是我创建闹钟的方法:

经理类:(具有警报的所有功能)

public static Integer DEFAULT_SILENT_DURATION = 20 * 60 * 1000;
    public static Integer DEFAULT_SILENT_START= 2 * 60 * 1000;

    public Manager(Context applicationContext) {

        this.context = applicationContext;
    }

    public static void acquireScreen(Context context) {
        PowerManager pm = (PowerManager) context.getApplicationContext()
                .getSystemService(Context.POWER_SERVICE);
        WakeLock wakeLock = pm
                .newWakeLock(
                        (PowerManager.SCREEN_BRIGHT_WAKE_LOCK
                                | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP),
                        "TAG");
        wakeLock.acquire();
        Log.v("Check Manager acquireScreen","YES");
    }

    public static void releaseScreen(Context context) {
        KeyguardManager keyguardManager = (KeyguardManager) context
                .getApplicationContext().getSystemService(
                        Context.KEYGUARD_SERVICE);
        KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
        keyguardLock.disableKeyguard();
        Log.v("Check Manager releaseScreen","YES");
    }

    public static void initPrayerAlarm(Service service,
            Class<PrayerReceiver> receiver) {

        Manager.prayerService = service; // we may need it ?
        Manager.prayerIntet = new Intent(service, receiver);
        Manager.prayerPendingIntent = PendingIntent
                .getBroadcast(service, 1234432, Manager.prayerIntet,
                        PendingIntent.FLAG_UPDATE_CURRENT);
        Manager.prayerAlarmManager = (AlarmManager) service
                .getSystemService(Context.ALARM_SERVICE);
        Manager.prayerAlarmManager.set(AlarmManager.RTC_WAKEUP,
                System.currentTimeMillis() + 1000, Manager.prayerPendingIntent);
        Log.v("Check Manager initPrayerAlarm",""+System.currentTimeMillis() + 1000);
    }

    public static void updatePrayerAlarm(long newTimeInterval) {

        Manager.prayerAlarmManager.set(AlarmManager.RTC_WAKEUP,
                System.currentTimeMillis() + newTimeInterval,
                Manager.prayerPendingIntent);
        Log.v("Check Manager updatePrayerAlarm",""+System.currentTimeMillis() + newTimeInterval);
    }

public void restartPrayerService(Activity activty) {

        Intent intent = new Intent(activty, PrayerService.class);
        context.startService(intent);
        Log.v("Check Manager restartPrayerService","YES");
    }
  • 在我的 MainActivity 中,我致电经理 restartPrayerService 功能
  • PrayerService 中,我打电话如下:

Manager.initPrayerState(this); Manager.initPrayerAlarm(this, PrayerReceiver.class);

然后注册接收器。

PrayerReceiver:

public class PrayerReceiver extends BroadcastReceiver {

static PrayerState prayerState;
private AudioManager am;
private Context context;
private SharedPreferences pref;
private Editor editor;
private int silentDuration;
private int silentStart ;
private int delayMilliSeconds = 1000 * 60;  // one minute by default.
private Object obj;


@Override
public void onReceive(Context context, Intent intent) {
        this.context = context;
        pref = PreferenceManager.getDefaultSharedPreferences(this.context);

    Manager m = new Manager(context);
    Preference p = m.getPreference();
    this.silentDuration = p.getSilentDuration();
    this.silentStart = p.getSilentStart();
    editor = pref.edit();
    try {

        prayerState = Manager.getPrayerState();
        am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        switch (prayerState.getCurrentState()) {

        case PrayerState.WAITING_AZAN:
            {
                Log.v("Check PrayerReceiver PrayerState","WAITING_AZAN");
                onWaitingAzan();

            }

            break;
        case PrayerState.DOING_AZAN:
            { 
                Log.v("Check PrayerReceiver PrayerState","DOING_AZAN");
                onDoingAzan();
            }
            break;

        case PrayerState.WAITING_PRAYER:
            {
                Log.v("Check PrayerReceiver PrayerState","WAITING_PRAYER");
                onWaitingPrayer();
            }

            break;

        }

    } catch (Exception e) {
        // TODO Auto-generated catch block

        Log.v("Check PrayerReceiver PrayerState","ERROR");
      }

    }


    public int getDelayMilliSeconds() {

        return delayMilliSeconds;
    }

    public void setDelayMilliSeconds(int delayMilliSeconds) {
          this.delayMilliSeconds = delayMilliSeconds;
    }

    private void onWaitingAzan() {
     try {


        boolean isRingerModeChangedToSilent = pref.getBoolean(
                "isRingerModeChangedToSilent", false);
        if (isRingerModeChangedToSilent == true) {
            am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
            editor.putBoolean("isRingerModeChangedToSilent", false);
            editor.commit();
        }

        // What is the remaining time until the next prayer ?
        Date date = new Date();
        int dd = date.getDate();
        int mm = date.getMonth() + 1;
        int yy = date.getYear() + 1900;
        int h = date.getHours();
        int m = date.getMinutes();
        int s = date.getSeconds();
        int nearestPrayerTime = Manager.computeNearestPrayerTime(context,
                h, m, s, yy, mm, dd);
        int deffTime = TimeHelper.different((h * 3600 + m * 60 + s),
                nearestPrayerTime);
        deffTime = deffTime * 1000; // to milliseconds

        // ok , come back after X seconds to do the Azan
        prayerState.setNextState(PrayerState.DOING_AZAN);

        Manager.updatePrayerAlarm(deffTime);


    } catch (Exception e) {

        Log.v("Check PrayerReceiver onWaitingAzan","ERROR");
      }
    }

    private void onDoingAzan() {

    prayerState.setNextState(PrayerState.WAITING_PRAYER);
    int delay = this.silentStart;
    if(delay < 2000*60)
        delay =2000*60; // two minutes  - at lease  
    Log.v("Check PrayerReceiver onDoingAzan","delay "+delay);
    Manager.playAzanNotification(context);

    Manager.updatePrayerAlarm(delay);



    }

    private void onWaitingPrayer() {

    Manager manager = new Manager(this.context);
    Preference preference = manager.getPreference();
    AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    if(am.getRingerMode() == AudioManager.RINGER_MODE_NORMAL && preference.isAutoSilentDisabled()==false ){
        am.setRingerMode(AudioManager.RINGER_MODE_SILENT);
        editor.putBoolean("isRingerModeChangedToSilent", true);
        editor.commit();
    }

    this.delayMilliSeconds = silentDuration;
    prayerState.setNextState(PrayerState.WAITING_AZAN);

    Manager.updatePrayerAlarm(delayMilliSeconds);

    }

有人可以帮助我,我到底做错了什么?

1 个答案:

答案 0 :(得分:3)

在api 19及更高版本的指定时间内未设置

Manager.prayerAlarmManager.set。这可能是为什么&#34;一些&#34;用户抱怨。

  

注意:从API 19(KITKAT)开始,警报传递不准确:操作系统将移动警报以最小化唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参阅setWindow(int,long,long,PendingIntent)和setExact(int,long,PendingIntent)。 targetSdkVersion早于API 19的应用程序将继续查看之前的行为,其中所有警报都在请求时准确传递。

在api 19及以上,您需要setExact在特定时间安排

你需要这样的东西:

if(android.os.Build.VERSION.SDK_INT >= 19) {
// setExact
}
else {
    //set
}