Search code examples
androidservicealarmmanager

AlarmManager + Service on Idle (screen off)


I call my Service with alarm manager

like this:

 alarmManage.setExact(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + getPoolingInterval(), pendingIntentPolling);

On my ServicePooling i reschedule it of the same way, and this ServicePooling call another service to send data on my service.

Intent serviceSocket = new Intent(this.context, SenderService.class);
    this.context.startService(serviceSocket);

All works very well every minut i receive on my server a polling communication, but when my device are screen off and without USB plugged, this stop work.


Solution

  • This is a bad idea to use Service for AlarmManager nowadays. Use WakefulBroadcastReceiver instead. your device fall asleep then unplugged.

    public class BRMine extends WakefulBroadcastReceiver {
        public static final String INTENT_FILTER = "com.example.BRMine";
        @Override
        public void onReceive(Context ctx, Intent intent) {
            // TODO Auto-generated method stub
            OWakeLocker.acquire(ctx, _.indexNOTS);
            ComponentName comp = new ComponentName(ctx.getPackageName(),
                    SMine.class.getName());
            startWakefulService(ctx, intent.setComponent(comp));
        }
    
    }
    

    where:

    public class OWakeLocker { private static PowerManager.WakeLock[] wakeLocks = new PowerManager.WakeLock[_.indexNOTS_MAX];//Services count

    @SuppressWarnings("deprecation")
    public static void acquire(Context ctx, int index) {
        WakeLock wakeLock = wakeLocks[index];
        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, _.APPNAME + Integer.toString(index));
        if (wakeLock != null && wakeLock.isHeld()){
            wakeLock.acquire();
        }
    }
    
    public static void release(int index) {
        WakeLock wakeLock = wakeLocks[index];
        if (wakeLock != null) 
            wakeLock.release();
            wakeLock = null;
    }}
    

    to start:

      Intent intent = new Intent(BRMine.INTENT_FILTER);
    PendingIntent pi = PendingIntent.getBroadcast(ctx, myintentalarm, intent, PendingIntent.FLAG_CANCEL_CURRENT):
    am.setExact(AlarmManager.RTC_WAKEUP, nexttime, pi);