Android Question BeaconParser Service.StartForeground

Lisa I

Member
Licensed User
Longtime User
Hi, I've been using your example BeaconParser app https://www.b4x.com/android/forum/t...iscover-ibeacons-and-eddystone-beacons.61127/
I want to receive beacon data continuously from when a start button is pressed until a stop button is pressed even if the phone display turns off.
It works well when the phone display is on, stops receiving when the display turns off, then restarts when the phone wakes up.

I read I needed to create a new service module which I have done but I'm not sure what to do now. Can you give me some idea please.
Thank you

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.
    Private nid As Int = 1
    Private lock As PhoneWakeState
End Sub

Sub Service_Create
    lock.PartialLock
End Sub

Sub Service_Start (StartingIntent As Intent)
    Service.StartForeground(nid, CreateNotification("..."))
End Sub


Sub CreateNotification (Body As String) As Notification
    Dim notification As Notification
    notification.Initialize2(notification.IMPORTANCE_LOW)
    notification.Icon = "icon"
    notification.SetInfo("Scanning", Body, Main)
    Return notification
End Sub

Sub Service_Destroy
    lock.ReleasePartialLock
End Sub
 
Hi Erel

Here is the Starter code, it's identical to your Beacon Parser example but for some changes in Sub Manager_DeviceFound

[CODE lang="b4x" title="Starter"]#Region Service Attributes
#StartAtBoot: False
#ExcludeFromLibrary: True
#End Region

Sub Process_Globals
Public manager As BleManager2
Public Parser As BeaconParser
Public currentStateText As String = "UNKNOWN"
Public currentState As Int
Public scanning As Boolean
Public Provider As FileProvider
Public beacons As Map
Public const TIME_TO_LIVE_SECONDS As Int = 5
Private Timer1 As Timer
Public rp As RuntimePermissions
Public rssisample As Double
Public RSSIData(10000) As Double
Public RSSITime(10000) As Long
Private i As Int =0
End Sub

Sub Service_Create
manager.Initialize("manager")
beacons.Initialize
Timer1.Initialize("timer1", TIME_TO_LIVE_SECONDS * DateTime.TicksPerSecond)
Timer1.Enabled = True
Parser.Initialize
Provider.Initialize
End Sub

Sub Service_Start (StartingIntent As Intent)

End Sub


Public Sub Scan
manager.Scan2(Null, True)
scanning = True
End Sub


Public Sub StopScan
manager.StopScan
scanning = False
End Sub

Private Sub Timer1_Tick
CallSub(Main, "StateChanged")
End Sub

Sub Manager_StateChanged (State As Int)
Select State
Case manager.STATE_POWERED_OFF
currentStateText = "POWERED OFF"
Case manager.STATE_POWERED_ON
currentStateText = "POWERED ON"
Case manager.STATE_UNSUPPORTED
currentStateText = "UNSUPPORTED"
End Select
currentState = State
CallSub(Main, "StateChanged")
End Sub


Sub Manager_DeviceFound (Name As String, Id As String, AdvertisingData As Map, RSSI As Double)

Dim beacon As Beacon = Parser.Parse(AdvertisingData, RSSI)
If beacon <> Null Then
'beacons.Put(beacon.uniqueid, beacon)
'CallSub(Main, "StateChanged")

Select beacon.BeaconType
Case Parser.TypeiBeacon
Dim ib As iBeacon = beacon.SpecificData
Log($"iBeacon: ${ib.uuid} (${ib.major}/${ib.minor})"$)
Case Parser.TypeEddystoneUID
Dim euid As EddystoneUID = beacon.SpecificData
Log($"Eddystone UID: ${euid.Namespace}:${euid.Instance}"$)
Log ("RSSI" & RSSI)
rssisample = RSSI
recordData
Case Parser.TypeEddystoneURL
Dim eurl As EddystoneURL = beacon.SpecificData
Log($"Eddystone URL: ${eurl.url}"$)
End Select
End If
End Sub

Public Sub recordData
RSSIData(i) = rssisample
RSSITime(i) = DateTime.Now
i = i +1
End Sub




'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
Return True
End Sub

Sub Service_Destroy

End Sub[/CODE]

and here's the main, thank you
[CODE lang="b4x" title="Main"]
#Region Project Attributes
#ApplicationLabel: B4A Example
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#End Region

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

Sub Process_Globals
'should be private
End Sub

Sub Globals
Private btnDisconnect As Button
Private btnScan As Button
Private lblState As Label
Private pbScan As ProgressBar
Private clv As CustomListView
Private uiitemas As Map
Private xui As XUI

Private Print As Button
Private EmailBtn As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("1")
uiitemas.Initialize
'i = 0
End Sub

Sub Activity_Resume
StateChanged
End Sub

Public Sub StateChanged
lblState.Text = Starter.currentStateText
btnDisconnect.Enabled = Starter.scanning
pbScan.Visible = Starter.scanning
btnScan.Enabled = (Starter.currentState = Starter.manager.STATE_POWERED_ON) And Starter.scanning = False
Dim beaconsToRemove As List
For Each beacon As Beacon In Starter.beacons.Values
If uiitemas.ContainsKey(beacon.uniqueid) = False Then
Dim p As Panel = CreateItem(beacon)
clv.Add(p, "")
uiitemas.Put(beacon.uniqueid, p)
Else
If beacon.time + Starter.TIME_TO_LIVE_SECONDS * DateTime.TicksPerSecond < DateTime.Now Then
'remove old beacon. We need to do it after the For Each loop.
If beaconsToRemove.IsInitialized = False Then beaconsToRemove.Initialize
beaconsToRemove.Add(beacon)
Else
Dim p As Panel = uiitemas.Get(beacon.uniqueid)
SetDistance(p.GetView(1), beacon)
End If
End If
Next
If beaconsToRemove.IsInitialized Then
For Each beacon As Beacon In beaconsToRemove
Dim p As Panel = uiitemas.Get(beacon.uniqueid)
clv.RemoveAt(clv.GetItemFromView(p))
uiitemas.Remove(beacon.uniqueid)
Starter.beacons.Remove(beacon.uniqueid)
Next
End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub btnScan_Click
Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_ACCESS_COARSE_LOCATION)
Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
If Result Then
pbScan.Visible = True
CallSub(Starter, "Scan")
StateChanged
Else
ToastMessageShow("No permission...", True)
End If
End Sub


Sub btnDisconnect_Click
CallSub(Starter, "StopScan")
StateChanged
End Sub


Sub CreateItem(beacon As Beacon) As Panel
Dim pnl As B4XView = xui.CreatePanel("")
pnl.SetLayoutAnimated(0, 0, 0, clv.AsView.Width, 50dip)
pnl.LoadLayout("Item")
Dim FirstLine As String
Select beacon.BeaconType
Case Starter.Parser.TypeiBeacon
Dim ib As iBeacon = beacon.SpecificData
FirstLine = $"iBeacon: ${ib.uuid} (${ib.major}/${ib.minor})"$
Case Starter.Parser.TypeEddystoneUID
Dim euid As EddystoneUID = beacon.SpecificData
FirstLine = $"Eddystone UID: ${euid.Namespace}:${euid.Instance}"$
Case Starter.Parser.TypeEddystoneURL
Dim eurl As EddystoneURL = beacon.SpecificData
FirstLine = $"Eddystone URL: ${eurl.url}"$
End Select
pnl.GetView(0).Text = FirstLine
SetDistance(pnl.GetView(1), beacon)
Return pnl
End Sub

Private Sub SetDistance(lbl As Label, beacon As Beacon)
lbl.Text = $"Distance: $1.1{beacon.distance} meters"$
End Sub


Private Sub Print_Click
Dim List1 As List
List1.Initialize

For i = 0 To 9999
List1.Add((Starter.RSSIData(i) & "," &Starter.RSSITime(i)))
Next


If File.Exists(File.DirInternal, "RSSIdata.txt") Then
File.Delete(File.DirInternal, "RSSIdata.txt")
End If
File.WriteList(File.DirInternal, "RSSIdata.txt", List1)


End Sub[/CODE]
 
Upvote 0
Back
Top