在应用程序处于后台时使用蓝牙 LE

Posted

技术标签:

【中文标题】在应用程序处于后台时使用蓝牙 LE【英文标题】:Use Bloothtooth LE while app is in background 【发布时间】:2017-06-20 20:13:14 【问题描述】:

我正在使用 Xamarin 构建一个 ios 应用,使用这个 BLE 插件:

https://github.com/aritchie/bluetoothle

我只是通过 BLE 广播 UUID,它可以工作。这是我的代码:

var data = new Plugin.BluetoothLE.Server.AdvertisementData
            
                LocalName = "MyServer",
            ;

data.ServiceUuids.Add(new Guid("MY_UUID_HERE"));

await this.server.Start(data);

唯一的问题是,一旦我将应用程序置于后台,它就会停止广播。并在我再次打开应用程序时再次恢复。

如何让它在后台继续播放?我在这里阅读了文档:

https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html

它说我必须使用CBCentralManager 类来获得保存和恢复功能(这样我就可以一直广播 UUID),但我很难将它翻译成 Xamarin/C# .

编辑

在研究了更多之后,我读到我需要创建一个CBCentralManager 的实例并在委托中实现WillRestoreState。我在AppDelegate 中做到了这一点:

[Register("AppDelegate")]
public class AppDelegate : MvxApplicationDelegate, ICBCentralManagerDelegate

    private IGattServer server = CrossBleAdapter.Current.CreateGattServer();
    private CBCentralManager cbCentralManager;

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    
        // irrelevant code...

        this.Ble();

        return true;
    

    private async Task Ble()
    
        try
        
            await Task.Delay(5000); // wait for it to finish initializing so I can access BLE (it crashes otherwise)

            var options = new CBCentralInitOptions();
            options.RestoreIdentifier = "myRestoreIndentifier";
            this.cbCentralManager = new CBCentralManager(this,null,options);

            var data = new Plugin.BluetoothLE.Server.AdvertisementData
            
                LocalName = "MyServer",
            ;

            data.ServiceUuids.Add(new Guid("MY_UUID_HERE"));

            await this.server.Start(data);
        
        catch (Exception e)
        

        
    

    public void UpdatedState(CBCentralManager central)
    
        //throw new NotImplementedException();
    

    [Export("centralManager:willRestoreState:")]
    public void WillRestoreState(CBCentralManager central, NSDictionary dict)
    
        //never gets called
    

但这对我来说并没有什么不同。而且WillRestoreState 方法永远不会被调用...如果我必须在这一点上使用不同的插件/库,我不介意...

编辑 2

我刚刚意识到应用程序仍在后台广播,我只是不再看到服务 UUID(在我正在测试的信标的 Web 门户中),我只看到手机的标识符。

【问题讨论】:

据我了解,您不能只继续广播。您可以指定处于 2 种可能的模式 bluetooth-central 或 bluetooth-peripheral。您应该在 plist 中指定。 我链接的文档中有一个名为“状态保护和恢复”的部分说你可以。它引用:Because state preservation and restoration is built in to Core Bluetooth, your app can opt in to this feature to ask the system to preserve the state of your app’s central and peripheral managers and to continue performing certain Bluetooth-related tasks on their behalf, even when your app is no longer running. “代表他们继续执行某些与蓝牙相关的任务”什么任务?不仅仅是您想要的任何任务,而是取决于您所处的模式的某些任务,对吧? 应用可以声明两种核心蓝牙后台执行模式——一种用于实现中心角色的应用,另一种用于实现外围角色的应用。如果您的应用程序实现了这两种角色,它可能会声明它支持两种后台执行模式。通过将 UIBackgroundModes 键添加到 Info.plist 文件并将键的值设置为包含以下字符串之一的数组来声明核心蓝牙后台执行模式:bluetooth-central bluetooth-peripheral 广告服务的 UUID 是您可以使用 BLE 做的最简单的事情......它还引用了一个示例:Some apps may need to use the Core Bluetooth framework to perform long-term actions in the background. As an example, imagine you are developing a home security app for an iOS device that communicates with a door lock (equipped with Bluetooth low energy technology). The app and the lock interact to automatically lock the door when the user leaves home and unlock the door when the user returns—all while the app is in the background. 【参考方案1】:

经过大量研究,我发现这只是一个 iOS 限制——当你的应用在后台时,你不能广播 BLE 服务的 UUID。 iOS 中的后台工作非常严格。

编辑以包含 Paulw11 评论(这是真的): 您可以宣传一项服务,但其宣传方式只有专门扫描该服务 UUID 的另一台 iOS 设备才能看到。

【讨论】:

好吧,您可以宣传一项服务,但宣传的方式只有另一台专门扫描该服务 uuid 的 iOS 设备才能看到。【参考方案2】:

虽然当你的 iOS 应用程序在后台时你不能广播 BLE 服务的 UUID,但对于任何试图做类似事情的人,你应该看看 iBeacon。这是 Apple 让 iOS 应用在后台执行蓝牙功能的协议。

【讨论】:

以上是关于在应用程序处于后台时使用蓝牙 LE的主要内容,如果未能解决你的问题,请参考以下文章

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

如何永远在后台运行需要蓝牙的应用程序?

是否可以/允许使用 iOS 作为蓝牙设备和云之间的网关(当应用程序在后台时)

应用程序在后台崩溃,而蓝牙连接长时间丢失

开启蓝牙 4.0 LE+经典(双模)

蓝牙 LE iOS 无法在后台扫描