3

I need a service to handle event while the screen is off, like receiving delayed messages (with the Handler) and internet connection state change.

Is it possible for a service to get those signal without permanently using the PARTIAL_WAKE_LOCK, since I don't need the service to run all the time?

Laetan
  • 879
  • 9
  • 26
  • 2
    You need `BroadcastReceivers` to receive different states http://developer.android.com/reference/android/content/BroadcastReceiver.html – Jibran Khan May 07 '15 at 15:14
  • @JibranKhan I would suggest you to make an answer of your comment because it's correct – Chaosit May 07 '15 at 15:23
  • 1
    @JibranKhan, of course it was your solution:) – Chaosit May 07 '15 at 15:29
  • please help me https://stackoverflow.com/questions/53705956/background-service-pause-and-start-again-automatically-for-android-oreo –  Dec 12 '18 at 11:36

2 Answers2

1

You need BroadcastReceivers to receive different states. Refer to Android Documentation for more information

http://developer.android.com/reference/android/content/BroadcastReceiver.html

Also for example, you can refer here https://www.grokkingandroid.com/android-getting-notified-of-connectivity-changes/ Some snippet from the example link provided

registerReceiver(
      new ConnectivityChangeReceiver(),
      new IntentFilter(
            ConnectivityManager.CONNECTIVITY_ACTION));

BroadcastReceiver implementation

public class ConnectivityChangeReceiver
               extends BroadcastReceiver {

   @Override
   public void onReceive(Context context, Intent intent) {
      debugIntent(intent, "grokkingandroid");
   }

   private void debugIntent(Intent intent, String tag) {
      Log.v(tag, "action: " + intent.getAction());
      Log.v(tag, "component: " + intent.getComponent());
      Bundle extras = intent.getExtras();
      if (extras != null) {
         for (String key: extras.keySet()) {
            Log.v(tag, "key [" + key + "]: " +
               extras.get(key));
         }
      }
      else {
         Log.v(tag, "no extras");
      }
   }

}

As StenSoft suggested you can use AlarmManager for delayed messages or any other scheduling task. I have used the below example and its working

public class Alarm extends BroadcastReceiver 
{    
    @Override
    public void onReceive(Context context, Intent intent) 
    {   
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wl.acquire();

        // Put here YOUR code.
        Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example

        wl.release();
    }

    public void SetAlarm(Context context)
    {
        AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, Alarm.class);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pi); // Millisec * Second * Minute
    }
}
Jibran Khan
  • 3,236
  • 4
  • 37
  • 50
  • You mean that a simple receiver still do the job even while the screen is off and no wake lock is used? That's convenient. What habout handler and delayed messages (if I want to do stuff 5 minutes after for example)? – Laetan May 07 '15 at 15:34
  • If you want some stuff done after some specific time and want to optimize your service then my opinion is to use `IntentService` and as suggested by StenSoft you can also use Alarm Services – Jibran Khan May 07 '15 at 15:36
  • I don't know if I've been clear enough, but I need all the works done after the event to be silent. I mean the screen stays off, the user do not know anything is happenning. If the alarm is like a timed PARTIAL_WAKE, it's all good. – Laetan May 07 '15 at 15:53
  • If you want silent execution for scheduled tasks, make use of `IntentService` IMO – Jibran Khan May 07 '15 at 16:13
  • You should not create wakelocks in `onReceive` (create them in application or service) and you should release the wakelock in `finally` (so that it will be released even when an exception is thrown). `WakefulBroadcastReceiver` does all this for you. – StenSoft May 07 '15 at 16:43
  • please help me https://stackoverflow.com/questions/53705956/background-service-pause-and-start-again-automatically-for-android-oreo –  Dec 12 '18 at 11:36
1

For delayed messages, use alarm.

For internet connection changes on background, use WakefulBroadcastReceiver.

StenSoft
  • 9,369
  • 25
  • 30
  • The alarm seems to "wake the device up" if it is asleep. Does it also set the screen on? And the documentation says the WakefulBroadcastRecivei receive "device wakeup events". Does it means event like ACTION_SCREEN_ON and OFF? Because that is no what I need. – Laetan May 07 '15 at 15:44
  • 1
    @Laetan No, neither alarm nor wakeful broadcast receiver turn the screen on, they just wake the device so your code can run. Your code then can [turn the screen on](https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON) if it wants to. – StenSoft May 07 '15 at 16:24
  • please help me https://stackoverflow.com/questions/53705956/background-service-pause-and-start-again-automatically-for-android-oreo –  Dec 12 '18 at 11:37