9

I have two examples of Intentservice. One is the Download example in the commonsware book. the other is at http://www.vogella.com/articles/AndroidServices/article.html#servicecommunication_handler. Both of these examples show the service executing a finite task and they both apparently destroy themselves by running to the end of the scope of the onHandleIntent event.

The service I am writing has to have events and listen for things. One is a LocationListener listening for GPS movement. Another makes Posts to a REST service and listens for replys. I want it to run until a time has elapsed or until it was told to quit by the activity that started it.

How do I keep it running? Where, for instance, do I put my implementation of LocationListener? Thanks, Gary

Dean Blakely
  • 3,535
  • 11
  • 51
  • 83
  • even i need an answer to the same question, in my case i am starting a flashlight from widget , but its getting killed. – user2548816 Aug 13 '16 at 19:34

3 Answers3

16

How do I keep it running?

You don't. IntentService is designed to do a piece of work (or perhaps a few off a queue, if commands happen to come in rapidly), then shut down.

The service I am writing has to have events and listen for things.

Then you should not be using an IntentService. Use a regular Service, with your own background thread(s) as needed.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 2
    Can someone qualify this answer? IntentService is a subclass of Service, so why should only the latter be used (in a new thread) for long-running / ongoing operations?? – ban-geoengineering Aug 30 '14 at 16:08
  • @ban-geoengineering: As I wrote, `IntentService` was designed around transactional operations, where the work is done fairly quickly and the service should then shut down. If you want something that will run longer than that, create your own `Service` with your own controls for when the `Service` stops itself (or is stopped by a client via `stopService()`). – CommonsWare Aug 30 '14 at 16:21
  • I understand what you've said, but I'd like to know where you have got this information from so I can verify for myself that this is indeed the case. – ban-geoengineering Aug 31 '14 at 22:21
  • 1
    @ban-geoengineering: Discussions with Google engineers, mostly. – CommonsWare Aug 31 '14 at 22:22
  • 1
    Is it not documented anywhere? – ban-geoengineering Sep 01 '14 at 11:33
  • @ban-geoengineering: Developer intentions when designing and implementing a class are not usually documented. If you don't like the advice, don't follow it. – CommonsWare Sep 01 '14 at 11:38
  • 2
    This is just not true. You can do anything inside IntentService which you would do with a regular service. All it does is it provides message queue to the thread executing HandleIntent. You can still put service in foreground all the same. – SergeyA Jun 16 '16 at 02:26
  • 2
    @SergeyA: "All it does is it provides message queue to the thread executing HandleIntent." -- and immediately shuts down once the work is completed. That is why computer programmers use it for a transactional bit of work. You are certainly welcome to use `startForeground()` for that transaction. But the question is about `LocationListener`; that is intrinsically asynchronous and therefore unsuitable for `IntentService`. – CommonsWare Jun 16 '16 at 11:08
  • @CommonsWare, you just never return from HandleIntent. – SergeyA Jun 16 '16 at 13:16
  • @SergeyA: I do not recommend that solution. Never indefinitely tie up a resource (e.g., a thread) that you did not create yourself. – CommonsWare Jun 16 '16 at 13:34
  • @CommonsWare, as good solution is any. I see no problem with it. – SergeyA Jun 16 '16 at 13:35
  • The documentation now says `All requests... may take as long as necessary (and will not block the application's main loop)...`: https://developer.android.com/reference/android/app/IntentService.html – ban-geoengineering Nov 07 '16 at 20:31
  • @ban-geoengineering: "as long as necessary" does not mean "indefinitely". – CommonsWare Nov 07 '16 at 20:32
  • I've used the foreground intent service approach (as mentioned by Luis: http://stackoverflow.com/a/12878290/1617737 ) and my intent service usually runs for hours/days/weeks. – ban-geoengineering Nov 07 '16 at 20:34
  • @CommonsWare I'm not sure about that. From my experience, "as long as necessary" is more towards the "indefinitely" end of the spectrum that the "just a few seconds" end. – ban-geoengineering Nov 07 '16 at 20:36
  • @CommonsWare your comments like from holy book man. is that still true that which is the part of "You don't..." after 5 years in 2017. if YES, are you prefer to use normal 'Service'? – mehmet Nov 19 '17 at 17:13
  • @mehmet: "is that still true..." -- yes. "are you prefer to use normal 'Service'?" -- that depends. In general, having long-running background started services of any type is not a good idea, which is why on Android 8.0+, they only run for a minute. A foreground service (`startForeground()`) could run for a longer period of time. Frequently, there is some other solution to the problem (e.g., `JobScheduler` for periodic work). – CommonsWare Nov 19 '17 at 17:22
-1

You can achieve this in either of two ways,

AlarmManager is android's in-buite class that allows you to execute certain action on particular time peroid.

TimerTask does same thing as AlarmManager, you can repeat certain action of your code again and again.

However AlarmManager is ligher in the execution so i suggest you to go with AlarmManager class.

Create an AlarmManager that fetches the GPS Co-ordinates and post them to server on regular interval basis.

Have a look at to this AlarmManager Example.

Lucifer
  • 29,392
  • 25
  • 90
  • 143
-1

To keep a service running, your service need to return START_STICKY in the service method onStartCommand().

With this, the service will be running even if you exit form your activity.

Note: The Android still kills services after some time (30 mintus to 1 hour) if they are not foreground services. Use startForeground(notification) to make it foreground.

good luck

Luis
  • 11,978
  • 3
  • 27
  • 35