Android Question BLE custom ScanFilter device settings

Rick in North Carolina

Member
Licensed User
Longtime User
I am using the example from BLE ScanSettingsBuilder modified starter service in posting: https://www.b4x.com/android/forum/threads/ble-scansettings.94908/#post-600231
Works great :cool:.

Now I am trying to add custom ScanFilterSettings with setDeviceName as a filter but I'm not having success with the Filters array (my lack of understanding of javaobject :()
This is my modified code from the example above, I'm guessing my problem is in Filters.InitializeArray.

B4X:
Private Sub ScanWithLeScanner
    Dim ScanSettingsStatic As JavaObject
    ScanSettingsStatic.InitializeStatic("android.bluetooth.le.ScanSettings")
    Dim ScanSettingsBuilder As JavaObject
    ScanSettingsBuilder.InitializeNewInstance("android.bluetooth.le.ScanSettings.Builder", Null)
    'https://developer.android.com/reference/android/bluetooth/le/ScanSettings.Builder
    ScanSettingsBuilder.RunMethod("setScanMode", Array(ScanSettingsStatic.GetField("SCAN_MODE_LOW_LATENCY")))
    '----------------------------------------------------------------------
    '    Add Scan Filter
    Dim ScanFilterStatic As JavaObject
    ScanFilterStatic.InitializeStatic("android.bluetooth.le.ScanFilter")
    Dim ScanFilterBuilder As JavaObject
    ScanFilterBuilder.InitializeNewInstance("android.bluetooth.le.ScanFilter.Builder", Null)
    'https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder
    ScanFilterBuilder.RunMethod("setDeviceName", Array("B4APeripheral"))
   
    ScanFilterBuilder.InitializeNewInstance("android.bluetooth.le.ScanFilter.Builder", Null)
    Dim Filters As JavaObject
    Filters.InitializeArray("android.bluetooth.le.ScanFilter",ScanFilterBuilder.RunMethod("build",Null))
    '---------------------------------------------------------------------------
   
    ScanSettingsBuilder.InitializeNewInstance("android.bluetooth.le.ScanSettings.Builder", Null)
    Scanner.RunMethod("startScan", Array(Filters, ScanSettingsBuilder.RunMethod("build", Null), ScanCallback))
    'Scanner.RunMethod("startScan", Array(Null, ScanSettingsBuilder.RunMethod("build", Null), ScanCallback))
End Sub

Any help is appreciated.
 

DonManfred

Expert
Licensed User
Longtime User
Do you get any error? Which?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4X:
Dim ScanFilterBuilder As JavaObject
ScanFilterBuilder.InitializeNewInstance("android.bluetooth.le.ScanFilter.Builder", Null)
ScanFilterBuilder.RunMethod("setDeviceName", Array("B4APeripheral"))
Dim Filters As List = Array(ScanFilterBuilder.RunMethod("build", Null)
Scanner.RunMethod("startScan", Array(Filters, ScanSettingsBuilder.RunMethod("build", Null), ScanCallback))

If it doesn't work then you should post the full error message.
 
Upvote 0

Rick in North Carolina

Member
Licensed User
Longtime User
Yep, like I thought, I didn't need Filters.InitializeArray but couldn't figure out the correct declaration for Dim Filiters. Thank you Erel. Works now. Still slow on Android 8 but I need to try different settings to see if it will be as fast as Android 7. Thanks again :).

Edit: I should clarify - Going custom with the ScanSettingsBuilder, the scan is fast but with a 4 second delay between scans (so overall slow). I tested with Android 7, 8 & 9 and this 5 sec delay is the same on all versions (I commented out the ScanFilterBuilder to troubleshoot).
I went custom because with the BLE2 B4A library on Android 8, the scan is about 330 to 500 ms on Sub Manager_DeviceFound, finding a beacon with xmit of 100 ms. BLE2 on Android 7 scans close to 100ms (great).

Update: My mistake - works now - see Post 8
 
Last edited:
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
The following may be relevant (or not), but could affect the speed issue in Android 8.

Some months ago, I used Erel's code and it helped a lot to solve some issues that I had with a specific device.
Additional to it, in Android 8 and specially with Samsung devices, you must make sure to have location ON (not the permissions, but the setting) since it directly affects how BLE scanning behaves, even if the permissions are ok.
 
Upvote 0

Rick in North Carolina

Member
Licensed User
Longtime User
The following may be relevant (or not), but could affect the speed issue in Android 8.

Some months ago, I used Erel's code and it helped a lot to solve some issues that I had with a specific device.
Additional to it, in Android 8 and specially with Samsung devices, you must make sure to have location ON (not the permissions, but the setting) since it directly affects how BLE scanning behaves, even if the permissions are ok.

Thanks JordiCP, I turned on Location but no change. Have you ever run into the issue with delay between scans? (I edited above post)
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Hi Rick,
I didn't experience delay between scans because, once found, I connected to the device (it was not a beacon) to start dialog with it.
The problem in my case was the delay to appear for the first time specially if there were other BLE devices nearby: using SCAN_MODE_LOW_LATENCY instead of CAN_MODE_BALANCED did the trick.

Just in case, what are you doing once the device is found? There's no need to call stopScan nor scan again, since it will continue running until you tell it to stop.

Will do some tests later and try to reproduce the delay.
 
Upvote 0

Rick in North Carolina

Member
Licensed User
Longtime User
OK I made a mistake in my Sub ScanWithLeScanner. Anyway this code works in Android 7,8,9 (in case anyone is following along)
B4X:
Private Sub ScanWithLeScanner
    Dim ScanSettingsStatic As JavaObject
    ScanSettingsStatic.InitializeStatic("android.bluetooth.le.ScanSettings")
    Dim ScanSettingsBuilder As JavaObject
    ScanSettingsBuilder.InitializeNewInstance("android.bluetooth.le.ScanSettings.Builder", Null)
    'https://developer.android.com/reference/android/bluetooth/le/ScanSettings.Builder
    ScanSettingsBuilder.RunMethod("setScanMode", Array(ScanSettingsStatic.GetField("SCAN_MODE_LOW_LATENCY")))
    '----------------------------------------------------------------------
    '    Add Scan Filter
    Dim ScanFilterStatic As JavaObject
    ScanFilterStatic.InitializeStatic("android.bluetooth.le.ScanFilter")
    Dim ScanFilterBuilder As JavaObject
    ScanFilterBuilder.InitializeNewInstance("android.bluetooth.le.ScanFilter.Builder", Null)
    'https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder
    ScanFilterBuilder.RunMethod("setDeviceName", Array("B4APeripheral"))
    Dim Filters As List = Array(ScanFilterBuilder.RunMethod("build", Null))
    '---------------------------------------------------------------------------
    Scanner.RunMethod("startScan", Array(Filters, ScanSettingsBuilder.RunMethod("build", Null), ScanCallback))
End Sub

This may be a little faster than using BLE2.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
OK I made a mistake in my Sub ScanWithLeScanner. Anyway this code works in Android 7,8,9 (in case anyone is following along)
B4X:
Private Sub ScanWithLeScanner
    Dim ScanSettingsStatic As JavaObject
    ScanSettingsStatic.InitializeStatic("android.bluetooth.le.ScanSettings")
    Dim ScanSettingsBuilder As JavaObject
    ScanSettingsBuilder.InitializeNewInstance("android.bluetooth.le.ScanSettings.Builder", Null)
    'https://developer.android.com/reference/android/bluetooth/le/ScanSettings.Builder
    ScanSettingsBuilder.RunMethod("setScanMode", Array(ScanSettingsStatic.GetField("SCAN_MODE_LOW_LATENCY")))
    '----------------------------------------------------------------------
    '    Add Scan Filter
    Dim ScanFilterStatic As JavaObject
    ScanFilterStatic.InitializeStatic("android.bluetooth.le.ScanFilter")
    Dim ScanFilterBuilder As JavaObject
    ScanFilterBuilder.InitializeNewInstance("android.bluetooth.le.ScanFilter.Builder", Null)
    'https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder
    ScanFilterBuilder.RunMethod("setDeviceName", Array("B4APeripheral"))
    Dim Filters As List = Array(ScanFilterBuilder.RunMethod("build", Null))
    '---------------------------------------------------------------------------
    Scanner.RunMethod("startScan", Array(Filters, ScanSettingsBuilder.RunMethod("build", Null), ScanCallback))
End Sub

This may be a little faster than using BLE2.

Hi
Have you scanned using UUID's, using your example I can scan using the mac address, but the UUID is not working for me.

B4X:
Private Sub ScanWithLeScanner
   
   Dim ScanSettingsStatic As JavaObject
   ScanSettingsStatic.InitializeStatic("android.bluetooth.le.ScanSettings")
   Dim ScanSettingsBuilder As JavaObject
   ScanSettingsBuilder.InitializeNewInstance("android.bluetooth.le.ScanSettings.Builder", Null)
   'https://developer.android.com/reference/android/bluetooth/le/ScanSettings.Builder
   ScanSettingsBuilder.RunMethod("setScanMode", Array(ScanSettingsStatic.GetField("SCAN_MODE_LOW_POWER")))
   
   ' // https://www.b4x.com/android/forum/threads/ble-custom-scanfilter-device-settings.99300/#post-625276
   Dim ScanFilterStatic As JavaObject
   ScanFilterStatic.InitializeStatic("android.bluetooth.le.ScanFilter")
   Dim ScanFilterBuilder As JavaObject
   ScanFilterBuilder.InitializeNewInstance("android.bluetooth.le.ScanFilter.Builder", Null)


   ' // https://developer.android.com/reference/android/os/ParcelUuid.html
   Dim ParcelUuidStatic As JavaObject
   ParcelUuidStatic.InitializeStatic("android.os.ParcelUuid")
   Dim ParcelUuid As JavaObject
   ParcelUuid = ParcelUuidStatic.RunMethod("fromString",Array("f7826da6-4fa2-4e98-8024-bc5b71e0893e"))
   Log("LOOK HERE => " & ParcelUuid.RunMethod("toString",Null))
   
   'https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder
   'ScanFilterBuilder.RunMethod("setServiceUuid", Array(ParcelUuid))
   
   ' // MAC Address
   ScanFilterBuilder.RunMethod("setDeviceAddress", Array(Main.APPSET.bleSOS.MacAddress))
   
   
   Dim Filters As List = Array(ScanFilterBuilder.RunMethod("build", Null))
   ' // start the scanning   
   Scanner.RunMethod("startScan", Array(Filters, ScanSettingsBuilder.RunMethod("build", Null), ScanCallback))
   
End Sub

Regards

John.
 
Upvote 0
Top