Service is closing automatically

salmander

Active Member
Licensed User
Longtime User
Service is closing Unexpectedly

Hello,

I am developing an app, where service module listens to various system events, but after first "smsReceived_MessageReceived" event, the service doesn't responds to another "smsReceived_MessageReceived" event. Here is a sample of my Service Module
B4X:
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Dim pEvents As PhoneEvents 'for screen on/off
   Dim smsReceived As SmsInterceptor ' for receiving SMS
   Dim cToast As CustomToast 'For displaying custom toast
   Dim screenOn As Boolean
   Dim fromMessage, fromNumber As String
   Dim msgPending As Boolean
   Dim pSensor As PhoneSensors
   Dim ProxTimer As Timer
   Dim pWakeState As PhoneWakeState
   
End Sub

Sub Service_Create
   pEvents.Initialize("pEvents")
   smsReceived.Initialize("smsReceived")
End Sub

Sub Service_Start (StartingIntent As Intent)
   screenOn = True
   msgPending = False
   'maxProxValue = pSensor.MaxValue
   ToastMessageShow("TextNotification Service Started.", True)
End Sub

Sub Service_Destroy
   ToastMessageShow("TextNotification Service Stopped.", True)
   pEvents.StopListening
End Sub

Sub pEvents_ScreenOn (Intent As Intent)
   Log("Screen On")
   screenOn = True
   If msgPending = True Then
      Log("message is pending, so displaying a toast now.")
      dispToast(fromNumber & ": " & fromMessage)
      msgPending = False
      ScreenAwoke
   End If
   
End Sub

Sub pEvents_ScreenOff (Intent As Intent)
   Log("Screen Off")
   screenOn = False
   
End Sub

Sub ScreenAwoke
   ' Screen On, therefore, turning off the Prox Sensor and Phone Wake State
   pSensor.StopListening
   pWakeState.ReleaseKeepAlive
End Sub

Sub smsReceived_MessageReceived (from As String, Body As String) As Boolean
   Log("From: " & from & ". Body: " & Body)
   fromMessage = Body
   fromNumber = from
   If screenOn = True Then
   dispToast(fromNumber & ": " & fromMessage)
   Else
      ' screen is off
      msgPending = True
      pSensor.Initialize(pSensor.TYPE_PROXIMITY)
      ProxTimer.Initialize("ProxTimer", 5000)
      ProxTimer.Enabled = True
      pSensor.StartListening("pSensor")
   End If
End Sub

Sub pSensor_SensorChanged (Values() As Float)
   Dim SensorValue As Int
   SensorValue = Values(0)
   Log("SensorValue: " & SensorValue)
   ' value = 0 then object in proximity
   ' value = maxValue then object not in proximity
   
   ' turning the screen on.
   'If SensorValue = 0 Then
   If SensorValue < pSensor.MaxValue Then
      pWakeState.KeepAlive(True)
      StartActivity(ReplyTo) ' Starting the Reply To Activity
   End If
End Sub

Sub ProxTimer_Tick
   ProxTimer.Enabled = False
   Log("Maximum Time Reached. Closing the proximity sensor and releasing the KeepAlive.")
   ' turning the Proximity off
   pSensor.StopListening
   ' realeasing the screen alive
   pWakeState.ReleaseKeepAlive
   
End Sub


Sub dispToast (message As String)
   cToast.Initialize
   'cToast.Show(message, 10000, Gravity.BOTTOM, 0, 60)
   cToast.Show(message, 10000, Gravity.CENTER, 0, 0)
End Sub

And in the ReplyTo activity, on a button onClick event, i am using Activity.Finish to close the activity. But the Service should be running in the background right?
:sign0163: :sign0085: please
 
Last edited:

rfresh

Well-Known Member
Licensed User
Longtime User
Don't you need to call Service_Start again when you finish processing your code in receive an SMS message?

From the Service tutorial:

Sub Service_Start is called each time you call StartService (or StartServiceAt). When this subs runs the process is moved to the foreground state. Which means that the OS will not kill your process until this sub finishes running. If you want to run some code every couple of minutes / hours you should schedule the next task with StartServiceAt inside this sub.
 
Upvote 0

salmander

Active Member
Licensed User
Longtime User
Don't you need to call Service_Start again when you finish processing your code in receive an SMS message?

From the Service tutorial:

Sub Service_Start is called each time you call StartService (or StartServiceAt). When this subs runs the process is moved to the foreground state. Which means that the OS will not kill your process until this sub finishes running. If you want to run some code every couple of minutes / hours you should schedule the next task with StartServiceAt inside this sub.
Really? I mean, I thought Service Modules are not affected by Android Activity life cycle. So If I am not calling "StopService("")", then the service should be running in background?

so the services for other apps like, "Facebook Push Notifications" etc, do they keep calling the Service Start in order to keep the service active?

Thanks for your reply though mate....but I am a bit confused.
 
Upvote 0

rfresh

Well-Known Member
Licensed User
Longtime User
I guess I'm unclear on that too...I call StartServiceAt() in my ServiceStart event. I was under the impression the service would not keep going if I didn't. I will remove that line and see if the service keeps active.

Thanks...
 
Upvote 0

salmander

Active Member
Licensed User
Longtime User
I guess I'm unclear on that too...I call StartServiceAt() in my ServiceStart event. I was under the impression the service would not keep going if I didn't. I will remove that line and see if the service keeps active.

Thanks...
Thanks mate. Please do let me know what you find. I want to see what Erel has to say about it.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
That is not true.
You probably need to read the lifecycle of a service.
When the service is initially invoked, Service_Create and Service_Start runs.
The service will remain in memory, until the OS needs more resources. In this case the SMSInterceptor will work until the OS does not remove the service from memory. Until then, the events in the service can fire.
If you want your service NOT to be removed by the OS, you can run it as a foreground service.
When the OS does destroy the service, Service_Destroy is run. (This is probably your chance to save any state or schedule it to run again).
After Service_Destroy, the service is completely removed from memory, and when it is invoked again, Service_Create will run again.
If you run StartService or StartServiceAt when the service is already in memory, Service_Create will not run, only Service_Start will run.
If there is nothing for the service to do after Service_Start sub is run, the service will just hang around in memory doing nothing until the OS goes low on resources and removes it.
 
Upvote 0

salmander

Active Member
Licensed User
Longtime User
Thanks everyone for their help.

One question @thedesolatesoul;
1. Is there any other way of keeping the service in the memory, apart from;

i. Showing the notification in the notification bar

ii. Rescheduling the service again.​

The basic point of my service is, to listen to system events and I don't want to display a notification bar. If the service keeps dying and I keep rescheduling the service, then I don't think this is very effective way of listening to system events.
 
Upvote 0

salmander

Active Member
Licensed User
Longtime User
Sorry one more question, its regarding broadcast receiver. I don't know if I should ask it in broadcast receiver thread or here, but as its related to this application, I am asking here. I was looking at the Android Broadcast Receiver class and b4a BroadcastReceiver library. So if i use broadcast receiver in this service, would it be any different? I mean if I have a broadcast receiver for sms on receive event and when an sms arrives, then start the service, would it work? if the service is killed by android OS then the broadcast receiver can initiate the service on the sms on receive event.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
1. Is there any other way of keeping the service in the memory, apart from;

i. Showing the notification in the notification bar

ii. Rescheduling the service again.​

The basic point of my service is, to listen to system events and I don't want to display a notification bar. If the service keeps dying and I keep rescheduling the service, then I don't think this is very effective way of listening to system events.

I see your point. It is important for you to run your service in the foreground. Although it is a little sneaky to run in the background without the user not knowing about it (I read somewhere in the Android guidelines this is frowned upon). You may be able to do this by assigning a Null icon.
See Here
Is there a reason why you do not want the user to be aware that your process is running?


Sorry one more question, its regarding broadcast receiver. I don't know if I should ask it in broadcast receiver thread or here, but as its related to this application, I am asking here. I was looking at the Android Broadcast Receiver class and b4a BroadcastReceiver library. So if i use broadcast receiver in this service, would it be any different? I mean if I have a broadcast receiver for sms on receive event and when an sms arrives, then start the service, would it work? if the service is killed by android OS then the broadcast receiver can initiate the service on the sms on receive event.

Yes, as long as you are not trying to intercept the message so it does not reach any other app.
It seems like your service is an add-on to the usual SMS application. For your case a Broadcast receiver will be a less power-hungry alternative.
 
Upvote 0

salmander

Active Member
Licensed User
Longtime User
I see your point. It is important for you to run your service in the foreground. Although it is a little sneaky to run in the background without the user not knowing about it (I read somewhere in the Android guidelines this is frowned upon). You may be able to do this by assigning a Null icon.
See Here
Is there a reason why you do not want the user to be aware that your process is running?




Yes, as long as you are not trying to intercept the message so it does not reach any other app.
It seems like your service is an add-on to the usual SMS application. For your case a Broadcast receiver will be a less power-hungry alternative.

Thanks again for your help mate. Appreciate it a lot.
Answer to first question:
Well the reason I don't want the notification to be displayed is that I don't want the service to be active (or in foreground state) all the time. As this would draw more power. It should only initiate when a new SMS is received. However, I think I have found a solution, create a service, which will be initiated when a SMS_received broadcast is received. This service will start another service, which will do all the operations that needed to be performed and then that's it. Now the OS can kill either or both services, but whenever, a new broadcast is received, the first service will be initiated again, triggering the second service. Well this is what I have understood so far, correct me if I am wrong. But now the problem is that I need to find a way to initiate the service when the SMS_received broadcast is received. I was looking at the Broadcast Receiver library but either I misunderstood or it doesn't seems to receive the broadcasts when the service is killed by the OS.

To your second question; yes you can say that its a addon to the normal messaging application client.

Cheers.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
You just need to set up the intent filter and permissions in the manifest.

I havent tried it myself.

B4X:
<uses-permission android:name="android.permission.RECEIVE_SMS">

B4X:
<receiver android:name=".MySMSReceiver "> 
    <intent-filter> 
            <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
    </intent-filter> 
</receiver>
 
Upvote 0
Top