Handwriting recognition library for Android apps running on Onyx Boox e-ink devices.
Wraps the on-device handwriting recognition service to provide a simple coroutine-based API. All recognition runs locally on the device — no internet connection required.
- Onyx Boox device with firmware that includes the
com.onyx.android.ksyncservice - Android minSdk 29 (Android 10) — matches the oldest Boox devices still in active use
Clone or copy the lib module into your project, or add it as a git submodule.
In your settings.gradle.kts:
include(":aragonite-hwr")
project(":aragonite-hwr").projectDir = file("path/to/AragoniteHWR/lib")In your app's build.gradle.kts:
dependencies {
implementation(project(":aragonite-hwr"))
}import dev.aragonite.hwr.AragoniteHWR
import dev.aragonite.hwr.HWRStroke
import dev.aragonite.hwr.HWRPoint
// 1. Bind to the recognition service
val ready = AragoniteHWR.bindAndAwait(context)
if (!ready) {
// Not running on a supported Boox device
return
}
// 2. Build strokes from your stylus input
val stroke = HWRStroke(
points = touchPoints.map { pt ->
HWRPoint(
x = pt.x,
y = pt.y,
dt = pt.deltaTimeMs, // optional, improves accuracy
pressure = pt.pressure // optional, normalized 0..1
)
},
createdAtMs = System.currentTimeMillis()
)
// 3. Recognize
val text = AragoniteHWR.recognizeStrokes(
strokes = listOf(stroke),
viewWidth = 1404f, // your drawing surface width in px
viewHeight = 1872f, // your drawing surface height in px
language = "en_US" // BCP-47 language code
)
println(text) // "Hello world"
// 4. Unbind when done
AragoniteHWR.unbind(context)Bind to the on-device recognition service. Returns true when ready. Call once (e.g., in onCreate).
AragoniteHWR.recognizeStrokes(strokes, viewWidth, viewHeight, language = "en_US", timeoutMs = 10000): String?
Recognize a list of strokes. Returns recognized text, empty string on recognition failure, or null if the service is not bound.
viewWidth/viewHeight— dimensions of the drawing surface in pixels. The recognition engine uses these to understand stroke scale.language— recognition language. The device must have the language pack installed.timeoutMs— maximum time to wait for a result.
Disconnect from the service. Call in onDestroy or when recognition is no longer needed.
data class HWRStroke(
val points: List<HWRPoint>,
val createdAtMs: Long // epoch milliseconds
)
data class HWRPoint(
val x: Float,
val y: Float,
val dt: Int? = null, // delta time in ms from stroke creation
val pressure: Float? = null // normalized 0..1
)Onyx Boox devices ship with a handwriting recognition service (KHwrService) bundled in the com.onyx.android.ksync package. This service is not publicly documented. AragoniteHWR communicates with it via reconstructed AIDL interfaces and a hand-rolled protobuf encoder for stroke data, transmitted over shared memory (MemoryFile).
- Only works on Onyx Boox devices.
bindAndAwait()returnsfalseon other hardware. - The service interface is reverse-engineered and could change with firmware updates (though this is unlikely since Onyx needs backward compatibility with their own apps).
- Uses a hidden Android API (
MemoryFile.getFileDescriptor()) via reflection, which requires thehiddenapibypasslibrary. - Language support depends on what's installed on the device.
Apache License 2.0. See LICENSE.
This library is not affiliated with, endorsed by, or associated with Onyx International Inc. or any of its subsidiaries. All product names and trademarks are the property of their respective owners.