Skip to main content

Android Data and Device Capabilities

SDK Version: 1.0.0
Package: com.xtalk.mesh.sdk.ble

Except for image transcoding, these APIs require successful ensureInitialized(); send APIs also require connection, Auth, and Init. Invoke blocking/device-waiting methods on Dispatchers.IO. Treat only the explicit success member of a delivered result enum as success.

1. Binary and RF​

APIUseResult semantics
sendBinaryFrame(data)Normal binary business frameSendResult; empty/length/state/link errors are enum outcomes
sendRfPayloadAndWaitSendFinish(rawPayload, timeoutMs)Device completion requiredtrue only after send completion within the deadline
sendRfPayloadNoWait(rawPayload)Realtime voice/controlSubmission only; empty payload is false; caller rate-limits

Prefer the waited operation for reliable traffic. Use no-wait only for a loss-tolerant, rate-controlled realtime stream. Never overlap with Auth, Init, or custom AT.

2. Raw AT and passthrough ownership (Advanced)​

APIContract
runAtCommand(...)Exclusive radio lock and response lines; see API Reference
sendAtCommand(command)SendResult, without response lines
sendAtCommandNoWait(command)Write submission only
sendEncryptedAt(bytes)Bytes already encoded by the delivered AT protocol; true on submission
setPassthroughListener(listener)Installs the single low-level passthrough owner; null releases it; may interfere with runAtCommand
withWirelessOpLock(block)Serializes an advanced customer transaction with Auth/Init/AT; never wait recursively on the same lock

Use BleAtErrorPolicy.COLLECT_UNTIL_COMPLETE only with a clear stopWhen. When drainResponseTailAfterStop = true, stopWhen is mandatory and the SDK retains the listener/lock through a terminal line or original deadline.

3. Text and data reception​

private val textListener = TextReceivedCallback { sourceId, text, snr, rssi ->
// Dispatch UI work to the main thread.
}
private val dataListener = DataReceivedCallback { bytes, length, snr, rssi ->
val payload = bytes.copyOf(length.coerceIn(0, bytes.size))
}
XTalkBleClient.addTextListener(textListener)
XTalkBleClient.addDataListener(dataListener)
val result = XTalkBleClient.sendText("hello")
XTalkBleClient.removeTextListener(textListener)
XTalkBleClient.removeDataListener(dataListener)

sendText returns SendResult. Data callbacks run on the high-frequency I/O path; consume only 0 until length and return quickly. Text callbacks include source ID, text, SNR, and RSSI.

4. File transfer​

private val sendListener = FileSendCallback { progress, sent, total, result -> }
private val receiveListener = FileReceiveCallback { progress, received, total, result, bytes ->
if (bytes != null) savePrivately(bytes)
}
XTalkBleClient.addFileSendListener(sendListener)
XTalkBleClient.addFileReceiveListener(receiveListener)
val accepted = XTalkBleClient.sendFile(fileBytes)
XTalkBleClient.cancelFileSend()
XTalkBleClient.cancelFileReceive()
XTalkBleClient.removeFileSendListener(sendListener)
XTalkBleClient.removeFileReceiveListener(receiveListener)

Send/cancel SendResult values describe the request; final progress and outcome come from callbacks. The customer owns file selection, size checks, storage, and privacy. Run one channel-owning file/AT/Auth/Init operation at a time. Restore text/PTT defaults after completion or cancellation when a mode was changed.

5. PTT and realtime voice​

Runtime RECORD_AUDIO permission is required.

APIParameters/defaultsLifecycle
startPttVoiceCapture(enablePcmCallback = true)Local PCM callback togglePair with stopPttVoiceCapture()
startRealtimeVoiceCapture(peopleCount = 2, mute = 0)Participant count and mute flagPair with stopRealtimeVoiceCapture()
stopVoiceCaptureLocal()NoneLocal-only abnormal/fast cleanup
setRealtimeWorkModeOverride(workMode)null clearsSet before and clear after the session
getRealtimeWorkModeOverride()NoneCurrent override or null

Register VoiceReceivedCallback and VoiceCaptureCallback with their matching add/remove pairs. Copy only the reported PCM length. Voice callbacks are realtime paths: do not perform file I/O, network calls, or blocking UI work.

6. PCM playback​

startVoicePlayback(pcm) and stopVoicePlayback() return PlaybackStartResult and PlaybackStopResult. Input must match the PCM format in the delivery contract. Inspect the enum result; do not infer success from elapsed time.

7. Image transcoding​

val output = XTalkBleClient.transcodeImage(
imageBytes = encodedImage,
targetTier = targetTier,
inputFormat = null, // auto-detect
)

This is an offline CPU operation and needs no BLE/Auth/Init/audio permission. Run large images off the main thread. Inspect the delivered ImageTranscodeResult success state before using output bytes.

8. 16-byte key​

require(key.size == 16)
check(XTalkBleClient.setCryptoKey16(key))
key.fill(0)

On false, do not continue encrypted traffic. Never log, send to analytics, or persist the plaintext key.

9. Radio settings​

APIDifference
setChannelFrequency(freqHz, timeoutMs = 3000)Waits for wireless-config channel callback
setFrequencyHz(freqHz, timeoutMs = 3000)AT command sets all four frequency slots
setRateMode(rateMode)Coerces into 0..255; device support is still determined by the result
restoreTextPttDefaults(rate = 7, addtl = 1, work = 21)Restores all three values; succeeds only when all do

Use only project/region-approved frequencies. Stop traffic and query actual state after a failed setting; do not retry forever.

10. Hardware, firmware, battery, and management events​

getHardwareVersion(2000), getFirmwareVersion(2000), and getBatteryLevel(4000) wait for device results and return null for failure, timeout, or unsupported operations. Successful values are cached until disconnect. A DeviceManageCallback can observe asynchronous management values; cast value based on type and remove the listener during cleanup. Do not invent an extra battery range/unit beyond the device-reported integer.

11. Listener pairs​

AddRemoveCallback/thread
addListenerremoveListenerScan/connection state; main-thread fanout
addDataListenerremoveDataListenerBinary/realtime data; I/O callback thread
addDeviceManageListenerremoveDeviceManageListenerVersions/battery; main-thread fanout
addTextListenerremoveTextListenerText; main-thread fanout
addVoiceListenerremoveVoiceListenerRemote PCM; realtime callback thread
addVoiceCaptureListenerremoveVoiceCaptureListenerLocal PCM; main-thread fanout
addFileSendListenerremoveFileSendListenerSend progress; main-thread fanout
addFileReceiveListenerremoveFileReceiveListenerReceive progress/final bytes; main-thread fanout

The SDK strongly retains listeners. Remove the same instance to prevent duplicate callbacks and leaked Activity/ViewModel lifetimes.

API Reference · Errors and FAQ