Develop Wi-Fi, BLE, MQTT in iOS and iPadOS, Android, and Windows.
Everything could be connected. Everything shall be connected.
Compared to Classic Bluetooth, Bluetooth Low Energy or BLE is intended to provide considerably reduced power consumption and cost while maintaining a similar communication range. Mobile operating systems including iOS, Android and Windows Phone, as well as macOS, Linux, Windows 8 and Windows 10, natively support Bluetooth Low Energy.
BluetoothManager mBluetoothManager = getSystemService( Context.BLUETOOTH_SERVICE );
BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter( );
BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback(){};
// Start to Scan
mBluetoothAdapter.startLeScan( mLeScanCallback );
// Call back when Devices are found
mLeScanCallback. onLeScan ( BluetoothDevice device, int rssi , byte[] scanRecord ) {
// Saved in Array
mName[] = device.getName();
mAddress[] = device.getAddress();
mRSSI[] = rssi;
}
BluetoothLeService mBluetoothLeService;
ServiceConnection mServiceConnection =
new ServiceConnection() {};
Intent mGattServiceIntent =
new Intent( this, mBluetoothLeService.class );
bindService( mGattServiceIntent, mServiceConnection, BIN_AUTO_CREATE );
// Fire automatically
mServiceConnection.onServiceConnected ( ComponentName componentName, IBinder service ) {
mBluetoothLeService = service.getService();
mBluetoothLeService.initialize();
}
initialize() {
BluetoothManager nBluetoothManager =
getSystemService
( Context.BLUETOOTH_SERVICE );
BluetoothAdapter nBluetoothAdapter =
nBluetoothManager.getAdapter();
}
// Fire automatically
Ibinder nIBinder = new LocalBinder();
onBind( Intent intent ) {
return nIBinder;
}
LocalBinder( ) {
BluetoothLeService getService(){
return BluetoothLeServie.this
}
}
// Connect to 1st Device
mBluetoothLeService.connect( mAddress[0], 1);
// Connect to 2nd Device
mBluetoothLeService.connect( mAddress[1], 2);
…
// Each device has its own BLE GATT and BLE Service
BluetoothGatt[] nBluetoothGatt;
BluetoothGattCallback nBluetoothGattCallback = BluetoothGattCallback(){};
connect( String address, int n ) {
nAddress[n-1] = address;
BluetoothDevice device =
nBluetoothAdapter.getRemoteDevice( address );
nBluetoothGatt[n-1] =
device.connectGatt( Context this, Boolean
autoConnect false, BluetoothGattCallback
nBluetoothGattCallback);
}
// Fire automatically
nBluetoothGattCallback() {
onConnectionStateChange( BluetoothGatt gatt, int status, int newState ) {
if( status == BluetoothGatt.GATT_SUCCESS ) {
if ( newState == STATE_CONNECTED ) {
if( gatt.getDevice().getAddress() == naddress[0] )
{ nBluetoothGatt[0]. discoverServices(); }
if( gatt.getDevice().getAddress() == naddress[1] )
{ nBluetoothGatt[1]. discoverServices(); }
…
}
}
}
}
// Automatically Search for BLE Service and BLE Characteristics
…
// Each BLE Service has its own BLE Characteristics
BluetoothGattCharacteristic[] nNotifyCharacteristic;
BluetoothGattCharacteristic[] nWriteCharacteristic;
BluetoothGattCharacteristic[] nReadCharacteristic;
// Fire automatically
nBluetoothGattCallback() {
onServicesDiscovered( BluetoothGatt gatt, int status ) {
if ( status == BluetoothGatt.GATT_SUCCESS ) {
BluetoothGattService service =
BluetoothGatt.getService( UUID.fromString(XXXX) );
if ( service != null ) { // go on to get characteristic
if ( gatt.getDevice().getAddress() == nAddress[0] ) {
nNotifyCharacteristic[0] = service.getCharacteristic(UUID.fromString(XXXX));
nWriteCharacteristic[0] = service.getCharacteristic(UUID.fromString(XXXX));
nReadCharacteristic[0] = service.getCharacteristic(UUID.fromString(XXXX));
}
if ( gatt.getDevice().getAddress() == nAddress[1] ) {
nNotifyCharacteristic[1] = service.getCharacteristic(UUID.fromString(XXXX));
nWriteCharacteristic[1] = service.getCharacteristic(UUID.fromString(XXXX));
nReadCharacteristic[1] = service.getCharacteristic(UUID.fromString(XXXX));
}
}
}
}
}
// Send Data to 1st Device
mBluetoothLeService.writeData( 1, data )
// Send Data to 2nd Device
mBluetoothLeService.writeData( 2, data )
…
writeData( int n, byte[] data ) {
nWriteCharacteristic[n].setValue( data );
nBluetoothGatt[n].writeCharacteristic
( nWriteCharacteristic[n] );
}
// Fire automatically
nBluetoothGattCallback() {
onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS)
{ }
}
}
// Read Data from 1st Device
mBluetoothLeService.readData ( 1, true );
// Read Data from 2nd Device
mBluetoothLeService.readData ( 2, true );
readData( int n, Boolean state) {
if(state) {
setCharacteristicNotification
( mNotifyCharacteristic[n-1],true );
nBluetoothGatt[n-1].readCharacteristic
( mNotifyCharacteristic[n-1] );
}
else {
nBluetoothGatt[n-1].
setCharacteristicNotification
( mNotifyCharacteristic[n-1],false );
}
}
// Feedback data to Android Activity with Broadcasting
// Fire automatically
nBluetoothGattCallback() {
// case 1
onCharacteristicRead (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if ( status == BluetoothGatt.GATT_SUCCESS ) {
if ( gatt.getDevice().getAddress() == nAddress[0] ) {
broadcastUpdate(ACTION_DATA_AVAILABLE_1,
characteristic);
}
if ( gatt.getDevice().getAddress() == nAddress[1] ) {
broadcastUpdate(ACTION_DATA_AVAILABLE_2,
characteristic);
}
}
}
// case 2
onCharacteristicChanged (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if ( status == BluetoothGatt.GATT_SUCCESS ) {
if ( gatt.getDevice().getAddress() == nAddress[0] ) {
broadcastUpdate(ACTION_DATA_AVAILABLE_1,
characteristic);
}
if ( gatt.getDevice().getAddress() == nAddress[1] ) {
broadcastUpdate(ACTION_DATA_AVAILABLE_2,
characteristic);
}
}
}
}
// This function send message from Android Service to Android Activity
broadcastUpdate (String action, BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
if ( UUID.fromString(XXXX).equals( characteristic.getUuid() ) ) {
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
intent.putExtra(EXTRA_DATA,data);
}
}
sendBroadcast(intent);
}
// Disconnect from 1st Device
mBluetoothLEService. Disconnect(1);
// Disconnect from 2nd Device
mBluetoothLEService.disconnect(2);
…
// Unbind
unbindService( mServiceConnection );
mBluetoothLeService = null;
disconnect (int n) {
nBluetoothGatt[n-1].disconnect();
}
// Central Device
var mCentralManager: CBCentralManager!
// Peripheral Devices
Var mPeripheral_1: CBPeripheral!
Var mPeripheral_2: CBPeripheral!
…
// Identifier of Peripheral
var mUUID_1: UUID
var mUUID_2: UUID
…
// Service
Var mService_1: CBService!
Var mService_2: CBService!
…
// Characteristic
Var mWriteCharacteristic_1: CBCharacteristic!
Var mReadCharacteristic_1: CBCharacteristic!
Var mNotifyCharacteristic_1: CBCharacteristic!
…
Var mWriteCharacteristic_2: CBCharacteristic!
Var mReadCharacteristic_2: CBCharacteristic!
Var mNotifyCharacteristic_2: CBCharacteristic!
…
// Initial Central Device
self.mCentralManager = CBCentralManager(delegate: self, queue: nil)
…
// Check Bluetooth Hardwire State
// Fire automatically
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch( central.state ){
case CBManagerState.poweredOn:
// Scan
self.mCentralManager.scanForPeripherals(withServices: nil, options: nil)
}
}
// Response when discovered Bluetooth Device Pepherial
// Fire automatically
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
// UUID of peripheral, name, RSSI
// 1st Callback
mPeripheral_1 = peripheral
mUUID_1 = mPeripheral_1.identifier
// 2nd Callback
mPeripheral_2 = peripheral
mUUID_2 = mPeripheral_2.identifier
…
}
// Connect to mPeripheral_1
mCentralManager.connect(mperipheral_1, options: nil)
// Connect to mPeripheral_2
mCentralManager.connect(mperipheral_2, options: nil)
…
// Response when connected to a Bluetooth Device Pepherial
// Fire automatically
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
if( peripheral.identifier == mUUID_1){
// mPeripheral_1 is connected
}
if( peripheral.identifier == mUUID_2){
// mPeripheral_2 is connected
}
…
}
// Check the connect state of Peripheral
mPeripheral_1.discoverServices(nil)
mPeripheral_2.discoverServices(nil)
// Response to discover Service
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if( peripheral == mPeripheral_1 ){
if( peripheral.services?.count != 0 )
for service in peripheral.services! {
if service.uuid.uuidString.contains(“XXXX"){
mService_1 = service as CBService
// Discovered Servie “XXXX"
// go on to discover Characteristic
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
}
// Response to discover Service
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if( peripheral == mPeripheral_2 ){
if( peripheral.services?.count != 0 )
for service in peripheral.services! {
if service.uuid.uuidString.contains(“XXXX"){
mService_2 = service as CBService
// Discovered Servie “XXXX"
// go on to discover Characteristic
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
}
// Response to discover Characteristic
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if( peripheral == mPeripheral_1 ){
if( service.characteristics!.count != 0 ){
for Characterisitc in service.characteristics!{
let mCharacteristic: CBCharacteristic = Characterisitc as CBCharacteristic
if( mService_1 != nil ){
if( mService_1 == service ){
if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
mNotifyCharacteristic_1 = mCharacteristic
}
if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
mWriteCharacteristic_1 = mCharacteristic
}
if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
mReadCharacteristic_1 = mCharacteristic
}
}
}
}
}
}
if( peripheral == mPeripheral_2 ){
if( service.characteristics!.count != 0 ){
for Characterisitc in service.characteristics!{
let mCharacteristic: CBCharacteristic = Characterisitc as CBCharacteristic
if( mService_2 != nil ){
if( mService_2 == service ){
if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
mNotifyCharacteristic_2 = mCharacteristic
}
if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
mWriteCharacteristic_2 = mCharacteristic
}
if( mCharacteristic.uuid.uuidString.contains(“xxxx") ){
mReadCharacteristic_2 = mCharacteristic
}
}
}
}
}
}
…
}
// Send Messages to mPeripheral_1
DispatchAfter(after: 0.0) {
self.mPeripheral_1.setNotifyValue(false, for: self.mNotifyCharacteristic_1)
}
DispatchAfter(after: 0.2) {
self.mPeripheral_1.writeValue(writedata, for: self.mWriteCharacteristic_1, type: CBCharacteristicWriteType.withoutResponse)
}
// Send Messages to mPeripheral_2
DispatchAfter(after: 0.0) {
self.mPeripheral_2.setNotifyValue(false, for: self.mNotifyCharacteristic_2)
}
DispatchAfter(after: 0.2) {
self.mPeripheral_2.writeValue(writedata, for: self.mWriteCharacteristic_2, type: CBCharacteristicWriteType.withoutResponse)
}
…
// Read Messages from mPeripheral_1
mPeripheral_1?.readValue(for: mReadCharacteristic_1!)
// Read Messages from mPeripheral_2
mPeripheral_2?.readValue(for: mReadCharacteristic_2!)
// Response to Read data
// Fire automatically
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
if( peripheral.identifier == mUUID_1){
readdata1[0] = characteristic.value![0]
readdata1[1] = characteristic.value![1]
readdata1[2] = characteristic.value![2]
readdata1[3] = characteristic.value![3]
readdata1[4] = characteristic.value![4]
readdata1[5] = characteristic.value![5]
…
}
if( peripheral.identifier == mUUID_2){
readdata2[0] = characteristic.value![0]
readdata2[1] = characteristic.value![1]
readdata2[2] = characteristic.value![2]
readdata2[3] = characteristic.value![3]
readdata2[4] = characteristic.value![4]
readdata2[5] = characteristic.value![5]
…
}
…
}
self.mCentralManager.cancelPeripheralConnection(self.mPeripheral_1)
self.mCentralManager.cancelPeripheralConnection(self.mPeripheral_2)
…
-- | Android | Windows | iOS and iPadOS |
BLE | JAVA code using android.bluetooth | -------------------------------- | Swift code using CoreBluetooth |
Wi-Fi | JAVA code using socket | C# code using socket | Swift code using socket |
MQTT | JAVA code using Eclipse Paho | C# code using C# M2MQTT.NET | Swift code using CocoaMQTT |