在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):JuulLabs/kable开源软件地址(OpenSource Url):https://github.com/JuulLabs/kable开源编程语言(OpenSource Language):Kotlin 100.0%开源软件介绍(OpenSource Introduction):KableKotlin Asynchronous Bluetooth Low Energy provides a simple Coroutines-powered API for interacting with Bluetooth Low Energy devices. Usage is demonstrated with the SensorTag sample app. ScanningTo scan for nearby peripherals, the The val scanner = Scanner {
filters = null
logging {
engine = SystemLogEngine
level = Warnings
format = Multiline
}
} To filter scan results at the system level (recommended), specify a list of filters for the services the remote peripheral is advertising, for example: val scanner = Scanner {
filters = listOf(
Filter.Service(uuidFrom("f000aa80-0451-4000-b000-000000000000")),
Filter.Service(uuidFrom("f000aa81-0451-4000-b000-000000000000"))
)
} In Android source sets, you can also scan with manufacturer data filters. See the Android section below for more details. Scanning begins when the val advertisement = Scanner()
.advertisements
.first { it.name?.startsWith("Example") } AndroidScan results can be filtered by manufacturer data using the same ID, data, and data mask that you would use with the Android API: val scanner = Scanner {
filters = listOf(
Filter.ManufacturerData(id = 1, data = byteArrayOf(), dataMask = byteArrayOf())
)
} Android also offers additional settings to customize scanning. They are available via the val scanner = Scanner {
scanSettings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build()
} The JavaScriptScanning for nearby peripherals is supported, but only available on Chrome 79+ with "Experimental Web
Platform features" enabled via: PeripheralOnce an val peripheral = scope.peripheral(advertisement) ConfigurationTo configure a val peripheral = scope.peripheral(advertisement) {
// Set peripheral configuration.
} LoggingBy default, Kable only logs a small number of warnings when unexpected failures occur. To aid in debugging, additional
logging may be enabled and configured via the val peripheral = scope.peripheral(advertisement) {
logging {
level = Events // or Data
}
} The available log levels are:
Available logging settings are as follows (all settings are optional; shown are defaults, when not specified): val peripheral = scope.peripheral(advertisement) {
logging {
engine = SystemLogEngine
level = Warnings
format = Multiline
data = Hex
}
} The format of the logs can be either
Display format of I/O data may be customized, either by configuring the val peripheral = scope.peripheral(advertisement) {
logging {
data = Hex {
separator = " "
lowerCase = false
}
// or...
data = DataProcessor { bytes ->
// todo: Convert `bytes` to desired String representation, for example:
bytes.joinToString { byte -> byte.toString() } // Show data as integer representation of bytes.
}
}
} I/O data is only shown in logs when logging When logging, the identity of the peripheral is prefixed on log messages to differentiate messages when multiple
peripherals are logging. The identifier (for the purposes of logging) can be set via the val peripheral = scope.peripheral(advertisement) {
logging {
identifier = "Example"
}
} The default (when not specified, or set to
Service DiscoveryAll platforms support an val peripheral = scope.peripheral(advertisement) {
onServicesDiscovered {
// Perform any desired I/O operations.
}
} Exceptions thrown in AndroidOn Android targets, additional configuration options are available (all configuration directives are optional): val peripheral = scope.peripheral(advertisement) {
onServicesDiscovered {
requestMtu(...)
}
transport = Transport.Le // default
phy = Phy.Le1M // default
} JavaScriptOn JavaScript, rather than processing a stream of advertisements, a specific peripheral can be requested using the
val options = Options(
optionalServices = arrayOf(
"f000aa80-0451-4000-b000-000000000000",
"f000aa81-0451-4000-b000-000000000000"
),
filters = arrayOf(
NamePrefix("Example")
)
)
val peripheral = scope.requestPeripheral(options).await() ConnectivityOnce a Multiple concurrent calls to peripheral.connect() To disconnect, the peripheral.disconnect() If the underlying subsystem fails to deliver the disconnected state then the // Allow 5 seconds for graceful disconnect before forcefully closing `Peripheral`.
withTimeoutOrNull(5_000L) {
peripheral.disconnect()
} StateThe connection state of a peripheral.state.collect { state ->
// Display and/or process the connection state.
} The
I/OBluetooth Low Energy devices are organized into a tree-like structure of services, characteristics and descriptors; whereas characteristics and descriptors have the capability of being read from, or written to. For example, a peripheral might have the following structure:
To access a characteristic or descriptor, use the When performing I/O operations on a characteristic ( In the above example, to lazily access "Descriptor D3": val descriptor = descriptorOf(
service = "00001815-0000-1000-8000-00805f9b34fb",
characteristic = "00002a56-0000-1000-8000-00805f9b34fb",
descriptor = "00002902-0000-1000-8000-00805f9b34fb"
) Alternatively, a characteristic or descriptor may be obtained by traversing the To access "Descriptor D3" using a discovered descriptor: val services = peripheral.services ?: error("Services have not been discovered")
val descriptor = services
.first { it.serviceUuid == uuidFrom("00001815-0000-1000-8000-00805f9b34fb") }
.characteristics
.first { it.characteristicUuid == uuidFrom("00002a56-0000-1000-8000-00805f9b34fb") }
.descriptors
.first { it.descriptorUuid == uuidFrom("00002902-0000-1000-8000-00805f9b34fb") } This example uses a similar search algorithm as When connected, data can be read from, or written to, characteristics and/or descriptors via The val data = peripheral.read(characteristic)
peripheral.write(descriptor, byteArrayOf(1, 2, 3)) ObservationBluetooth Low Energy provides the capability of subscribing to characteristic changes by means of notifications and/or indications, whereas a characteristic change on a connected peripheral is "pushed" to the central via a characteristic notification and/or indication which carries the new value of the characteristic. Characteristic change notifications/indications can be observed/subscribed to via the val observation = peripheral.observe(characteristic)
observation.collect { data ->
// Process data.
} When used with A Failures related to notifications/indications are propagated via the scope.peripheral(advertisement) {
observationExceptionHandler { cause ->
// Log failure instead of propagating associated `observe` flow.
println("Observation failure suppressed: $cause")
}
} In scenarios where an I/O operation needs to be performed upon subscribing to the val observation = peripheral.observe(characteristic) {
// Perform desired I/O operations upon collecting from the `observe` Flow, for example:
peripheral.write(descriptor, "ping".toByteArray())
}
observation.collect { data ->
// Process data.
} In the above example,
The Structured ConcurrencyPeripheral objects/connections are scoped to a Coroutine scope. When creating a Scanner()
.advertisements
.filter { advertisement -> advertisement.name?.startsWith("Example") }
.map { advertisement -> scope.peripheral(advertisement) }
.onEach { peripheral -> peripheral.connect() }
.launchIn(scope)
delay(60_000L)
scope.cancel() // All `peripherals` will implicitly disconnect and be disposed.
SetupGradleKable can be configured via Gradle Kotlin DSL as follows: New memory model
kotlin.native.binary.memoryModel=experimental
plugins {
id("com.android.application") // or id("com.android.library")
kotlin("multiplatform")
}
repositories {
mavenCentral()
}
kotlin {
android()
js().browser()
macosX64()
iosX64()
iosArm64()
sourceSets {
val commonMain by getting {
dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${coroutinesVersion}")
implementation("com.juul.kable:core:${kableVersion}")
}
}
val androidMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:${coroutinesVersion}")
}
}
}
}
android {
// ...
} Old memory model全部评论
专题导读
上一篇:mage-tianxie/latex-: 中文的latex期刊论文双栏模板发布时间:2022-07-09下一篇:acaroom/kotlin: Do it! Kotlin Programming发布时间:2022-07-07热门推荐
热门话题
阅读排行榜
|
请发表评论