Android issues when receiving broadcast from pending intent

I am using an emergency message manager to start a broadcast at a specific time. But after testing it so many times, I found that sometimes the transmission arrives late. Sometimes 5 seconds, 10, 15 or even sometimes. Especially when the device is locked. I have done various experiments. My least problematic code is here.

Even after using the tracking lock, I don't know what I am missing.

Shooting

Intent intent = new Intent(this.getApplicationContext(), BroadCastReceiver.class);  
//..... some extras
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), code, intent, 0);
manager.setRepeating(AlarmManager.RTC_WAKEUP, time, 1000 * 120 , pi);

      

Receiving a broadcast

public void onReceive(Context context, Intent intent)
{
       WakeLocker.acquire(context);
       .......
       Intent alarm = new Intent(context, xyz.class);
       alarm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       context.startActivity(alarm);
}

      

and freeing the Wakelock in the destroy () of the xyz activity.

Custom class WakeLocker     public abstract class WakeLocker {

private static PowerManager.WakeLock wakeLock;

public static void acquire(Context ctx) {
    if (wakeLock != null) wakeLock.release();

    PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
            PowerManager.ACQUIRE_CAUSES_WAKEUP |
            PowerManager.ON_AFTER_RELEASE, "haris");
    wakeLock.acquire();
}

public static void release() {
    if (wakeLock != null) wakeLock.release(); wakeLock = null;
}

      

}

+3


source to share


1 answer


According to the official documentation :

AlarmManager.setRepeating (...) - As with API 19, all repeated alarms are inaccurate. If your application requires accurate delivery times, you must use one-time accurate alarms, reschedule each time as described above. Legacy apps whose targetSdkVersion was earlier than API 19 will still have all of their alarms, including reoccurring alarms, are considered accurate.

This means that you must set your PendingIntent again when you receive it.
Something like that:



public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) {
    switch (intent.getAction()) {
        case AlarmHelper.ACTION_MY_ALARM: 
            doWhatYouNeed();
            long nextTime = getNextAlarmTime();
            AlarmHelper.resetAlarm(nextTime);
            break;
        ...
        }
    }
}

      

To get the next alarm time, you can use the System.currentTimeMillis () + interval or pass it in addition to the settings, the second way is more accurate. And I'm pretty sure you don't need the WakeLock in the BroadcastReceiver.

public class AlarmHelper {
    public static void resetAlarm(long time) { 
        Intent intent = createIntent(); 
        PendingIntent pendingIntent = createPendingIntent(intent);
        setAlarmManager(time, pendingIntent); 
    }

    public static void setAlarmManager(long time, PendingIntent pendingIntent) {
        AlarmManager alarmManager = (AlarmManager) MyApp.getAppContext().getSystemService(Context.ALARM_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent);
        } else {
            alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
        }
    }
}

      

+1


source







All Articles