Cordova:在后台模式下扫描 iBeacons / BLE(iOS 和 Android)

Posted

技术标签:

【中文标题】Cordova:在后台模式下扫描 iBeacons / BLE(iOS 和 Android)【英文标题】:Cordova: Scan for iBeacons / BLE in background mode (iOS and Android) 【发布时间】:2015-12-18 06:24:07 【问题描述】:

我已经实现了一个 cordova/ionic 应用程序(ios/android 的混合),它在后台模式下扫描 iBeacons 并在找到信标时通知用户。我正在使用以下插件:

iBeacon 扫描:cordova-plugin-ibeacon by petermetz 后台模式: cordova-plugin-background-mode by katzer 通知:cordova-plugin-local-notifications by katzer

到目前为止效果很好(在 iOS 和 Android 上)。这里的问题是,Apple 会拒绝将我的 App 表单发布到 App Store(请参阅https://github.com/katzer/cordova-plugin-background-mode/issues/77)。 另一个问题是,后台信标扫描似乎消耗了非常多的电池容量。有了这个后台插件,整个应用程序就在后台运行,而不仅仅是一个特定的功能/服务。

你们中是否有人知道是否有一个用于在后台运行任务的插件(或者更具体地说:在后台扫描 iBeacons),它适用于 iOS 和 Android 并且会被 App Store 接受?我还没有找到。如果没有这样的插件,您认为一般可以开发这样的插件吗?据我所知,后台服务可用于 Android 和 iOS(本机)。

谢谢!

【问题讨论】:

嗨,我正在做和你一样的项目。但我绊倒在墙上。你是如何让信标在后台被检测到的?因为当我最小化应用程序时。在区域外检测到所有信标。如果您能给我一些指点,那就太好了。 【参考方案1】:

对于 iOS,这并不是 Cordova 特有的问题。如果没有特殊权限(需要额外的障碍才能在 AppStore 中获得批准),Apple 不允许在后台对信标进行一次超过几分钟的测距(扫描)。为了在 AppStore 中通过持续的后台扫描信标获得批准,您必须让 Apple 相信您的应用程序是导航应用程序。 Read more here.

至于电池使用情况,是的,信标的恒定范围确实会显着消耗电池电量。这就是为什么 Apple 通常不允许应用在后台执行此操作的原因。另一种方法是使用信标监控 API 而不是信标测距 API。监控 API 会在信标出现或消失时提醒您,并使用硬件辅助或仅定期蓝牙扫描来节省电池电量。

在后台处理方面有特定的 Cordova 复杂性(主要是由于需要激活 WebView 来处理回调),但如果您计划部署到 AppStore,则必须首先解决更基本的问题以上。

【讨论】:

【参考方案2】:

我也面临同样的问题。我不是本地应用程序开发人员,但我知道结合所有这三个插件你会得到想要的结果。

我的概念是在应用程序后台模式下信标从该区域移动时通知移动设备。

-奈蒂克

【讨论】:

【参考方案3】:

抱歉延迟回复。几个月前我遇到了同样的问题,但没有找到答案:(,我只是愿意分享我的发现

您可以使用cordova 插件只担心android 设备。对于 iOS,您可以使用信标监控 api。

你只需要在xCode上导入cordoba项目

您会在项目中找到一个名为 AppDelegate.swift 的文件 在类初始化之前放这个

import CoreLocation

在类初始化之后,你需要像这样放置变量

class AppDelegate: UIResponder, UIApplicationDelegate 
    var beaconManager:CLLocationManager!
    var region:CLBeaconRegion!

现在按 command + N 或转到文件 > 新建 > 文件

创建一个新的 swift 文件,点击下一步并给它命名

用这个改变文件内容

import Foundation
import CoreLocation
import UserNotifications

extension AppDelegate:CLLocationManagerDelegate
//here we will initialize our beacon monitoring manager, 
//we will call this function later on the AppDelegate Main class
func initBeaconManager()
    //remember whe have defined our locationManager and region variable on AppDelegate Main Class
    locationManager: CLLocationManager = CLLocationManager()
    locationManager.delegate = self

    //you will need to change these variables according to your becon configuration
    let uuid = UUID(uuidString: "CHANGE ME YOUR BEACON UUID IF YOU DONT CHANGE IT IT WILL CRASH")!
    let major = 123 //beacon major
    let minor = 012 // beacon minor
    let identifier = "some indentifier of your region that you like"

    //you can define your region with just the uuid that way if you have more that one beacon it will work with just one region
    //uncomment below if that´s the case
    //let region = CLBeaconRegion(proximityUUID: uuid, identifier: identifier)

    //in this case we will be ussing all variables major minor and uuid
    region = CLBeaconRegion(proximityUUID: uuid, major: CLBeaconMajorValue(major), minor: CLBeaconMinorValue(minor), identifier: identifier)

    //great now that we have defined our region we will start monitoring on that region
    //first of all we make sure we have the correct permissions
    let authorization = CLLocationManager.authorizationStatus()
    switch authorization 
    case .notDetermined:
        //in case it is not authorized yet we will ask here for authorization
        //the key is to request always authorization that way the enter and exit region callbacks will be called even if the app is killed or the phone restarted
        locationManager.requestAlwaysAuthorization()
        //after requesting for ahtorization we will get the authorization changed callback, there will be starting monitoring our region
    case .denied, .restricted ,.authorizedWhenInUse:
        //the user has denied the authorization we can make the user go to settings and enable it again 
        //but you can do that also ussing cordoba so... I just put in this case switch to commit that :D
        break
    case .authorizedAlways:
        //we are goot to go now we can start monitoring
        locationManager.startMonitoring(for: region)
    


    if let uuid = UUID(uuidString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D") 
        let beaconRegion = CLBeaconRegion(
            proximityUUID: uuid,
            major: 100,
            minor: 50,
            identifier: "iBeacon")
        locationManager.startMonitoring(for: beaconRegion)
    



//LOCATOIN MANAGER EXIT AND ENTER REGION
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) 
    //notification when enter
    let notificationTitle = "CHANGE ME"
    let notificationBody = "CHANGE ME ENTER REGION"
    sendNotification(title: notificationTitle, body: notificationBody)

func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) 
    //notification when leave 
    let notificationTitle = "CHANGE ME"
    let notificationBody = "CHANGE ME EXIT REGION"
    sendNotification(title: notificationTitle, body: notificationBody)




//Simple notification with only a custom title and body
func sendNotification(title:String,body:String)
    if #available(iOS 10.0, *) 
        let content = UNMutableNotificationContent()
        content.title = title
        content.body = body
        content.sound = UNNotificationSound.default()
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false)
        let request = UNNotificationRequest(identifier: "enterNotification", content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request, withCompletionHandler:  (error) in
            // Handle error
        )
     else 
        let notification = UILocalNotification()
        if #available(iOS 8.2, *) 
            notification.alertTitle = title
        
        notification.alertBody = body
        notification.soundName = UILocalNotificationDefaultSoundName
        UIApplication.shared.presentLocalNotificationNow(notification)
    



在文件注释上可以找到需要修改的地方

现在返回 AppDelegate 文件并将其放入函数中

func application(_ application: UIApplication, didFinishLaunchingWithOptions ....

这将初始化您在扩展上编写的所有功能

self.initBeaconManager()

【讨论】:

以上是关于Cordova:在后台模式下扫描 iBeacons / BLE(iOS 和 Android)的主要内容,如果未能解决你的问题,请参考以下文章

后台模式下的 iBeacon 访问

PhoneGap BLE 插件在后台不起作用

IOS:手机锁定时iBeacon扫描频率?

我们可以在后台启动一个 iBeacon 发射器吗?

iBeacon 监控不适用于 Cordova-plugin-ibeacon

在后台使用 iBeacon 或 CoreBluetooth 识别 iOS 设备