使用CoreBluetooth在iOS上更改间隔时间读取信标RSSI

时间:2015-12-09 09:40:45

标签: ios swift bluetooth core-bluetooth ibeacon

我试图比每秒一次读取信标(estimote)的RSSI更多。我知道使用Core Location nd方法locationManager (manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon] inRegion region: CLBeaconRegion)是不可能的。

我找到了使用Core Bluetooth的建议。我的实现如下:

class Bluetooth : NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
    var manager: CBCentralManager!
    lazy var peripherals = [NSUUID:CBPeripheral]()


    static let sharedInstance = Bluetooth()

    private override init() {
        super.init()
        manager = CBCentralManager()
        manager.delegate = self
    }

    func centralManagerDidUpdateState(central: CBCentralManager) {
        switch(central.state) {
            case .PoweredOn:
                print("powered on")
                manager.scanForPeripheralsWithServices(nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(bool: true)])
                break
            default:
                print("Unknown status")
        }
    }

    func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {   
        //fot testo only one becon
        if(peripheral.name == "EST" && peripherals.count == 0) {            
            manager.connectPeripheral(peripheral, options: nil)         
            peripherals[peripheral.identifier] = peripheral
            peripherals[peripheral.identifier]?.delegate = self     
            manager.stopScan()
        }
    }

    func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
        print("Connect peripheral \(peripheral.name) \(peripheral.identifier)")
        peripheral.delegate = self
        peripheral.readRSSI()
    }

    func peripheral(peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: NSError?) {
        let currentTime = CACurrentMediaTime();
        print("\(currentTime) \(RSSI)")
        peripheral.readRSSI()
    }
}

我在信标上设置广告时间间隔为100毫秒,毕竟peripheral (peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: NSError?)似乎没有比每秒一次更多地调用。

有没有办法每100毫秒读一次RSSI?

额外的问题 - 在上面的代码方法peripheral (peripheral: CBPeripheral, didReadRSSI RSSI)中只运行了大约10次,然后停止。灯塔是否可能“挂断”,我需要与他重新联系?

我用于测试iPhone 6s以及iOS9。

1 个答案:

答案 0 :(得分:1)

两个提示:

  1. 配置您的信标,使其以10 Hz而非1Hz进行传输。每次检测到广告时,您只会收到CoreBluetooth回调。如果它每秒只发布一次广告,则通常只能获得RSSI读数。

  2. 删除调用FATAL EXCEPTION: main Process: com.forsale.forsale, PID: 9040 java.lang.VerifyError: com/google/android/gms/measurement/internal/zzt at com.google.android.gms.measurement.AppMeasurementContentProvider.onCreate(Unknown Source) at android.content.ContentProvider.attachInfo(ContentProvider.java:1656) at android.content.ContentProvider.attachInfo(ContentProvider.java:1627) at android.app.ActivityThread.installProvider(ActivityThread.java:4887) at android.app.ActivityThread.installContentProviders(ActivityThread.java:4474) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4411) at android.app.ActivityThread.access$1500(ActivityThread.java:142) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5118) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605) at dalvik.system.NativeStart.main(Native Method) 的代码。如果您连接到蓝牙LE设备,它将停止广告,您将无法再获得广告回调。

  3. 请注意,使用此技术无法保证您正在读取信标与附近任何其他蓝牙设备的RSSI值,因为CoreBluetooth不允许您读取信标标识符。因此,只有当一个蓝牙设备出现时,这才能可靠地工作。