Android Question Widget service lifecycle...

tunderin

Member
Licensed User
Longtime User
Hi everybody,

I spent some time searching outside of this forum - Stack Overflow & such - but came up empty handed...

The B4A documentation says that the widget service is just a regular service, but when I deliberately stop the service, Android immediately starts it again. That would make sense because it handles events from widget views, etc

That behavior would also suggest to me that a widget service is more like a sticky service & that it runs almost 100% of the time. This would seem to make my widget service a better home for my phone call listener (using PhoneEvents) than building it in a service of its own.

Are my assumptions correct?
 

tunderin

Member
Licensed User
Longtime User
Thanks Erel... I see the advantages

My end objective is to get the telephone number of the incoming call so that I can pop an information panel (with data from the DB) over the incoming call screen.

I should be able get there using "Android.Telephony.LISTEN_CALL_STATE" and manifest permission "android.permission.READ_PHONE_STATE" - correct?
 
Upvote 0

tunderin

Member
Licensed User
Longtime User
Thanks Erel,

This is my test app's manifest in which I set up my intent filter:

B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.b4x.com/forum/showthread.php?p=78136

AddManifestText(
<uses-sdk android:minSdkVersion="8" />
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.
AddPermission(android.permission.READ_PHONE_STATE)
AddReceiverText(Listener,
<intent-filter>
    <action android:name="android.telephony.PhoneStateListener.LISTEN_CALL_STATE" />
</intent-filter>)



My service is named "Listener" & it starts with:


B4X:
Sub Service_Start(startingIntent As Intent)
    Log("Listener Service started.")
    If startingIntent.Action = "android.telephony.PhoneStateListener.LISTEN_CALL_STATE" Then
        Dim callState As List
        Dim r As Reflector
        callState = r.RunStaticMethod("android.telephony.PhoneStateListener","onCallStateChanged",Null,Null)
        Log("CallState="&callState)

    End If
   
End Sub


When I place a call to my dev phone, the service is not started.

Is there anything obviously wrong in the above?

Thanks...
 
Last edited:
Upvote 0

tunderin

Member
Licensed User
Longtime User
Thanks NJDude,

I corrected the capitalization but it still doesn't work.

I originally used PhoneEvents (as in your sample) to implement a listener & looked to give it a home in my widget service (hence this thread) which I would then need to run in foreground. Erel suggested a static filter which suited my purposes better.

From his link:

Difference between static and dynamic receivers

The main difference between the two types of receivers is that dynamic receivers listen to intents as long as the process is running.

Static receivers always work. If the process is not running then it will be created.

Normal processes eventually get killed. This means that you cannot rely on dynamic receivers to intercept intents when your application is in the background. A possible workaround is to call Service.StartForeground in the service. This will prevent the process from being killed. However this will also add an ongoing notification icon (see the Services tutorial for more information).

It seems to me to be a more elegant solution for a listener - now I just have to make it work...
 
Upvote 0

tunderin

Member
Licensed User
Longtime User
Are you talking about substituting in the manifest or the service_start sub?
 
Upvote 0

tunderin

Member
Licensed User
Longtime User
Thanks NJDude, that worked! I found the incoming telephone number that I needed in the intent extras.

I had poked around the TelephonyManager class during the course of this effort but went PhoneStateListener instead. Was there something fundamental that I overlooked that made your suggestion the more appropriate way to go?
 
Upvote 0

NJDude

Expert
Licensed User
Longtime User
Well, you are listening for that event which will start the service, so, unless I'm not seeing something (or understanding) using the filter + the PhoneEvents looked good to me, so, what's the final code you ended up with?
 
Upvote 0

tunderin

Member
Licensed User
Longtime User
This is what I ended up with - I still can't explain why PhoneStateListener class didn't work...

Be good NJDude


B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.b4x.com/forum/showthread.php?p=78136

AddManifestText(
<uses-sdk android:minSdkVersion="8" />
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.
AddPermission(android.permission.READ_PHONE_STATE)
AddReceiverText(Listener,
<intent-filter>
    <action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>)


B4X:
Sub Service_Start(startingIntent As Intent)

    Log("Listener Service started.")
    Log("startingIntent="&startingIntent)

    If startingIntent.Action = "android.intent.action.PHONE_STATE" Then
        Log(startingIntent.ExtrasToString)

    End If
   
End Sub
 
Upvote 0
Top