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:

Star-Dust

Expert
Licensed User
Longtime User
A few use cases for receivers:
  • Handling push notifications
  • Scheduling receivers to run
  • Home screen widgets
  • Activity recognition
  • Run after boot
  • And more...
Thanks for the great work.
Is it possible to have a complete list of cases in which the intent can be used? Is there any Android documentation we can consult?

If I'm not mistaken you have updated some of your examples for the new version. Can you list which examples have been updated?
It may be useful to download the new versions to study them and better understand how to use this tool
 

ema01

Member
Licensed User
Longtime User
Hi, could receivers be used to launch the application if a bluetooth device is in range?
Because you basically can't (or don't want to have) a service running 24/7 looking for devices
 

Creideiki

Active Member
Licensed User
Longtime User
When do I need to switch from service to receiver?
* When I use 31 (or 32?) as targetSDK? (ok, that's quite obvious)
* When I run on a device with Android 12+ without changing my targetSDK?
* When I switch to B4A 12.2?

In other words: Is this only relevant when I use targetSDK >= 31 or in other cases, too?
 
1. Yes.
2. No.
3. No.

4. Google Play requires setting the targetSdkVersion to 31.
5. It is quite simple to switch to receivers and I suggest doing it anyway.
Hi Erel,
First of all, thanks for your work. I want to receive broadcast intents in my app. I've tested broadcastreceiver library, and worked fine in the demo example, but when I add to my app with api 33, it doesn't work.
So I'm testing with new module of receiver type, adding the manifest, but I don't get the receive envent.
What is the problem?

this is my manifest.xml:
B4X:
AddReceiverText(MyReceiver, <intent-filter>
    <action android:name="com.my.application.CUSTOM_INTENT"/>
</intent-filter>)

and this is myReceiver module:
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)   
    Log(StartingIntent)
End Sub
 
Status
Not open for further replies.
Top