Android BLE在屏幕关闭时进行扫描(使用Galaxy)

huangapple go评论69阅读模式
英文:

Android BLE scan with screen off (with Galaxy)

问题

我使用 Galaxy S10,android 10 进行工作。从这里了解到,在三星设备上进行BLE扫描需要设置非空的扫描过滤器以在屏幕关闭状态下进行扫描。

以下是我的AdvertiseData和ScanFilter代码。

ParcelUuid aaUuid = ParcelUuid.fromString("0000aa11-0000-1000-8000-00805F9B34FB");

AdvertiseData advertiseData = new AdvertiseData.Builder()
                .setIncludeDeviceName(true) 
                .addServiceUuid(aaUuid)
                .build();

ScanFilter scanFilter = new ScanFilter.Builder()
                .setServiceUuid(aaUuid)
                .build();

在屏幕开启时,它可以正常工作。然而,在屏幕关闭时,它也无法正常工作。

我设置了10次扫描来检查这个问题。一开始,屏幕开启时,它可以正常工作。但当屏幕关闭时,第一次扫描可以正常工作,但下一次扫描结果不会出现,它只会开始下一次扫描过程(没有结果)。

每次扫描重复使用'WakeLock'都会得到相同的结果。如何解决这个问题?


添加1. 我使用WorkManager来处理后台进程。然后我正在寻找另一种方法。

添加2. 以下是我的扫描回调代码。

private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            if (result.getDevice().getName() != null)
                setBleScanResult(result);
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            Log.d("LOG_BLESCANNING_onScanFailed", "错误代码 : " + errorCode);
        }
    };

添加3. 屏幕关闭时的日志如下

...
D/Worker: ============ 蓝牙扫描开始 ============
D/LOG_BluetoothScan: 蓝牙扫描成功启动
D/BluetoothAdapter: isLeEnabled(): 开启
D/BluetoothLeScanner: onScannerRegistered() - 状态=0 scannerId=4 mScannerId=0
D/BluetoothAdapter: isLeEnabled(): 开启
D/LOG_BluetoothScan: 蓝牙扫描停止
...

屏幕开启时的日志如下

D/Worker: ============ 蓝牙扫描开始 ============
D/LOG_BluetoothScan: 蓝牙扫描成功启动
D/BluetoothAdapter: isLeEnabled(): 开启
D/BluetoothLeScanner: onScannerRegistered() - 状态=0 scannerId=4 mScannerId=0
D/LOG_BluetoothScan: W S10 | [00001111-0000-1000-8000-00805f9b34fb] | 55:40:DE:86:D0:03
D/LOG_BluetoothScan: W S10 | [00001111-0000-1000-8000-00805f9b34fb] | 55:40:DE:86:D0:03
D/LOG_BluetoothScan: W S10 | [00001111-0000-1000-8000-00805f9b34fb] | 55:40:DE:86:D0:03
D/LOG_BluetoothScan: W S10 | [00001111-0000-1000-8000-00805f9b34fb] | 55:40:DE:86:D0:03
D/BluetoothAdapter: isLeEnabled(): 开启
D/LOG_BluetoothScan: 蓝牙扫描停止

添加4. 我好奇的是'为什么这个问题只出现在BLE扫描中?' 我检查了屏幕关闭状态下的BLE广告没有任何问题。


添加5. 广告也有问题...但这不是必要的。我认为MainActivity - Worker(来自WorkManager)之间的连接对控制这种情况不好。

英文:

Im working with Galaxy S10, android 10. From here, BLE scan with Samsung devices need non-empty scan filter to scan in screen-off state.

Below is my AdvertiseData and ScanFilter code.

ParcelUuid aaUuid = ParcelUuid.fromString(&quot;0000aa11-0000-1000-8000-00805F9B34FB&quot;);

AdvertiseData advertiseData = new AdvertiseData.Builder()
                .setIncludeDeviceName(true) 
                .addServiceUuid(aaUuid)
                .build();

ScanFilter scanFilter = new ScanFilter.Builder()
                .setServiceUuid(aaUuid)
                .build();

With screen on, it works well. However, with screen off, it doesn't work too.

I set 10 times scanning to check this. At first, screen on, it works well. When it became screen-off, the first scan works good. But next scan result does not appear and it just start next scanning process (without result).

'WakeLock' for each scanning repetition makes same result. How to solve this problem?


Add 1. I used WorkManager to handle background process. Then I was looking for another method.

Add 2. Below is my scancallback code.

private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            if (result.getDevice().getName() != null)
                setBleScanResult(result);
        }

        @Override
        public void onBatchScanResults(List&lt;ScanResult&gt; results) {
            super.onBatchScanResults(results);
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            Log.d(&quot;LOG_BLESCANNING_onScanFailed&quot;, &quot;Error Code : &quot; + errorCode);
        }
    };

Add 3. Below is my log when screen off

...
D/Worker: ============ Bluetooth Scanning start ============
D/LOG_BluetoothScan: Bluetooth scanning started successfully
D/BluetoothAdapter: isLeEnabled(): ON
D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=4 mScannerId=0
D/BluetoothAdapter: isLeEnabled(): ON
D/LOG_BluetoothScan: Bluetooth scanning stopped
...

and screen on

D/Worker: ============ Bluetooth Scanning start ============
D/LOG_BluetoothScan: Bluetooth scanning started successfully
D/BluetoothAdapter: isLeEnabled(): ON
D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=4 mScannerId=0
D/LOG_BluetoothScan: W S10 | [00001111-0000-1000-8000-00805f9b34fb] | 55:40:DE:86:D0:03
D/LOG_BluetoothScan: W S10 | [00001111-0000-1000-8000-00805f9b34fb] | 55:40:DE:86:D0:03
D/LOG_BluetoothScan: W S10 | [00001111-0000-1000-8000-00805f9b34fb] | 55:40:DE:86:D0:03
D/LOG_BluetoothScan: W S10 | [00001111-0000-1000-8000-00805f9b34fb] | 55:40:DE:86:D0:03
D/BluetoothAdapter: isLeEnabled(): ON
D/LOG_BluetoothScan: Bluetooth scanning stopped

Add 4. I'm curious about 'Why is this problem only in the ble scanning?' I check ble advertising in screen off state does not have any problem.


Add 5. Advertising also has problem... but it is not essential. I think MainActivity - Worker (from WorkManager) connection is bad to control this situation.

答案1

得分: 1

这是我解决问题的方法:

  1. 使用'ForegroundService'
  • 我没有检查WorkManager是否可用,但ForegroundService运行良好。我使用定时器和定时任务在前台重复执行进程。
  1. 授予权限"始终允许"
  • 这是主要问题。Doze模式不允许我的应用使用GPS。因此,我打开了GPS设置,并将我的应用权限从仅在使用应用时允许更改为始终允许。
英文:

This is how I solve the problem

  1. Use 'ForegroundService'
  • I didnt check whether workmanager is available or not, but ForegroundService works well. I use timer and timertask to repeat the process in foreground.
  1. Grant permission "Allowed all the time"
  • It was the main issue. Doze mode do not allow my app to use GPS. So I open the GPS setting and set my app's permission from allow when using app to allow all the time.

答案2

得分: 0

这是我的工作代码 - 即使设备屏幕被锁定。

更新:

感谢您提到您使用了**"WorkerManager"。之后才浮现在我的脑海中。自从Android 8以来,谷歌引入了电池优化功能,比如Doze模式。因此,在睡眠(Doze模式)期间,它不允许服务在后台运行。所以,您可以使用"前台服务"**而不是Worker或Jobscheduler等。

请查看此链接:
https://developer.android.com/training/monitoring-device-state/doze-standby

我也曾在2年前遇到过这个问题。在切换到**"前台服务"**之后,它可以正常工作。

旧(与BLE扫描有关的初始化)
请检查您的代码。这很简单。期待您的回应。

1. 初始化扫描过滤器

btLeScanFilters = new ArrayList<ScanFilter>();
ScanFilter scanFilter = new ScanFilter.Builder()
        .setServiceUuid(new ParcelUuid("........ uuid reference ......"))
        .build();
btLeScanFilters.add(scanFilter);

2. 初始化扫描设置

btLeScanSettings = new ScanSettings.Builder().
        setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();

3. 初始化扫描回调

private ScanCallback leScanCallback = new ScanCallback() {

    @Override
    public void onScanResult(int callbackType,
                             final ScanResult result){

        new TPMSAsyncTask().execute(result);
    }
}

4. 开始扫描

btLeScanner.startScan(btLeScanFilters, 
           btLeScanSettings,
           leScanCallback);
英文:

this is my working code - even device screen is locked.

UPDATE:

thank u for mentioned that you have used "WorkerManager". After that only striked in my mind. Since android 8, google introduced battery optimizations such as Doze mode. So, it doesn't allow the service to be run in background during Sleep(Doze mode). So, you can do the BLE Scanning **

> using "Foreground Service"

** instead of Worker or Jobscheduler, etc.

please view this link:
https://developer.android.com/training/monitoring-device-state/doze-standby

I also, struggled at this stage 2years ago. After switched to "Forgreound Service" it is working

OLD ( Initialization Regarding - BLE Scan)
kindly check with your code. This is simple. Awaiting for your response.

1. Initialize scanfilter

    btLeScanFilters = new ArrayList&lt;ScanFilter&gt;();
    ScanFilter scanFilter = new ScanFilter.Builder()
            .setServiceUuid(new ParcelUuid(&quot;........ uuid reference ......&quot;))
            .build();
    btLeScanFilters.add(scanFilter);

2. Initialize scan settings

    btLeScanSettings = new ScanSettings.Builder().

setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();

3. Initialize scan callback

   private ScanCallback leScanCallback = new ScanCallback() {

    @Override
    public void onScanResult(int callbackType,
                             final ScanResult result){

        new TPMSAsyncTask().execute(result);
    }
   }

4. start scanning

    btLeScanner.startScan(btLeScanFilters, 
               btLeScanSettings,
               leScanCallback);

huangapple
  • 本文由 发表于 2020年8月6日 20:11:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/63283352.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定