androidiosibeaconaltbeaconandroid-ibeacon

iOS CLLocationManager Not Detecting Android Beacon Library iBeacon Signal Sent From Android


App Purpose

  1. Transmit a Beacon signal from iOS and detect that signal on Android & iOS Devices.
  2. Transmit a Beacon signal from Android and detect that signal on Android & iOS Devices.

Technologies

Android: Android Beacon Library.

iOS: CoreLocation CLLocationManager iBeacon.

The Problem

    locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion)

Using the same UUID to transmit an iBeacon signal from Android using the Android Beacon Library, the beacon is not detected by the above CLLocationManager delegate method on iOS.

The Code

    func startRangingBeacons(satisfying constraint: CLBeaconIdentityConstraint)

Detecting on iOS

    var locationManager: CLLocationManager!
    var localBeaconUUID = "578f4eba-a16e-11ea-bb37-0242ac130002"
    let beaconIdentifier = "MyBeacon"

    override func viewDidLoad() {
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
   }

    func startScanning() {
        let uuid = UUID(uuidString: localBeaconUUID)!
        let beaconRegion = CLBeaconRegion(uuid: uuid, identifier: beaconIdentifier)
        locationManager.startMonitoring(for: beaconRegion)
        locationManager.startRangingBeacons(in: beaconRegion)
    }

    func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
        print("Ranged beacons: \(beacons.count)")
    }

Transmitting iBeacon on Android

    private val uuid = "578f4eba-a16e-11ea-bb37-0242ac130002"

    fun transmitBeacon() {
        val beacon = Beacon.Builder()
                .setId1(uuid)
                .setId2("1")
                .setId3("1")
                .setManufacturer(0x004c)
                .setTxPower(-59)
                .setDataFields(listOf(0L))
                .build()
        val beaconParser = BeaconParser()
                .setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24")
        val beaconTransmitter = BeaconTransmitter(applicationContext, beaconParser)
        beaconTransmitter.startAdvertising(beacon)
    }

Solution

  • The layout shown here:

    val beaconParser = BeaconParser()
                    .setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24")
    

    is for AltBeacon, which iOS devices cannot detect via CoreBluetooth. You can only use that iOS API to detect iBeacon, which has this layout:

    val beaconParser = BeaconParser()
                    .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")
    

    In an earlier answer in another forum, I noted that the OP was using a layout with a data field added and suggested he remove it, but did not realize the more fundamental issue that that the layout in the question uses the matching bytes beac which only works for AltBeacon format. For iBeacon, you must match on 0215