I'm Making an app which has 5 different notifications at different times every day. it works perfectly but after beta testing some users are complaining that some alarm fire again at wrong times I haven't faced this problem before and I don't know how to trace the problem so I can fix it. This is how I create the alarm:
Manager Class:(which has all the functions of the alarm)
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");
}
- In my MainActivity I call Manager
restartPrayerService
function - In PrayerService I call as below:
Manager.initPrayerState(this);
Manager.initPrayerAlarm(this, PrayerReceiver.class);
and then register the receiver.
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);
}
Can some one please help me,exactly what am I doing wrong?
Manager.prayerAlarmManager.set
is not set exact on the specified time on api 19 and above. That is probably why "some" users complain.On api 19 and above you need
setExact
to schedule at a specific timeYou will need something like this: