0

I have this problem with inconsistency of launching alarms while device is in sleep mode (well documented problem), that is driving me crazy.

In my app for frequent reminders i use alarmmanager to set time for next reminder, when the previous one occurs. In most cases app runs fine, but in sleep mode on my ASUS TF300t (API 17), the alarms goes bonkers.

Code for registering alarm:

            Intent i = new Intent(mContext, OnAlarmReceiver.class);
        i.putExtra(RReminder.PERIOD_TYPE, type);
        i.putExtra(RReminder.EXTEND_COUNT, extendCount);
        i.setAction(RReminder.CUSTOM_INTENT_ALARM_PERIOD_END);
        pi = PendingIntent.getBroadcast(mContext, (int)when, i, PendingIntent.FLAG_ONE_SHOT);

        if(buildNumber >= Build.VERSION_CODES.LOLLIPOP){
            AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(when, pi);
            mAlarmManager.setAlarmClock(alarmClockInfo,pi);
        } else if(buildNumber >= Build.VERSION_CODES.KITKAT){
            mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, when, pi);
        } else {
            mAlarmManager.set(AlarmManager.RTC_WAKEUP, when, pi);
        }

And my WakefulBroadcastReceiver class:

public class OnAlarmReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent){
    int type = intent.getExtras().getInt(RReminder.PERIOD_TYPE);
    int extendCount = intent.getExtras().getInt(RReminder.EXTEND_COUNT);
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    Log.d("period type",""+type);
    Log.d("time",sdf.format(Calendar.getInstance().getTime()));
    Intent i = new Intent(context, PeriodService.class);
    i.putExtra(RReminder.PERIOD_TYPE, type);
    i.putExtra(RReminder.EXTEND_COUNT, extendCount);
    startWakefulService(context,i);

}

}

First thing i am observing is the alarm-batching, when an alarm isn't launched when it was supposed, but instead it launches when the next alarm is due together with the second one.

Other thing is, when an alarm does not launch on time in sleep mode, it goes off right after i wake up the device with power button.

I am aware of the changes of alarm behaviour in API 19 and 23 (doze mode). I solved the inexact issues with newer API's observed in emulated virtual devices with setExact().

I have two physical android devices, this TF300t tablet and Galaxy S3 phone. And while with S3 this problem is occurs very rarely, the consistency of problems on TF300t basically makes my app useless.

So my question would be, are my described problems present on many devices across all API's (which would require me to look for entireally different solution), or are they device or API specific and can be dealt as exception?

aphelion
  • 561
  • 1
  • 5
  • 12

1 Answers1

0

Use PowerManger to solve this:

Define in Service:

PowerManager powerManager;
PowerManager.WakeLock wakeLock;

Now in Service class, In Oncreate Metod add this:

powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NAME");

In startCommnd method, add this before starting your Work:

wakeLock.acquire();

Add this in your Service class:

@Override
    public void onDestroy() {
        wakeLock.release();
        this.isRun=false;
    }

Finally, add in Manifest file:

<uses-permission android:name="android.permission.WAKE_LOCK"/>
Divyesh Patel
  • 2,576
  • 2
  • 15
  • 30
  • WakefulBroadcastReceiver has the aquisition of wake lock implemented. [WakefulBroadcastReceiver](https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html) – aphelion Oct 27 '16 at 14:17
  • that is for BroadcastReceiver. You start service from that broadcast, so your service need wake log to perform task successfully. – Divyesh Patel Oct 27 '16 at 14:19
  • from the linki posted in prevous comment: "Helper for the common pattern of implementing a BroadcastReceiver that receives a device wakeup event and then passes the work off to a Service, while ensuring that the device does not go back to sleep during the transition. This class takes care of creating and managing a partial wake lock for you; you must request the WAKE_LOCK permission to use it." – aphelion Oct 27 '16 at 15:20