Android Question Broadcast Receiver not working

Angel Maza

Member
Licensed User
Longtime User
I'm trying to send data between two Android Apps using a Broadcast Receiver. I followed the forum post by Erel here: https://www.b4x.com/android/forum/t...sms-messages-in-the-background.20103/#content

The Sender App appears to be running fine, no error msg, and the receiver App seems to receive Sender App intents (see logs below).

The Receiver App yields these ongoing error msg. I tried implementation in the Starter->Starter_Create Sub as shown by Erel and moving the code into Main as show below. Both ways yield the same error msg "The Starter service should never be starter from a receiver".

Any help will be much appreciated.

Error Log:
B4X:
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Initialized the timers..
Intent Action: com.calypso.api.ACTION_DATA_AVAILABLE looking for: com.calypso.api.ACTION_DATA_AVAILABLE
Received AWA = 0
--
Intent Action: com.calypso.api.ACTION_DATA_AVAILABLE looking for: com.calypso.api.ACTION_DATA_AVAILABLE
** Receiver (starter) OnReceive **
The Starter service should never be started from a receiver.
** Service (starter) Start **
** Receiver (starter) OnReceive **
The Starter service should never be started from a receiver.
** Service (starter) Start **
** Receiver (starter) OnReceive **
The Starter service should never be started from a receiver.
** Service (starter) Start **
** Receiver (starter) OnReceive **
The Starter service should never be started from a receiver.
** Service (starter) Start **
** Receiver (starter) OnReceive **
The Starter service should never be started from a receiver.
** Service (starter) Start **
** Receiver (starter) OnReceive **
The Starter service should never be started from a receiver.
** Service (starter) Start **
** Receiver (starter) OnReceive **
The Starter service should never be started from a receiver.
** Service (starter) Start **
** Receiver (starter) OnReceive **


Receiver Code:
B4X:
    #Region  Project Attributes
    #ApplicationLabel: Ultrasonic Broadcast Receiver
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Public uiTimer As Timer
    Public broadcastTimer As Timer
    Public ctr As Int
    Public broadcastIntent As Intent
    Public AWA As Float
    Public AWD As Float
    Public AWS As Float
    Public dataFieldsAPI As List
    Public broadcastReceiverID As String
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Public lblTitle As Label
    Public ListView1 As ListView

    ' Initialize a list of all available Broadcast Intent Extras
    dataFieldsAPI.Initialize2(Array As String("Battery", "Temp", "AWA", "AWD", "AWS", "TWA", "TWD", "TWS", _
            "Pitch", "Roll", "Compass", "COG", "SOG"))

    broadcastReceiverID = "com.calypso.api.ACTION_DATA_AVAILABLE"  ' must match the Manifest entry
    ctr = 0
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("MainActivity")
    Activity.Title = "Calypso Ultrasonic API"

    lblTitle.Text = "Calypso Ultrasonic API"
    ' initialize the data fields available thru the API
End Sub

Sub Activity_Resume
    uiTimer.Initialize("uiTimer", 1000)
    uiTimer.Enabled = True
    
    broadcastTimer.Initialize("broadcastTimer", 800)
    broadcastTimer.Enabled = True
    Log("Initialized the timers.. ")
    
    broadcastIntent.Initialize(broadcastReceiverID, "")
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    uiTimer.Enabled = False
    broadcastTimer.Enabled = False
    If UserClosed Then
        Activity.Finish
    End If
End Sub

Sub uiTimer_Tick
    Log("Received AWA = " & AWA)
    Log("--")
    ctr = ctr + 1
    lblTitle.Text = ctr & ". dataset"
    ListView1.AddSingleLine( ctr & ". AWS record received = " & AWS)
    ListView1.SingleLineLayout.Label.TextSize = 14
End Sub

Sub broadcastTimer_Tick
'Sub broadcastIntent_OnReceive
    Log("Intent Action: "&broadcastIntent.Action&" looking for: "&broadcastReceiverID)
    If broadcastIntent.Action = broadcastReceiverID Then
        If broadcastIntent.HasExtra("AWA") Then
            Dim value() As String
            value = broadcastIntent.GetExtra("AWA")
            Log("AWA value: " & value(0))
            If (value.Length>0 And value(0).Length>0) Then
                AWA = value(0)
            Else
                AWA = 0.0
            End If
        End If
    End If
    
End Sub
 

DonManfred

Expert
Licensed User
Longtime User
You should not use the starter service for a broadcast receiver. Use another Service for this.
 
Upvote 0

Angel Maza

Member
Licensed User
Longtime User
DonManfred,
thx for your quick reply. As I'm still learning B4a, could you please give me a short example on how to do that ("... use another Service for this...")
 
Upvote 0

Angel Maza

Member
Licensed User
Longtime User
Thanks for all the help. I got it running by creating a new Service module called "BroadcastReceiverService" with this code below and updating the manifest as shown below:

BroadcastReceiverService.bas
B4X:
#Region  Service Attributes
    #StartAtBoot: False
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Public broadcastIntent As Intent
    Public TEMP As Float
    Public AWD As Float
    Public dataFieldsAPI As List
    Public broadcastReceiverID As String
End Sub

Sub Service_Create
    ' Initialize a list of all available Broadcast Intent Extras
    dataFieldsAPI.Initialize2(Array As String("Battery", "Temp", "AWA", "AWD", "AWS", "TWA", "TWD", "TWS", _
            "Pitch", "Roll", "COG", "SOG"))

    broadcastReceiverID = "com.calypso.api.ACTION_DATA_AVAILABLE"  ' must match the Manifest entry

End Sub

Sub Service_Start (StartingIntent As Intent)

    'Log("Intent Action: "&StartingIntent.Action&" looking for: "&broadcastReceiverID)
    If StartingIntent.Action = broadcastReceiverID Then
        ParseIntentData(StartingIntent)
    End If
    Sleep(50)
    
    Service.StopAutomaticForeground 'Call this when the background task completes (if there is one)
End Sub

Sub Service_Destroy

End Sub

Sub ParseIntentData(apiINTENT As Intent)
    Dim value() As String
    If apiINTENT.HasExtra("Temp") Then
        value = apiINTENT.GetExtra("Temp")
        Log("Temp value: " & value(0))
        If (value.Length>0 And value(0).Length>0) Then
            TEMP = value(0)
        Else
            TEMP = 0.0
        End If
    End If
    If apiINTENT.HasExtra("AWD") Then
        value = apiINTENT.GetExtra("AWD")
        Log("AWD value: " & value(0))
        If (value.Length>0 And value(0).Length>0) Then
            AWD = value(0)
        Else
            AWD = 0.0
        End If
    End If

End Sub

Manifest code addition:
B4X:
AddPermission(android.permission.RECEIVE_ULTRASONIC_API)
AddReceiverText(BroadcastReceiverService,
<intent-filter>
    <action android:name="com.calypso.api.ACTION_DATA_AVAILABLE" />
</intent-filter>)
 
Upvote 0
Top