当应用程序在后台时扫描外围设备(例如,当屏幕锁定时)

Posted

技术标签:

【中文标题】当应用程序在后台时扫描外围设备(例如,当屏幕锁定时)【英文标题】:Scan peripheral when app in background (ex. when screen locked) 【发布时间】:2020-05-07 19:58:19 【问题描述】:

我有一个在后台运行的应用程序。我使用 CBPeripheralManager 来做广告和 CBCentralManager 来扫描。我使用两个 ıos(ios 11.3 和 IOS 13.4.1)设备。第一个是广告前景和背景。第二个是扫描前景和背景。我可以扫描;

后台应用,手机已解锁 - 完美运行

应用在后台,手机被锁定,屏幕被点亮 - 完美运行

应用在后台,手机锁定,屏幕关闭 - 无法正常工作!

/* 我检查它在 android 设备中运行后台显示的广告应用 */

有什么问题。请告诉我。如何解决这个问题?我想在后台扫描两者。我的代码如下所示;

let scanOptions = [
        CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: true)
    ]

let services = [CBUUID(string: "e2c56db5-dffb-48d2-b060-d0f5a71096e0")]

let advertisingData = [
        CBAdvertisementDataLocalNameKey: "xxx",
        CBAdvertisementDataServiceUUIDsKey:[CBUUID(string: "e2c56db5-dffb-48d2-b060-d0f5a71096e0")]
        ] as [String : Any]

func initLocal() 

        peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
        cbCentralManager = CBCentralManager(delegate: self, queue: nil,options: nil)

    

func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) 

        if peripheral.state == .poweredOn 
            peripheralManager.startAdvertising(advertisingData)
        
       else if peripheral.state == .poweredOff 
            peripheralManager.stopAdvertising()
        
    

func centralManagerDidUpdateState(_ central: CBCentralManager) 

        if central.state == .poweredOn

            central.scanForPeripherals(withServices: services,options:scanOptions)
            print("scanning...")

        
        else 
            print("Bluetooth is not active")
        
    

func centralManager(_ central: CBCentralManager,didDiscover peripheral: CBPeripheral,advertisementData: [String : Any],
                        rssi RSSI: NSNumber)
    

        print("RSSI   : \(RSSI)")

    

这是我的 info.plist;

【问题讨论】:

【参考方案1】:

因为您设置了CBCentralManagerScanOptionAllowDuplicatesKey,您似乎期待重复。该键在后台被忽略。如果您希望通过广告多次看到同一设备,那是不可能的。但是,发现您以前从未见过的新设备应该可以工作。你有麻烦吗? (你应该详细解释你是如何测试这个的,你看到了什么精确的行为,你期望看到什么。蓝牙非常微妙。细节很重要,“不工作”太模糊了。 )

【讨论】:

谢谢。我希望通过广告多次看到同一设备,例如前台应用程序。你说那不可能。对?也许这是一个非常不同的问题,但是如何计算设备在特定时间处于后台时的距离。 正确;这不可能。在前景中计算距离是非常不可能的,而在背景中则完全不可能。您可以在前景中使用 RSSI 获得非常粗略的距离概念,但是有很多警告,它几乎没有用(墙壁、反射、设备的方向、通过巨型微波吸收水袋的信号-称为人)。但在广告的背景下,这一切都是不可能的。 这个一般问题是不可能的,但是对于某些子集它是可构建的(我在那个领域做了各种工作)。真正的目标是什么?只要它不是接触者追踪应用之类的东西,它可能是可以解决的。 谢谢。我知道。该应用程序的目的是通过使用蓝牙信号和可在两个不同设备上运行的后台应用程序来计算设备之间的大致距离。 如果只是两个设备(或任何少量已知设备),您可能希望使用连接而不是广告。设备可以在后台非常可靠地连接到已知设备,并且可以通过交换数据相互唤醒。 RSSI 不可靠,但可用,当与 CoreLocation 的一些增强相结合时,可能会满足需要。

以上是关于当应用程序在后台时扫描外围设备(例如,当屏幕锁定时)的主要内容,如果未能解决你的问题,请参考以下文章

当后台应用程序扫描蓝牙连接的外围设备时

Swift 3:如何在后台扫描外围设备?

应用程序暂停时如何在 iPhone 上获取屏幕锁定/解锁事件?

iOS - 当应用程序在后台时取消蓝牙连接

BLE外围设备断开

从后台服务打开应用程序屏幕并锁定手机屏幕时冻结