Android Question Ble Peripheral mode as IBeacon in foreground service

mike1967

Active Member
Licensed User
Longtime User
Hello, i have attached ,based on https://www.b4x.com/android/forum/threads/ble-peripheral-as-ibeacon.105601/post-662028. Can some one help me to create a foreground service ,always on, for transmit in background also if the app is minimized ? Thanks in advances. I work with https://www.b4x.com/android/forum/threads/background-location-tracking.99873/ WITHOUTH SUCCESS.
Solved in some part
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
    Private rp As RuntimePermissions
End Sub

Sub Globals
    Private btnStartStop As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Layout")
Dim Permissions As List
Permissions = Array(rp.PERMISSION_ACCESS_FINE_LOCATION,"android.permission.BLUETOOTH_ADVERTISE",rp.PERMISSION_POST_NOTIFICATIONS)
For Each PER As String In Permissions
    rp.CheckAndRequest(PER)
    Wait For Activity_PermissionResult (PERMISSION As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission: " & PERMISSION, True)
        Activity.Finish
    End If
Next
End Sub

Sub btnStartStop_Click
    If btnStartStop.Text="Avvia IBeacon" Then
        StartService(ForegroundBeacon)
        btnStartStop.Text="Ferma IBeacon"
    Else
        btnStartStop.Text="Avvia IBeacon"
        StopService(ForegroundBeacon)
    End If
      
End Sub

Sub Activity_Resume
  
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Starter:
#Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: 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.

End Sub

Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.

End Sub

Sub Service_Start (StartingIntent As Intent)
    Service.StopAutomaticForeground 'Starter service can start in the foreground state in some edge cases.
End Sub

Sub Service_TaskRemoved
    'This event will be raised when the user removes the app from the recent apps list.
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:
#Region  Service Attributes
    #StartAtBoot: False
  
#End Region


Sub Process_Globals
    Private manager As BleManager2
    Public connectedCentrals As Map
    Private peripheral As BlePeripheral2
    Public NotAvailable As Boolean
    Private NativeMe As JavaObject
  
    Private b() As Byte
End Sub

Sub Service_Create
    NativeMe.InitializeContext
    manager.Initialize("manager")
    connectedCentrals.Initialize
End Sub

Sub Service_Start (StartingIntent As Intent)
    Dim n As Notification
    n.Initialize
    n.Icon = "icon"
    n.SetInfo("iBeacon Attivo", "Trasmissione in corso", Main)
    Service.StartForeground(1, n)
    StartAdvertising
End Sub

Sub Service_Destroy
    StopAdvertising
    Service.StopForeground(1)
End Sub

Private Sub StartAdvertising
    Dim bc As ByteConverter
    If  manager.State=manager.STATE_POWERED_OFF Then
        ToastMessageShow("Please enable Bluetooth", True)
        NotAvailable = True
    Else
        peripheral.Initialize("peripheral", manager)
      
        Dim bb As B4XBytesBuilder 'B4XCollections
        bb.Initialize
        bb.Append(Array As Byte(0x02, 0x15))
        Dim bc As ByteConverter
        bb.Append(bc.HexToBytes("0CF052C297CA407C84F8B62AAC4E9020"))
        bb.Append(Array As Byte(0, 9, 0, 6, 0xb5))
        b = bb.ToArray
        peripheral.ManufacturerData = CreateMap(76: b )
        Log(b.Length)
        If peripheral.IsPeripheralSupported = False Then
            ToastMessageShow("Peripheral mode not supported.", True)
            NotAvailable = True
        Else
            Dim AdvertiseDataBuilder As JavaObject
            AdvertiseDataBuilder = AdvertiseDataBuilder.InitializeNewInstance("android.bluetooth.le.AdvertiseData.Builder", Null)
            If peripheral.ManufacturerData.IsInitialized Then
                For Each key As Int In peripheral.ManufacturerData.Keys
                    Dim value() As Byte = peripheral.ManufacturerData.Get(key)
                    AdvertiseDataBuilder.RunMethod("addManufacturerData", Array(key, value))
                Next
            End If
            Dim AdvertiseData As JavaObject = AdvertiseDataBuilder.RunMethod("build", Null)
            Dim AdvertiseSettingsBuilder As JavaObject
            AdvertiseSettingsBuilder = AdvertiseSettingsBuilder.InitializeNewInstance("android.bluetooth.le.AdvertiseSettings.Builder", Null)
            AdvertiseSettingsBuilder.RunMethod("setConnectable", Array(False))
            Dim callback As JavaObject
            callback.InitializeNewInstance(Application.PackageName & ".foregroundbeacon$MyCallback", Null)
            Dim jo As JavaObject = peripheral
            jo.GetFieldJO("advertiser").RunMethod("startAdvertising", Array(AdvertiseSettingsBuilder.RunMethod("build", Null), _
                AdvertiseData, Null, callback))
        End If
      
    End If
End Sub

Private Sub StopAdvertising
    Dim callback As JavaObject
    callback.InitializeNewInstance(Application.PackageName & ".foregroundbeacon$MyCallback", Null)
    Dim jo As JavaObject = peripheral
    jo.GetFieldJO("advertiser").RunMethod("stopAdvertising", Array(callback))
End Sub

#if Java
import android.bluetooth.le.*;
public static class MyCallback extends AdvertiseCallback {
 public void onStartSuccess(AdvertiseSettings settingsInEffect) {
         BA.Log("Started successfully");
    }
    public void onStartFailure(int errorCode) {
    BA.Log("failed to start: " + errorCode);
    }
}
#End If
Manifest:
AddManifestText(
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
CreateResourceFromFile(Macro, Themes.LightTheme)
AddPermission("android.permission.BLUETOOTH")
AddPermission("android.permission.BLUETOOTH_ADMIN")
AddPermission("android.permission.BLUETOOTH_ADVERTISE")
AddPermission("android.permission.ACCESS_FINE_LOCATION")
AddPermission("android.permission.FOREGROUND_SERVICE")
AddPermission("android.permission.FOREGROUND_SERVICE_LOCATION")
AddPermission("android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE")
SetServiceAttribute(ForegroundBeacon, android:foregroundServiceType, "location|connectedDevice")


The stop advertising not work . Can help me ? Also Can help me with the Correct request of permission for Android 12+? Thanks In Advances
 
Upvote 0

mike1967

Active Member
Licensed User
Longtime User
Solved in some part
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
    Private rp As RuntimePermissions
End Sub

Sub Globals
    Private btnStartStop As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Layout")
Dim Permissions As List
Permissions = Array(rp.PERMISSION_ACCESS_FINE_LOCATION,"android.permission.BLUETOOTH_ADVERTISE",rp.PERMISSION_POST_NOTIFICATIONS)
For Each PER As String In Permissions
    rp.CheckAndRequest(PER)
    Wait For Activity_PermissionResult (PERMISSION As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("No permission: " & PERMISSION, True)
        Activity.Finish
    End If
Next
End Sub

Sub btnStartStop_Click
    If btnStartStop.Text="Avvia IBeacon" Then
        StartService(ForegroundBeacon)
        btnStartStop.Text="Ferma IBeacon"
    Else
        btnStartStop.Text="Avvia IBeacon"
        StopService(ForegroundBeacon)
    End If
    
End Sub

Sub Activity_Resume
 
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Starter:
#Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: 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.

End Sub

Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.

End Sub

Sub Service_Start (StartingIntent As Intent)
    Service.StopAutomaticForeground 'Starter service can start in the foreground state in some edge cases.
End Sub

Sub Service_TaskRemoved
    'This event will be raised when the user removes the app from the recent apps list.
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:
#Region  Service Attributes
    #StartAtBoot: False
 
#End Region


Sub Process_Globals
    Private manager As BleManager2
    Public connectedCentrals As Map
    Private peripheral As BlePeripheral2
    Public NotAvailable As Boolean
    Private NativeMe As JavaObject
 
    Private b() As Byte
End Sub

Sub Service_Create
    NativeMe.InitializeContext
    manager.Initialize("manager")
    connectedCentrals.Initialize
End Sub

Sub Service_Start (StartingIntent As Intent)
    Dim n As Notification
    n.Initialize
    n.Icon = "icon"
    n.SetInfo("iBeacon Attivo", "Trasmissione in corso", Main)
    Service.StartForeground(1, n)
    StartAdvertising
End Sub

Sub Service_Destroy
    StopAdvertising
    Service.StopForeground(1)
End Sub

Private Sub StartAdvertising
    Dim bc As ByteConverter
    If  manager.State=manager.STATE_POWERED_OFF Then
        ToastMessageShow("Please enable Bluetooth", True)
        NotAvailable = True
    Else
        peripheral.Initialize("peripheral", manager)
    
        Dim bb As B4XBytesBuilder 'B4XCollections
        bb.Initialize
        bb.Append(Array As Byte(0x02, 0x15))
        Dim bc As ByteConverter
        bb.Append(bc.HexToBytes("0CF052C297CA407C84F8B62AAC4E9020"))
        bb.Append(Array As Byte(0, 9, 0, 6, 0xb5))
        b = bb.ToArray
        peripheral.ManufacturerData = CreateMap(76: b )
        Log(b.Length)
        If peripheral.IsPeripheralSupported = False Then
            ToastMessageShow("Peripheral mode not supported.", True)
            NotAvailable = True
        Else
            Dim AdvertiseDataBuilder As JavaObject
            AdvertiseDataBuilder = AdvertiseDataBuilder.InitializeNewInstance("android.bluetooth.le.AdvertiseData.Builder", Null)
            If peripheral.ManufacturerData.IsInitialized Then
                For Each key As Int In peripheral.ManufacturerData.Keys
                    Dim value() As Byte = peripheral.ManufacturerData.Get(key)
                    AdvertiseDataBuilder.RunMethod("addManufacturerData", Array(key, value))
                Next
            End If
            Dim AdvertiseData As JavaObject = AdvertiseDataBuilder.RunMethod("build", Null)
            Dim AdvertiseSettingsBuilder As JavaObject
            AdvertiseSettingsBuilder = AdvertiseSettingsBuilder.InitializeNewInstance("android.bluetooth.le.AdvertiseSettings.Builder", Null)
            AdvertiseSettingsBuilder.RunMethod("setConnectable", Array(False))
            Dim callback As JavaObject
            callback.InitializeNewInstance(Application.PackageName & ".foregroundbeacon$MyCallback", Null)
            Dim jo As JavaObject = peripheral
            jo.GetFieldJO("advertiser").RunMethod("startAdvertising", Array(AdvertiseSettingsBuilder.RunMethod("build", Null), _
                AdvertiseData, Null, callback))
        End If
    
    End If
End Sub

Private Sub StopAdvertising
    Dim callback As JavaObject
    callback.InitializeNewInstance(Application.PackageName & ".foregroundbeacon$MyCallback", Null)
    Dim jo As JavaObject = peripheral
    jo.GetFieldJO("advertiser").RunMethod("stopAdvertising", Array(callback))
End Sub

#if Java
import android.bluetooth.le.*;
public static class MyCallback extends AdvertiseCallback {
 public void onStartSuccess(AdvertiseSettings settingsInEffect) {
         BA.Log("Started successfully");
    }
    public void onStartFailure(int errorCode) {
    BA.Log("failed to start: " + errorCode);
    }
}
#End If
Manifest:
AddManifestText(
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
CreateResourceFromFile(Macro, Themes.LightTheme)
AddPermission("android.permission.BLUETOOTH")
AddPermission("android.permission.BLUETOOTH_ADMIN")
AddPermission("android.permission.BLUETOOTH_ADVERTISE")
AddPermission("android.permission.ACCESS_FINE_LOCATION")
AddPermission("android.permission.FOREGROUND_SERVICE")
AddPermission("android.permission.FOREGROUND_SERVICE_LOCATION")
AddPermission("android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE")
SetServiceAttribute(ForegroundBeacon, android:foregroundServiceType, "location|connectedDevice")


The stop advertising not work . Can help me ? Also Can help me with the Correct request of permission for Android 12+? Thanks In Advances
Declare callback as private and removing the initialization in stopAdvertising and the declaration in startAdvertising can stop the ble advertising. Now seem that work fine.
 
Upvote 0
Top