All Projects → XYOracleNetwork → sdk-ble-android

XYOracleNetwork / sdk-ble-android

Licence: LGPL-3.0 license
A robust Bluetooth solution for Android

Programming Languages

kotlin
9241 projects
java
68154 projects - #9 most used programming language

logo

XYO Bluetooth SDK

Download Maintainability

BCH compliance Sonarcloud Status Codacy Badge Known Vulnerabilities

The XYO Foundation provides this source code available in our efforts to advance the understanding of the XYO Protocol and its possible uses. We continue to maintain this software in the interest of developer education. Usage of this source code is not intended for production.

Table of Contents

Description

A robust Bluetooth solution for Android. This BLE SDK was written from ground-up, in Kotlin, to help developers with the agonizing issues with Android the BLE stack. Not only will this SDK make XYO apps better, but bring XYO functionality to existing apps. In addition to generalized BLE support, the SDK also has support for XY specific hardware.

Prerequisites

  • JDK 1.8

  • Android SDK

    • Kotlin
    • Build Tools 27+

Install

You can add sdk-ble-android to your existing app by cloning the project and manually adding it to your build.gradle:

allprojects {
    repositories {
        maven { url "https://dl.bintray.com/xyoraclenetwork/xyo" }
    }
}
dependencies {
    implementation 'com.github.XYOracleNetwork:sdk-ble-android:3.0.1165'
}

Usage

As of version 3.0.1165, listeners have been renamed to streamline class names. Updates to examples below.

A full Working example is included in the project. Look at the ble-android-sample folder for more information.

Configure and create an instance of the scanner:

// enable the device types you want to listen for
// you can create your own custom listener
// for any type of BLE device by creating a Class that extends XYBluetoothDevice
XYAppleBluetoothDevice.enable(true)     //Apple devices
XYIBeaconBluetoothDevice.enable(true)   //iBeacon device
XYFinderBluetoothDevice.enable(true)    //XY device
XY4BluetoothDevice.enable(true)         //XY4+ Find It device
XY3BluetoothDevice.enable(true)         //XY3 Find It device
XY2BluetoothDevice.enable(true)         //XY2 Find It device
XYGpsBluetoothDevice.enable(true)       //XY GPS device
myCustomDevice.enable(true)

val scanner: XYFilteredSmartScan = XYFilteredSmartScanModern(MyApplication.getAppContext())

Add a listener for the XYFilteredSmartScan:

  scanner.addListener(
    "myTAG",
    object : XYFilteredSmartScanListener() {

        override fun entered(device: XYBluetoothDevice) {
            super.entered(device)
            checkMyDeviceTypeAddListener(device)
        }
    
        override fun exited(device: XYBluetoothDevice) {
            super.exited(device)
            doSomethingOnExit()
        }
    
        override fun detected(device: XYBluetoothDevice) {
            super.detected(device)
            doSomethingOnDetected()
        }
    
        override fun connectionStateChanged(device: XYBluetoothDevice, newState: Int) {
            super.connectionStateChanged(device, newState)
            doSomethingOnChanged()
        }

},)

Start scanning for BLE devices:

scanner.start()

Once we know the device type, add a specific device type listener

private fun checkMyDeviceTypeAddListener(device: XYBluetoothDevice) {

    (device as? XY4BluetoothDevice)?.addListener("myTAG", object : XY4BluetoothDeviceListener() {
        override fun buttonSinglePressed(device: XYFinderBluetoothDevice) {
            super.buttonSinglePressed(device)
            doSomethingOnSinglePressed()
        }

        override fun buttonDoublePressed(device: XYFinderBluetoothDevice) {
            super.buttonDoublePressed(device)
            doSomethingOnDoublePressed()
        }

        override fun buttonLongPressed(device: XYFinderBluetoothDevice) {
            super.buttonLongPressed(device)
            doSomethingOnLongPressed()
        }

        override fun entered(device: XYBluetoothDevice) {
            super.entered(device)
            doSomethingOnEntered()
        }

        override fun exited(device: XYBluetoothDevice) {
            super.exited(device)
            doSomethingOnExited()
        }

        override fun detected(device: XYBluetoothDevice) {
            super.detected(device)
            doSomethingOnDetected()
        }

        override fun connectionStateChanged(device: XYBluetoothDevice, newState: Int) {
            super.connectionStateChanged(device, newState)
            doSomethingOnConnectionStateChanged()
        }
    })

    (device as? XY3BluetoothDevice)?.addListener("myTAG", object : XY3BluetoothDeviceListener(){
        //add your logic here
    })

    (device as? XY2BluetoothDevice)?.addListener("myTAG", object : XY2BluetoothDeviceListener(){
    //add your logic here
    })

    (device as? XYIBeaconBluetoothDevice)?.addListener("myTAG", object : XYIBeaconBluetoothDeviceListener(){
    //add your logic here
    })

}

Connecting to a BLE device:

fun connectXY4Device(device: XY4BluetoothDevice) {
    device.connection {
        // within this connection, you can do multiple tasks
        // the connection will stay open until all tasks are completed
        // the connection will auto-disconnect after 5 seconds of inactivity.

        var batteryLevel = device.batteryService.level.get().await()
        var firmwareVersion = device.deviceInformationService.firmwareRevisionString.get().await()
        var deviceName = device.genericAccessService.deviceName.get().await()
    }
}

Basic callback server use

val myAwesomeReadCharacteristic = XYBluetoothReadCharacteristic(UUID.fromString("01ef8f90-e99f-48ae-87bb-f683b93c692f"))
val myAwesomeWriteCharacteristic = XYBluetoothWriteCharacteristic(UUID.fromString("01ef8f90-e99f-48ae-87bb-f683b93c692f"))

/**
 * Will send "Carter is cool" on every read
 */
myAwesomeReadCharacteristic.addResponder("myResponder", object : XYBluetoothReadCharacteristic.XYBluetoothReadCharacteristicResponder {
    override fun onReadRequest(device: BluetoothDevice?): ByteArray? {
        return "Carter is cool".toByteArray()
    }
},)

myAwesomeWriteCharacteristic.addResponder("myResponder", object : XYBluetoothWriteCharacteristic.XYBluetoothWriteCharacteristicResponder {
    override fun onWriteRequest(value: ByteArray, device: BluetoothDevice?): Boolean? {
        if (value.size == 10) {
            return true
        }
        return false
    }
},)

val myAwesomeService = XYBluetoothService(UUID.fromString("3079ca44-ae64-4797-b4e5-a31e3304c481"), BluetoothGattService.SERVICE_TYPE_PRIMARY)
myAwesomeService.addCharacteristic(myAwesomeReadCharacteristic)
myAwesomeService.addCharacteristic(myAwesomeWriteCharacteristic)

val server = XYBluetoothGattServer(applicationContext)
server.addService(myAwesomeService).await()
server.startServer()

Basic await server use

val myAwesomeService = XYBluetoothService(UUID.fromString("3079ca44-ae64-4797-b4e5-a31e3304c481"), BluetoothGattService.SERVICE_TYPE_PRIMARY)
myAwesomeService.addCharacteristic(myAwesomeReadCharacteristic)
myAwesomeService.addCharacteristic(myAwesomeWriteCharacteristic)

val server = XYBluetoothGattServer(applicationContext)
server.addService(myAwesomeService).await()
server.startServer()
//make sure you stop the scanner when no longer needed
scanner.stop()

//remove all device listeners when shutting down an activity:
 override fun onStop() {
    super.onStop()
    device!!.removeListener(TAG)
}

License

See the LICENSE.md file for license details.

Credits

Made with 🔥and ❄️ by XYO

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].