Skip to content Skip to sidebar Skip to footer

Ble: Send Advertise Data To Ios From Android

I have to send some advertise data via ble to an iOS central app. On Android peripheral side, when i create advertise i do: var byteArrayData = dataToSend.toByteArray(Charsets.

Solution 1:

iOS is very restrictive regarding advertisement data. Both when sending and receiving it, you can only control a small subset of it. Most of it is controlled by iOS itself and — in case of the central manager role — not even forwarded to the app.

The exceptions are the Advertisement Data Retrieval Keys, applicable for the advertisementData parameter of centralManager(_:didDiscover:advertisementData:rssi:).

A more specific example is mentioned in this answer.

Update

Even though one of the keys is for service data, I don't think the data is forwarded to the app. But I might be wrong. I guess you are asking this question because the key CBAdvertisementDataServiceDataKey is not set.

Update 2

I've created a minimal Android and iOS example and got it working without any problem. I don't see no obvious problem in your Android code. So you will need to talk to your iOS colleague...

The service data is "ABC" (or 61 62 63 in hex) and the 16-bit UUID is FF01. The iOS log output is:

2019-09-05 16:39:18.987142+0200BleScanner[18568:3982403] [Scanner] Advertisement data: FF01:<616263>

Android - MainActivity.kt

package bleadvertiser

import android.bluetooth.BluetoothManager
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

classMainActivity : AppCompatActivity() {

    privatevar peripheral: Peripheral? = nulloverridefunonCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    overridefunonStart() {
        super.onStart()
        val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        peripheral = Peripheral(bluetoothManager.adapter)
        peripheral?.startAdvertising()
    }
}

Android - Peripheral.kt

package bleadvertiser

import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.AdvertiseCallback
import android.bluetooth.le.AdvertiseData
import android.bluetooth.le.AdvertiseSettings
import android.os.ParcelUuid
import android.util.Log
import java.util.*

privateconstval TAG = "Peripheral"classPeripheral(privateval bluetoothAdapter: BluetoothAdapter) {

    funstartAdvertising() {
        val advertiseSettings = AdvertiseSettings.Builder().build()
        val serviceData = "abc".toByteArray(Charsets.UTF_8)
        val advertiseData = AdvertiseData.Builder()
            .addServiceData(ParcelUuid(SERVICE_UUID), serviceData)
            .build()
        val advertiser = bluetoothAdapter.bluetoothLeAdvertiser
        advertiser.startAdvertising(advertiseSettings, advertiseData, advertiseCallback)
    }

    privateval advertiseCallback = object: AdvertiseCallback() {
        overridefunonStartFailure(errorCode: Int) {
            Log.w(TAG, String.format("Advertisement failure (code %d)", errorCode))
        }
        overridefunonStartSuccess(settingsInEffect: AdvertiseSettings?) {
            Log.i(TAG, "Advertisement started")
        }
    }

    companionobject {
        val SERVICE_UUID: UUID = UUID.fromString("0000ff01-0000-1000-8000-00805F9B34FB")
    }
}

iOS - ViewController.swift

import UIKit

classViewController: UIViewController {

    var bleScanner: BleScanner?

    overridefuncviewDidLoad() {
        super.viewDidLoad()
        bleScanner =BleScanner()
    }
}

iOS - BleScanner.swift

import Foundation
import CoreBluetooth
import os.log

classBleScanner : NSObject {

    staticlet serviceUUID =CBUUID(string: "FF01")
    staticlet log =OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Scanner")

    privatevar centralManager: CBCentralManager!
    privatevar scanningTimer: Timer?

    overrideinit() {
        super.init()
        centralManager =CBCentralManager(delegate: self, queue: nil)
    }

    funcstartScanning() {
        scanningTimer =Timer.scheduledTimer(withTimeInterval: TimeInterval(20), repeats: false, block: { (_) inself.stopScanning()
        })
        centralManager.scanForPeripherals(withServices: [ BleScanner.serviceUUID ], options: nil)
    }

    funcstopScanning() {
        centralManager.stopScan()
    }
}

extensionBleScanner : CBCentralManagerDelegate {

    funccentralManagerDidUpdateState(_central: CBCentralManager) {
        if centralManager.state == .poweredOn {
            startScanning()
        }
    }

    funccentralManager(_central: CBCentralManager, didDiscoverperipheral: CBPeripheral, advertisementData: [String : Any], rssiRSSI: NSNumber) {
        for (key, value) in advertisementData {
            if key ==CBAdvertisementDataServiceDataKey {
                let serviceData = value as! [CBUUID : NSData]
                for (uuid, data) in serviceData {
                    os_log("Advertisement data: %{public}s: %{public}s", log: BleScanner.log, type: .info, uuid.uuidString, data.debugDescription)
                }
            }
        }
    }
}

Post a Comment for "Ble: Send Advertise Data To Ios From Android"