Android Question Service stops

Discussion in 'Android Questions' started by davfla, Apr 16, 2015.

  1. davfla

    davfla Member Licensed User

    Hi all,

    i have a problem with start a alarm through a service. The service should check every minute for the wake time, but it will not work. I tested it under Android 5.0, Android 4.3 (Cyanogenmod) and Android 4.3 (Tab3). On every device the same problem.

    At first I tried it with a Timer in service :
    Works fine. But if the device are sleeping (screen off), the timer stops until the user awake the device.

    Then with StartServiceAt :
    Works not steadily.

    I use the Service Attribute
    In the event Service_Destroy :
    The code :
    Code:
    Dim StartTime as String = "10:30"

    Sub Service_Create
        
    DateTime.TimeFormat = "HH:mm"
        
    Dim n As Notification

        
    'This part only prevent for killing the process through the OS
        n.Initialize
        n.Icon = 
    Null
        n.Vibrate = 
    False
        n.OnGoingEvent = 
    True
        n.SetInfo(
    "Info""Prevent from being killed", Main)
        
    Service.StartForeground(0, n)

        SaveInText(
    "Service created.")

    End Sub

    Sub Service_Start (StartingIntent As Intent)
        CheckForUpdate
    End Sub

    Sub CheckForUpdate
        
    Dim tmpZeit As String = DateTime.Time(DateTime.Now)     'Nowtime
        StartServiceAt(""DateTime.Now + (44 * 1000), True)    'Restart service in 44 seconds

        
    'Check for alarm time
        If tmpZeit = StartTime then
              
    'Raise alarm
        End If
        SaveInText(
    "Service restart in : 44 seconds.")   'Log
    End Sub

    'Write the log in file
    Private Sub SaveInText(SaveText As String)
        
    Dim tw As TextWriter
        
    Dim Tt As String
        tw.Initialize(
    File.OpenOutput(File.DirRootExternal, "Info.txt"True))
        Tt = 
    DateTime.time(DateTime.Now) & " : " & SaveText
        
    Log(Tt)
        tw.Write(
    CRLF & Tt)
        tw.Flush
        tw.Close
    End Sub
    Here is a log file :

    09:00 : Service restart in : 44 seconds.
    09:03 : Service restart in : 44 seconds.
    09:04 : Service restart in : 44 seconds.
    09:04 : Service restart in : 44 seconds.
    09:05 : Service restart in : 44 seconds.
    09:06 : Service restart in : 44 seconds.
    09:08 : Service restart in : 44 seconds.
    09:10 : Service restart in : 44 seconds.

    09:10 : Service restart in : 44 seconds.
    09:11 : Service restart in : 44 seconds.
    09:12 : Service restart in : 44 seconds.
    09:13 : Service restart in : 44 seconds.
    09:15 : Service restart in : 44 seconds.
    09:16 : Service restart in : 44 seconds.
    09:17 : Service restart in : 44 seconds.
    09:19 : Service restart in : 44 seconds.
    09:21 : Service restart in : 44 seconds.

    09:22 : Service restart in : 44 seconds.
    09:23 : Service restart in : 44 seconds.
    09:24 : Service restart in : 44 seconds.
    09:24 : Service restart in : 44 seconds.
    09:26 : Service restart in : 44 seconds.

    09:27 : Service restart in : 44 seconds.
    09:29 : Service restart in : 44 seconds.
    09:33 : Service restart in : 44 seconds.

    09:34 : Service restart in : 44 seconds.
    09:35 : Service restart in : 44 seconds.
    09:37 : Service restart in : 44 seconds.
    09:39 : Service restart in : 44 seconds.

    09:39 : Service restart in : 44 seconds.
    09:40 : Service restart in : 44 seconds.
    09:41 : Service restart in : 44 seconds.
    09:42 : Service restart in : 44 seconds.
    09:44 : Service restart in : 44 seconds.
    09:44 : Service restart in : 44 seconds.
    09:46 : Service restart in : 44 seconds.

    09:48 : Service restart in : 44 seconds.
    09:49 : Service restart in : 44 seconds.
    09:50 : Service restart in : 44 seconds.
    09:54 : Service restart in : 44 seconds.

    09:55 : Service restart in : 44 seconds.
    09:56 : Service restart in : 44 seconds.
    09:57 : Service restart in : 44 seconds.
    09:59 : Service restart in : 44 seconds.

    09:59 : Service restart in : 44 seconds.
    10:00 : Service restart in : 44 seconds.
    10:01 : Service restart in : 44 seconds.
    10:02 : Service restart in : 44 seconds.
    10:03 : Service restart in : 44 seconds.
    10:03 : Service restart in : 44 seconds.
    10:04 : Service restart in : 44 seconds.
    10:06 : Service restart in : 44 seconds.
    10:08 : Service restart in : 44 seconds.

    10:09 : Service restart in : 44 seconds.
    10:11 : Service restart in : 44 seconds.
    10:12 : Service restart in : 44 seconds.
    10:13 : Service restart in : 44 seconds.
    10:14 : Service restart in : 44 seconds.
    10:15 : Service restart in : 44 seconds.
    10:16 : Service restart in : 44 seconds.
    10:17 : Service restart in : 44 seconds.
    10:19 : Service restart in : 44 seconds.

    10:20 : Service restart in : 44 seconds.
    10:21 : Service restart in : 44 seconds.
    10:22 : Service restart in : 44 seconds.
    10:23 : Service restart in : 44 seconds.
    10:24 : Service restart in : 44 seconds.
    10:25 : Service restart in : 44 seconds.
    10:25 : Service restart in : 44 seconds.
    10:26 : Service restart in : 44 seconds.
    10:27 : Service restart in : 44 seconds.
    10:28 : Service restart in : 44 seconds.
    10:29 : Service restart in : 44 seconds.
    10:29 : Service restart in : 44 seconds.
    10:32 : Service restart in : 44 seconds.

    10:32 : Service restart in : 44 seconds.
    10:33 : Service restart in : 44 seconds.
    The alarm was not raised because in the alarm time the service don't checked for the time. But the service should checked the time every 44 seconds. I tried to check with more then 44 seconds. But the same result.
    I know, this way is not the best for check the time. But in this example I only want to know why the service proof not every minute.

    Any suggestion what matters ?

    Thank you.
    David

    P.S. Sorry for my english
     
    Last edited: Apr 16, 2015
  2. Erel

    Erel Administrator Staff Member Licensed User

    Add Log(tmpZeit) to see the value of this variable.
     
  3. davfla

    davfla Member Licensed User

    Hi Erel,

    thank you for your answer.
    But the if-function is not the problem. I can remove this if-function and the result in the log file is the same. It looks for me the Android OS sometimes forget the wake event of the service. It is possible, that the start event fired after 1 - 4 minutes after the time in the StartServiceAt time. (see in log file from first thread).
    And sometimes the service create new without ending before. All the data in the log file was created while the app runs in background.

    Here is a part of a new log file from today. In this try I removed all functions. The service should only start every 44 seconds. Not more or less.

    12:30:11 : Service restart in : 44 seconds.
    12:30:55 : Service restart in : 44 seconds.
    12:31:40 : Service restart in : 44 seconds.
    12:32:24 : Service restart in : 44 seconds.
    12:33:08 : Service restart in : 44 seconds.
    12:33:53 : Service restart in : 44 seconds.
    12:36:18 : Service restart in : 44 seconds.

    12:36:19 : Service restart in : 44 seconds.
    12:37:03 : Service restart in : 44 seconds.
    12:37:48 : Service restart in : 44 seconds.
    12:38:32 : Service restart in : 44 seconds.
    12:39:16 : Service restart in : 44 seconds.

    In the time between 12:33 and 12:36 no event was raised. In this time the device was sleeping.

    And work with StartServiceAt with longer dimensions like 2 hours or more have the same problem.
    Is it possible to get a Android event, if the time changing?

    Very confused problem for me.

    Thank you.

    David
     
    Last edited: Apr 16, 2015
  4. Erel

    Erel Administrator Staff Member Licensed User

    Yes, it is possible that the OS doesn't start the service at the exact scheduled time.
     
    Peter Simpson and lemonisdead like this.
  5. davfla

    davfla Member Licensed User

    Hi,

    I created a new test. Now I stop the service after proof the time and cancel all scheduled wake times for the service before sending the ServiceStartsAt command.

    In this logs the app wrotes the estimated wake time of the service (second time in the log).

    09:31:52 : Next : 17/04 09:32:52*
    09:34:53 : Next : 17/04 09:35:53*
    09:35:53 : Next : 17/04 09:36:53*
    09:38:54 : Next : 17/04 09:39:54*

    09:42:54 : Next : 17/04 09:43:54*
    09:43:55 : Next : 17/04 09:44:55*
    09:46:30 : Next : 17/04 09:47:30*
    09:50:38 : Next : 17/04 09:51:38*
    09:52:20 : Next : 17/04 09:53:20*

    09:53:20 : Next : 17/04 09:54:20*
    09:54:20 : Next : 17/04 09:55:20*
    09:55:20 : Next : 17/04 09:56:20*
    09:56:38 : Next : 17/04 09:57:38*
    09:57:38 : Next : 17/04 09:58:38*
    09:58:38 : Next : 17/04 09:59:38*
    09:59:38 : Next : 17/04 10:00:38*
    10:00:38 : Next : 17/04 10:01:38
    10:01:38 : Next : 17/04 10:02:38*
    10:02:38 : Next : 17/04 10:03:38*
    10:03:39 : Next : 17/04 10:04:39*
    10:04:39 : Next : 17/04 10:05:39*
    10:06:14 : Next : 17/04 10:07:14*

    10:07:40 : Next : 17/04 10:08:40*
    10:08:40 : Next : 17/04 10:09:40*
    10:11:40 : Next : 17/04 10:12:40*

    Under Galaxy S5 with Android 5.0 the results looks better, but not steadily.

    06:16:50 : Next : 17/04 06:17:50*
    06:17:51 : Next : 17/04 06:18:51*
    06:18:52 : Next : 17/04 06:19:52*
    06:19:53 : Next : 17/04 06:20:53*
    06:20:53 : Next : 17/04 06:21:53*
    06:23:03 : Next : 17/04 06:22:54* <- very mysterious. Start the service before now time ?
    06:23:03 : Next : 17/04 06:24:03

    06:24:03 : Next : 17/04 06:25:03*
    06:25:04 : Next : 17/04 06:26:04*

    Is there any way to realize a reliable alarm watcher without the standard alarm from android ?
    Maybe I can proof the wake time for plausibility. Then I check for alarm in the last minutes and raise the alarm event in my app. But this would be a workaround only.

    I would be grateful for any suggestions.

    Thank you
    David
     
    Last edited: Apr 17, 2015
  6. Erel

    Erel Administrator Staff Member Licensed User

    You shouldn't use ServiceStartAt as a timer. You should instead use a real timer.

    You can use it to start the service a few minutes before the exact time then call Service.StartForeground to prevent the OS from killing the process and with a timer do whatever you need in the exact time.
     
  7. lemonisdead

    lemonisdead Well-Known Member Licensed User

    I am sorry this is not my question but the advice is important for me.
    Please why shouldn't a service be used as a timer with StartServiceAt ?

    Because it won't be started at the right time or because it is too heavy for the system ?

    Because it could be less energy spending having an action planned using StartServiceAt instead of having a long time service running

    Sorry again and many thanks
     
  8. Peter Simpson

    Peter Simpson Expert Licensed User

    @lemonisdead I personally use StartServiceAt set to True and as a Sticky Service in all my widgets and services. I use StartServiceAt as a timer (Mainly set to every 60 seconds or 60 minutes (for my weather app)) as I find that using an actual timer is not reliable enough for me, especially for my clock app/widget.

    Resources wise I've just check settings - battery usage on 4 devices running my widgets and services and not one of my widgets or services are showing up in the standard Android battery usage list :) lowest is 1%.

    I will use a timer within StartServiceAt if what I'm doing with the timer falls within 60 seconds of the StartServiceAt starting...
     
    Last edited: Apr 19, 2015
    lemonisdead likes this.
  9. lemonisdead

    lemonisdead Well-Known Member Licensed User

    Peter Simpson likes this.
  10. davfla

    davfla Member Licensed User

    Thank you for this hint. First tests looks good. I will report more soon. But what suprise me, in older tests the timer was stopped if the device was sleeping. Maybe I had tried without StickyService or Service.Foreground.

    Thanks
     
  11. davfla

    davfla Member Licensed User

    I had tested now the alarm with a timer. And there is the old problem again.

    I created a timer in a service. Here is a simplified example.

    Code:
    #Region  Service Attributes
       
    #StartAtBoot: True
       
    #StartCommandReturnValue: android.app.Service.START_STICKY
    #End Region

    Dim Time as Timer

    Sub Service_Create
       
    Dim n As Notification
      n.Initialize
      n.Icon = 
    Null
      n.Vibrate = 
    False
      n.OnGoingEvent = 
    True
      n.SetInfo(
    "Info""Prevent from being killed", Main)

      
    Service.StartForeground(0, n)
    End Sub

    Sub Service_Start (StartingIntent As Intent)

       
    If Time.IsInitialized = False Then
         Time.Initialize(
    "tim"1000) : Time.Enabled = True
         
    Log("Restart service - Init")
       
    Else
         Time.Interval = 
    1000 : Time.Enabled = True
         
    Log("Restart service - Reset")
       
    End If
     
    End Sub

    Sub Service_Destroy
       
    Log("Service was destroyed. Restart in 5 seconds.")
       
    StartServiceAt(""DateTime.Now + 5 * 1000True)
    End Sub

    Sub tim_Tick
       
    Log("Timer ticked")
       CheckForAlarm
    End Sub

    Sub CheckForAlarm
         
    'Here is code for restart the timer.
         'If the time > 30 minutes until the next wake point, then restart timer in 30 minutes.
         'Else restart at the wake time
    End Sub
    Now is the problem, that the service will killed by the OS without raise the "Sub Service_Destroyed".

    I think it depends from the device.
    I don't understand this because I use START_STICKY and Service.StartForeground.
    On Samsung Galaxy S1 with Cyanogenmod (Android 4.3) the service will destroyed nearly instantly. (Low System)
    On Samsung Galaxy S5 with Android 5.0 it will work 2-3 times and then the service stop. (Good System)
    On Emulator with Genymotion and Cyanogenmod it works without problems. (System no matters)

    If the OS would call the destroyed function then I could restart the service. But I get no request whether the service was killed or not.
    Maybe a mix between StartServiceAt and the timer can be the solution, but this is very complicated.

    I think, I work now with the workaround, that the service recreated himself in every minute and proof the time. If the duration of sleep bigger then the planned time, the application proof for missed alarm events. So a maximum of 5 minutes the alarm raised later. That's not a good solution, but the only I can see.
    If I find a better way I will post it here.

    Thanks all.

    David
     
    Last edited: Apr 19, 2015
  12. Erel

    Erel Administrator Staff Member Licensed User

    This is the expected behavior.

    Yes. You need to call StartServiceAt to start your process 10 minutes (?) before the exact time and then use a timer to fire at the exact time.
     
    Peter Simpson likes this.
  13. davfla

    davfla Member Licensed User

    Hi Erel,

    But the problem is, the timer on devices with poor hardware unpredictable interrupt. In my test with the Galaxy S1 the timer raise the Tick Event only 0-1 after the first initializing (in a service, in activity not). Then the timer stops without any message. I believe, the service will killed from the OS (without a Service_Destroyed) between the ticks. On my S5 this happends not so often, but it's possible.
    With other words : The service can destroyed from the OS in the Timer mode (10 minutes in your example)

    I know, devices with so old hardware configurations are not very distributed. But maybe anyone have many crapware on they device. Then it can matter, too. Because low RAM from the other apps.

    My method to start every minute with proof for skipped alarms works good, but it's drained the battery a little bit. Not the ideal solution.

    Maybe anyone have time and can test for get the same results.
    You need only a service, start a timer with a tick duration from 60*1000 and run it on a poor real device. I'm cursious about it.

    Thanks.

    David
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    See my answer in post #6. You need to call Service.StartForeground. You should also acquire a partial lock with PhoneWakeState.
     
  15. davfla

    davfla Member Licensed User

    I will try it with the PhoneWakeState function and report the result. Sounds what I searched for. Thanks for this tip.
     
  16. davfla

    davfla Member Licensed User

    Hi,

    I've tested with many different solutions and I solved the problem now.

    The timer object is not a good solution. This stop every time if the device is sleeping. I tried to wake up the screen with PhoneWakeState and it works. But if the user manually do switch off the screen, the timer don't work until the screen wake up again. This is for the snooze timer not practicabel. It works not with Start_Sticky or the PhoneWakeState.

    Now I realized it with a "four step" solution with two services. Here is an simplified example.

    Service A:
    Code:
    Dim TimeToStart as String   'i.E. 15:00
    Dim TimeNow as String       'Datetime.Now
    Dim Minutes as int 

    Minutes = timeToStart - TimeNow

    If NoWakePointToday then
         
    'Restart service 00:00 at next day
    end if

    If Minutes > 60 Minutes then         'Wake in 53 Minutes because battery drain and if the Service "forget" to start at the correct time
        'Restart Service in 53 minutes
    End if

    If Minutes >= 10 Minutes then       'Wake in 6 Minutes because battery drain and if the Service "forget" to start at the correct time
       'Restart Service in 6 Minutes
    End if

    If Minutes < 10 Minutes then
         
    Service B.TimeToStart = TimeToStart
         
    StartService(Service B)
    end if
    Service B:
    Code:
    Dim TimeToStart as String
    Dim TimeNow as String       'Datetime.Now

    Sub Service_Start
         
    If TimeToStart = TimeNow then
                
    'Raise Alarm
         Else
                RestartServiceAt(Me, 
    datetime.now + 10 * 1000True)
                
    StopService(me)
         
    End if
    End sub
    With this solution the battery drain is very low until the last 10 minutes. But it works reliably on weak hardware devices.

    Maybe anyone can help this. It had needed one week to get this result here.

    Thanks for answers.

    David
     
    Last edited: Apr 25, 2015
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice