Android Tutorial Receivers and Services in 2023+

Status
Not open for further replies.
In the early days of Android services were simple to use and powerful. They allowed doing all kinds of things in the backgrounds with very few restrictions. That's not the case with newer versions of Android.
With a few exceptions (that aren't 100% reliable), the only use case for services is to let the app continue to do its job while it moves to the background - for example a music player app or navigation app.

B4A v12.2 includes a new type of module named Receiver or the Java term static Broadcast Receiver. Receivers "listen" to intents and are started when a relevant intent is received.
The default code is:
B4X:
Sub Process_Globals
  
End Sub

'Called when an intent is received.
'Do not assume that anything else, including the starter service, has run before this method.
Private Sub Receiver_Receive (FirstTime As Boolean, StartingIntent As Intent)
  
End Sub
Receivers aren't actively listening to intents. It is the OS that is responsible for starting the process after a relevant intent was sent.
There are two types of intents that are deemed relevant:
1. Intents that explicitly target the receiver. For example, such intent is created when we schedule a receiver to start with StartReceiverAt.
2. Intents with actions that are defined in the manifest editor. For example, if we want to run something after boot:
B4X:
AddPermission(android.permission.RECEIVE_BOOT_COMPLETED)
AddReceiverText(MyReceiver, <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>)
A few use cases for receivers:
  • Handling push notifications
  • Scheduling receivers to run
  • Home screen widgets
  • Activity recognition
  • Run after boot
  • And more...
Q. Can receivers do everything that services can?

A. No. Receivers run for a short time. There is no similar feature to foreground services where a service can continue to run in the background indefinitely.

Q. I don't need new stuff. I will continue to use my beloved services for all of these use cases.

A. Good for you, but your app will crash on Android 12+ devices with this error when the process is started from the background:

Fatal Exception: java.lang.RuntimeException: Unable to start receiver b4a.example.starter$starter_BR: android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service b4a.example/.starter

Notes
  • The starter service will not start before the receiver when a process starts from a receiver.
  • The CancelScheduledService keyword, which cancels services scheduled with StartServiceAt, also works with receivers scheduled with StartReceiverAt.
  • B4A services are actually made of a receiver + service. These automatic receivers are named <service>_BR. Not too important but you might encountered those in the past.
 
Last edited:

Magma

Expert
Licensed User
Longtime User
Hi there

Great news... but bad as always for Android and new versions.

1.Sometimes when I run an app that has services and reboot.. start again automatically... sometimes not.. that can fix it?

2.if the app start at foreground... we can run services.. without the new adds.. right?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Sometimes when I run an app that has services and reboot.. start again automatically... sometimes not.. that can fix it?
1. Yes and you can't start services at boot on newer devices.
2.if the app start at foreground... we can run services.. without the new adds.. right?

2. True. This is more or less the only use case for services.
 

Magma

Expert
Licensed User
Longtime User
@Erel It will help a b4xpage example starting a service/or activity (with the right permissions) from intent...

B4X:
Private Sub Receiver_Receive (FirstTime As Boolean, StartingIntent As Intent)
    'hmmm here.... i am going to run my service ???
StartService(BanBank_Alarm)
   'or it is better to start activity.... ???
End Sub
 

LucaMs

Expert
Licensed User
Longtime User
Receivers are not new in Android. The new thing is that services can no longer do what receivers can.
If I remember correctly (and I never remember correctly 😁 :confused: , especially this stuff, after at least 10 years) when I discovered the existence of Android I started "studying" (reading) and the basic elements were just:
Activity, Service, Receiver, Intent (I think)
At that time Eclipse + ADT (a dedicated plugin) was used to develop apps.

If Erel only implemented Services there must have been a reason, certainly. Today I will have to go back to studying Recesivers and Services well, because since they both exist, I suppose that the differences are not minimal (and because I obviously don't remember what I read, after at least 10 years)
 

Erel

B4X founder
Staff member
Licensed User
Longtime User

Erel

B4X founder
Staff member
Licensed User
Longtime User
If Erel only implemented Services there must have been a reason,
Not too important but B4A services are actually made of a receiver + a service. The receiver was never exposed as there was no reason to interact with it. The internal receiver simply delegated the intent to the service.
 

Alessandro71

Well-Known Member
Licensed User
Longtime User
You cannot start a service while the app is in the background.

In order to start an activity you need to have this permission: https://www.b4x.com/android/forum/threads/draw-on-top-of-other-apps-permission.90513/
If you have it then all that you need to do is call StartActivity(Main). This is true for B4XPages projects as well.
I think we’ll see updated samples in the forum soon, because this whole receivers thing seems to have big implications.
By reading this, I think of one app of mine, which has a Home Screen widget, that, when clicked, opens up the main page.
I think this won’t work anymore, but I dont have a clear idea of how to fix it.
 

Magma

Expert
Licensed User
Longtime User
You cannot start a service while the app is in the background.

In order to start an activity you need to have this permission: https://www.b4x.com/android/forum/threads/draw-on-top-of-other-apps-permission.90513/
If you have it then all that you need to do is call StartActivity(Main). This is true for B4XPages projects as well.
.i want to ask..something silly...

1) Let's talk about a commercial app.. like Viber...
You are getting into Viber for first time... giving permissions - all set ok...
rebooting... and automatic viber run at background - or not ? - without the need to show activity - right ?
So it has something like us at service:
B4X:
    #StartAtBoot: True
Or somehow manufacturer of device, commercial apps already setuped for this... (???)

2a) It has to do with (1)..
So mine "block call incoming" app now with Android 12 works... with this - if first time ofcourse get in app and take permissions:
B4X:
    #StartAtBoot: True
and in service, with this:
B4X:
Sub Service_Start (StartingIntent As Intent)
...
        Service.StartForeground(1, CreateNotification("..."))
...
End Sub
When I got into my app first time, give permissions... then reboot and then automatically notification showed at notifications-bars.. now for Android 13-SDK 33 I will need module receiver... and i will startactivity (ofcourse if having draw on apps permission)? So I will need every time to show an activity of my app ?

2b) draw on apps permission - is it Google giving it easy... or will stuck again... and wait Google-Team 1 month :) ?
 
Last edited:

giggetto71

Active Member
Licensed User
Longtime User
one question to understand if this may apply to one of my applications. I have one service started as automatic foreground always that implements an MQTT client and keeps listening, once started, for subscribed topics from an MQTT broker over the network (to keep running it also requests partial lock). could I evaluate use receivers? could one receiver "receive" the topics, execute the relevant code and then "sleep" until the next topic?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Do the changes mean that scheduling services to restart themselves as Erel presents here https://www.b4x.com/android/forum/threads/service-modules.7542/post-43019 will no longer work?
StartServiceAt / StartServiceAtExact will not work on Android 12+. This is related to new Android restrictions.
You need to use StartReceiverAt instead.

draw on apps permission - is it Google giving it easy... or will stuck again... and wait Google-Team 1 month :) ?
It has nothing to do with Google. This is a permission that the user grants your app. B4A-Bridge uses it for example.

one question to understand if this may apply to one of my applications. I have one service started as automatic foreground always that implements an MQTT client and keeps listening, once started, for subscribed topics from an MQTT broker over the network (to keep running it also requests partial lock). could I evaluate use receivers? could one receiver "receive" the topics, execute the relevant code and then "sleep" until the next topic?
With push notifications yes. In this case no, as you need to maintain a network connection. You should use a service and start it while the app is in the foreground.
 

Magma

Expert
Licensed User
Longtime User
StartServiceAt / StartServiceAtExact will not work on Android 12+. This is related to new Android restrictions.
You need to use StartReceiverAt instead.


It has nothing to do with Google. This is a permission that the user grants your app. B4A-Bridge uses it for example.


With push notifications yes. In this case no, as you need to maintain a network connection. You should use a service and start it while the app is in the foreground.
So for foreground services with notifications no need changes, right ? Or it is better to do from now some changes?

* I think 🤔 that I m cycling the same and same, sorry if I am annoying.. but I always feel bad with SDK android changes
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
So for foreground services with notifications no need changes, right ?
It depends. If you are starting the service while the app is in the foreground (there is a visual activity / B4XPage) then it will continue to work as before.
However, if you are starting the service while the app is in the background then it will not work on Android 12+ devices.
 

Intelemarketing

Active Member
Licensed User
Longtime User
My mind has just about flipped :oops: - I have no idea what you are all talking about and "DOES THIS RELATE TO ME?.

However I will wait until someone can explain in simple terms what this is all about, and what kind of applications it relates to.

I just love this statement "A service is normally unable to start an activity if there isn't already an activity in the foreground."
(So how to get the activity in the foreground if you are unable to start an activity if there isn't one started already ? HUH?)

Memories of "Who's on First ?"
 

DonManfred

Expert
Licensed User
Longtime User
So how to get the activity in the foreground if you are unable to start an activity if there isn't one started already ? HUH?
You need to have a special permission

StartActivity from a service will not work if there is no visible activity. As a workaround you can request the special "draw over apps" permission: https://www.b4x.com/android/forum/threads/draw-on-top-of-other-apps-permission.90513/
It will allow StartActivity to work.
 

3fazeac

Member
Licensed User
Longtime User
To prevent the OS from stopping my (long running) app, will I still be able to use :
PhoneWakeState.PartialLock construct ?

Should I move the PartialLock code from the Service to the Main?
 
Status
Not open for further replies.
Top