Android Question BLE Android 9 - Scanning stops when screen turned off

Jmu5667

Well-Known Member
Licensed User
Hello

We are working with these devices, https://store.kontakt.io/next-generation/43-asset-tag-s18-3.html.

We have a service that runs and is scanning:

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 manager As BleManager2
   Private currentStateText As String = "UNKNOWN"
   Private currentState As Int
   Private scanning As Boolean
   Private bc As ByteConverter
      
   Private const TIME_TO_LIVE_SECONDS As Int = 30
  
   Private Timer1 As Timer
   Private rp As RuntimePermissions
   Private ManagerJO As JavaObject
   Private Adapter As JavaObject
   Private Scanner As JavaObject
   Private ScanCallback As JavaObject


End Sub

Sub Service_Create

   manager.Initialize("manager")
   ManagerJO = manager
   Adapter = ManagerJO.GetField("blueAdapter")
   Scanner = Adapter.RunMethod("getBluetoothLeScanner", Null)
   ScanCallback.InitializeNewInstance(Application.PackageName & ".svc_ble_sos_le$MyScanCallback", Null)
  
   Timer1.Initialize("hook",5000)

End Sub

Sub Service_Start (StartingIntent As Intent)
   Timer1.Enabled = True
  
   StartScan_le
  
  
End Sub

Sub Service_Destroy
  
   StopScanWithLeScanner
  
   Timer1.Enabled = False
   

End Sub

Sub hook_tick
  
   mod_functions.writelog("hook_tick() Still Running")
  
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

End Sub

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

' // based on this answer: http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing
Private Sub CalculateDistance(tx As Int, rssi As Double) As Double
   If rssi = 0 Then Return -1
   Dim ratio As Double = rssi / tx
   If ratio < 1 Then
       Return Power(ratio, 10)
   Else
       Return 0.89976 * Power(ratio, 7.7095) + 0.111
   End If
End Sub

#region "LE Scanner"

Public Sub StartScan_le
   If manager.State <> manager.STATE_POWERED_ON Then
       Log("Not powered on.")
   Else If rp.Check(rp.PERMISSION_ACCESS_COARSE_LOCATION) = False Then
       Log("No location permission.")
   Else
       ScanWithLeScanner
   End If
End Sub


Private Sub Scan_Result (Result As Object)
  

   Dim ScanResult As JavaObject = Result
   Dim device As JavaObject = ScanResult.RunMethod("getDevice", Null)
   Dim address As String = device.RunMethod("getAddress", Null)
  
  
  
   ManagerJO.GetFieldJO("devices").RunMethod("put", Array(address, device))

   Dim name As String
   Dim o As Object = device.RunMethod("getName", Null)
   If o = Null Then name = "" Else name = o
   Dim ScanRecord As JavaObject = ScanResult.RunMethod("getScanRecord", Null)
   'Log(ScanRecord) 'you can extend the code to access the data.
   'https://developer.android.com/reference/android/bluetooth/le/ScanRecord
   Dim rssi As Double = ScanResult.RunMethod("getRssi", Null)
  
   log("svc_ble_sos_le() Scan_Result > name : " & name & ", rssi : " & rssi & ", " & address)
  
' // not called yet as screen off issue
'   Manager_DeviceFound(name, address, CreateMap(), rssi)
  
End Sub

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")))
  
   Scanner.RunMethod("startScan", Array(Null, ScanSettingsBuilder.RunMethod("build", Null), ScanCallback))
End Sub

Private Sub StopScanWithLeScanner
   Scanner.RunMethod("stopScan", Array(ScanCallback))
End Sub


#End Region


#if Java
import android.bluetooth.le.*;
public static class MyScanCallback extends ScanCallback {
 public void onScanResult(int callbackType, ScanResult result) {
         processBA.raiseEvent(this, "scan_result", result);
    }

  

    /**
     * Callback when scan could not be started.
     *
     * @param errorCode Error code (one of SCAN_FAILED_*) for scan failure.
     */
    public void onScanFailed(int errorCode) {
       BA.Log("Error: " + errorCode);
    }
}
#End If

We have noticed that on Android 9 when the screen is turned off no more Scan_Result events are fired, and when the screen is turn back on the scan results resume.

We were using the standard Ble method that Erel provided, https://www.b4x.com/android/forum/threads/ble-2-bluetooth-low-energy.59937/#content

We switched to the above code example to see if it made a difference, the result was the same. It functioned fine up to Android 8.

Regards

John.
 

emexes

Expert
Licensed User
BTW, do now of any tags, that can :

1. Be filtered scanned (UUID's) in a background service
2. Have a button on it
3. Trigger some sort of New UUID, service data etc when pressed ?

The tags I have here are from Ebay for about $3 each, and look like this:

upload_2019-3-5_2-12-57.png


and the name that comes up on the Scan[2] advertising data is "ITAG".

1/ they are what I scanned above using Scan2 with the filter service 0000ffe0-0000-1000-8000-00805f9b34fb,

2/ they do have a button, but...

3/ what happens when you press the button, that's a bit interesting.

Normally these tags emit an advert once per second.

When you press the button (on the green one, at least - I purchased them at separate times, and I vaguely remember that there was some subtle difference between the two batches) then it emits a burst of perhaps 15-20 adverts at a much higher rate, like 5-10 per second.

I expected that the button press would be encoded somewhere in the advertising, but I was wrong - the advertisement doesn't change (other than rate). I then connected up to it and found that there is a characteristic that tells you whether the button is pressed or not. Why that button-press data is not in the advertisements, I have no idea. The tags would be much more usable if it was, rather than having to connect up and read a characteristic.

It occurred to me later that maybe some id of the device was changing when the button was pressed, and that perhaps I'd only looked at one of these (hypothetically) two ids, and that could be why the advertising data appeared to not change. I haven't yet gotten back to checking that out.
 
Last edited:
Upvote 0

Jmu5667

Well-Known Member
Licensed User
The tags I have here are from Ebay for about $3 each, and look like this:

View attachment 77985

and the name that comes up on the Scan[2] advertising data is "ITAG".

1/ they are what I scanned above using Scan2 with the filter service 0000ffe0-0000-1000-8000-00805f9b34fb,

2/ they do have a button, but...

3/ what happens when you press the button, that's a bit interesting.

Normally these tags emit an advert once per second.

When you press the button (on the green one, at least - I purchased them at separate times, and I vaguely remember that there was some subtle difference between the two batches) then it emits a burst of perhaps 15-20 adverts at a much higher rate, like 5-10 per second.

I expected that the button press would be encoded somewhere in the advertising, but I was wrong - the advertisement doesn't change (other than rate). I then connected up to it and found that there is a characteristic that tells you whether the button is pressed or not. Why that button-press data is not in the advertisements, I have no idea. The tags would be much more usable if it was, rather than having to connect up and read a characteristic.

It occurred to me later that maybe some id of the device was changing when the button was pressed, and that perhaps I'd only looked at one of these (hypothetically) two ids them and that was why the advertising data appeared to not change. I haven't yet gotten back to checking that out.

Thanks for that info :)
 
Upvote 0

emexes

Expert
Licensed User
Just to be clear, have you successfully done a background UUID filtered scan, even with the screen off ?

Good question.

I thought the double-whammy scan-with-screen-off issue was with Android 9 (which I don't have - two devices I bought last month, one is 7.0 and the other is 5.1.1) and that we were trying to do a filtered scan because that was a (new) requirement for BLE scans done in-the-background / with-screen-off, and you were at a point where filtered scans weren't working at all:
I got a list of services ... put that as filtered list in the our app that wants to background scan and did not yield any results in the foreground no[r?] the background.

Anyway, to simply answer your question (rather than sound like I'm dodging it ;-) it's: no, I have not successfully done a background UUID-filtered scan, even with the screen off.

But bear in mind that's because: no, I have not tried to do a background UUID-filtered scan, with the screen off.

I'll give that a go tomorrow (I mean: today) (if I wake up...) When we're talking "background" and "with the screen off", is that like: screen off by pressing the sleep button, or by the display timing out ie backlight off, or the device locking after not being used for a while, or... something else I haven't thought of?
 
Last edited:
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Good question.

I thought the double-whammy scan-with-screen-off issue was with Android 9 (which I don't have - two devices I bought last month, one is 7.0 and the other is 5.1.1) and that we were trying to do a filtered scan because that was a (new) requirement for BLE scans done in-the-background / with-screen-off, and you were at a point where filtered scans weren't working at all:


Anyway, to simply answer your question (rather than sound like I'm dodging it ;-) it's: no, I have not successfully done a background UUID-filtered scan, even with the screen off.

But bear in mind that's because: no, I have not tried to do a background UUID-filtered scan, with the screen off.

I'll give that a go tomorrow (I mean: today) (if I wake up...) When we're talking "background" and "with the screen off", is that like: screen off by pressing the sleep button, or by the display timing out ie backlight off, or the device locking after not being used for a while, or... something else I haven't thought of?
Talk tomorrow I am sure :)
 
Upvote 0

OliverA

Expert
Licensed User
Did I not read some where that if there was a foreground service that other service would inherit these properties
Would a Manifest entry apply in case of Android 9 and Foreground services? See https://www.b4x.com/android/forum/threads/firebase-cloud-messaging-manifest-important.103403/
Please note, as to FCM and this issue, there seems to be a debate about the necessity of the Manifest entry: https://www.b4x.com/android/forum/threads/android-9-and-firebase-messaging.103402/#post-648023
 
Upvote 0

emexes

Expert
Licensed User
I am back on to answering your just-to-be-clear question. So far, I have banged out a minimal app that counts received ads from a particular device, and what I do is:

- stop app (if still running from previous test)
- make sure Bluetooth device (iTag) is off
- start app
- wait 10 seconds to make absolutely certain it's not receiving any ads from that device
- put Android device to sleep by either:
(i) wait for display "Sleep, After 30 seconds of inactivity" timeout, or
(ii) press the sleep/power button
- wait another 10 seconds
- turn on the Bluetooth device
- wait another 10 seconds
- press the button on the Bluetooth device (which will emit an extra bunch of ads)
- wait another 10 seconds
- turn off the Bluetooth device
- wait another 10 seconds
- wake up Android device by pressing sleep/power button, then have to swipe up
- confirm that it has counted a bunch of ads and picked up the name and id of that device

This is all being done on the $14.50 cheapie I bought today: ZTE Blade B112 aka Zume 5 running Android 6.0

I am about to try using BLE2 Scan2 with a filter.

Ah, and so far, this has all been done with bridge logging and wifi on, so I'll be having to repeat it all with those off, to be sure, to be sure.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Upvote 0

emexes

Expert
Licensed User
Righto, I have done all 8 combinations of:

- b4bridge and wifi: active or not active
- sleep method: display sleep timeout, or press sleep/power button
- scan2 filter: null, or single UUID per ScanFilter.Add("0000ffe0-0000-1000-8000-00805f9b34fb")

on a: ZTE Blade B112 aka Zume 5 running Android 6.0

and the scan picked up ads whilst the screen was black, every time.

Just to be clear, have you successfully done a background UUID filtered scan, even with the screen off ?

Still a good question, and now the answer is yes.

But I don't have Andr... hang on a sec... nope, false hope: I have a month-old (or month-new?) Samsung SM-960F aka Note 9 here too, but it is Android 8.1.0

As I understand it, the background-scanning-needs-UUID-filter issue began with Android 9.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Righto, I have done all 8 combinations of:

- b4bridge and wifi: active or not active
- sleep method: display sleep timeout, or press sleep/power button
- scan2 filter: null, or single UUID per ScanFilter.Add("0000ffe0-0000-1000-8000-00805f9b34fb")

on a: ZTE Blade B112 aka Zume 5 running Android 6.0

and the scan picked up ads whilst the screen was black, every time.



Still a good question, and now the answer is yes.

But I don't have Andr... hang on a sec... nope, false hope: I have a month-old (or month-new?) Samsung SM-960F aka Note 9 here too, but it is Android 8.1.0

As I understand it, the background-scanning-needs-UUID-filter issue began with Android 9.


Excellent work, Yes the issue in on 9.0, my understanding is that UUID filter must be a service filter, and I stand corrected if I am wrong. Need food, talk later :)
 
Upvote 0

emexes

Expert
Licensed User
Btw, those pink and green iTags are definitely different, even though they look identical:

- the pcb board visible under the battery connector is different
- the green ones advertise at ~3/sec, the pink ones at ~1/sec
- the green ones emit extra ads, and faster, when the button is pressed, the pink ones dgaf
- the ad data must be different, because the pink ones don't show up when the scan filter uuid is used

so I'll have a bit of an explore there out of interest, but spare you the results. If you do get similar devices and want to compare them, let me know.
 
Upvote 0

emexes

Expert
Licensed User
So all you need is for your device to include a service uuid in their ad. How hard can that be ?!?! Like, every other device can do it - I've never seen that nRF Connect screen come up empty before.

If you can connect to the device using nRF Connect, maybe you could ask the manufacturer how to make the device include a service uuid in the ad, like apparently every other BLE device does. Probability of success perhaps 3%, but that's still infinitely times larger than 0.

;-)
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
So all you need is for your device to include a service uuid in their ad. How hard can that be ?!?! Like, every other device can do it - I've never seen that nRF Connect screen come up empty before.

If you can connect to the device using nRF Connect, maybe you could ask the manufacturer how to make the device include a service uuid in the ad, like apparently every other BLE device does. Probability of success perhaps 3%, but that's still infinitely times larger than 0.

;-)

The device has 2 MAC address's. In nRF connection you can connect to one of the MAC's and see the same stuff you saw on your device. When you try to filter on it you get nothing.

We are looking at making our own device, which we have done before using classic bluetooth.
 
Upvote 0
Top