Skip to main content
The Android SDK has many high-level and low-level methods to interact with Plaud devices. We recommend using the high-level methods outlined on this page to handle:
  1. Device Connection: Connecting to & disconnecting from Plaud devices via mobile app
  2. File Management: Syncing files from Plaud device to mobile app
  3. Firmware Updates: Updating Plaud device firmware
These methods should cover majority of Plaud Embedded use cases. For advanced usage, see the advanced Android SDK usage.

Prerequisites

The SDK ships native libraries for arm64-v8a / armeabi-v7a. For testing, you must use a physical device, not an emulator.
Try the Plaud Embedded Skill to have your coding agent help you with your Android implementation.
Visit our GitHub repo for more details on the skill.

Installation

1

Clone the Plaud SDK repo

2

Copy and import the Plaud Android SDK as a dependency

The Android SDK ships as a pre-built .aar. Copy sdk/android/plaud-sdk.aar into your app module’s libs/ directory and add it as a dependency:
build.gradle

Getting Started

Import PlaudDeviceAgent from sdk. PlaudDeviceAgent is a singleton object, so call it directly — there is no instance to construct:
Kotlin
Use these methods and callbacks to drive device interactions between your mobile app and your users’ Plaud devices.

Methods

Plaud Device SDK Initialization

The SDK is initialized with your app Context, a User Token, and your regional domain.
If you haven’t onboarded to the Plaud Developer Platform, see our quickstart onboarding steps.If you’d like more details on how to retrieve your User Token and your regional domain, see the Authentication API reference.
Kotlin
Context
required
Your application Context (e.g. applicationContext).
String
required
User Access Token (JWT), used for device authentication.
String
required
Your regional Plaud server domain without https:// prefix. All SDK network requests use this domain.For more information on how to find your regional server domain, see the Authentication API docs.

Permission Manager

BLE scanning requires runtime permissions on Android. The SDK’s sdk.permission.PermissionManager requests the full set it needs and reports the result.
Kotlin
android.app.Activity
required
Android activity
(Boolean) -> Unit
required
Receives true only when every requested permission was granted.
PermissionManager requests BLUETOOTH_SCAN, BLUETOOTH_CONNECT, ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION on API 31+, and BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION on API ≤ 30. Note that it asks for location on Android 12+ as well.

Connecting (binding) to a Plaud Device

Binding a Plaud device generates a key-pair using the user token and creates an ownership lock on your users’ Plaud device. This makes sure their files on device is always encrypted and can only be decrypted with a valid user token by your application. Binding a device requires an API call to Plaud’s cloud services, so you can track device statuses remotely. And a local bind triggered by the Embedded SDK to verify and generate keys on Plaud device.
1

Scan for the device

.startScan() delivers results on the bleScanResult callback defined in the PlaudDeviceAgentListener.
Kotlin
2

Bind from the cloud

Registers the device/owner association in the Plaud registry. Re-binding a device to the same owner is idempotent, so multiple calls will not have side effects.
Kotlin
String
required
Device type string derived from the SN prefix (881notepro, 882notepins).
String
required
Device serial number.
A 403 response means the device is already bound to another account.
3

Bind the device over BLE

Connects and generates the key-pair on the device itself. The bind result is delivered on bleBind(sn, status, protVersion, timezone).
Two things must be in place before connectBleDevice(...), or the secure handshake fails:
  1. The partner RSA key pair must have arrived. initSDK(...) fetches it over HTTP.
  2. The device serial number must be signed and stored, with NiceBuildSdk.signAndStoreDeviceSn(deviceType, sn). The BLE layer reads that signature during the pre-handshake.
Kotlin
BleDevice
required
A scanned device, as delivered by bleScanResult.
String
Optional second argument on the connectBleDevice(bleDevice, deviceToken) overload — a unique identifier for that device. Omit it to connect with an empty token, which is what most integrations do.The serial number is read from the BleDevice — you do not pass it here.

PlaudDeviceAgentListener Callbacks

Plaud devices can only be bound to one mobile application. If a user is uninstalling your mobile app, make sure to unbind your Plaud device.

Depair (unbind) a device

Plaud devices can only be bound to one application at a time. This is done to properly secure and encrypt files stored on a Plaud device. When a user wants to unbind a Plaud device (whether to use with another Plaud Embedded App or the core Plaud app), unbind over both cloud and BLE. Unbinding via the cloud allows you to track Connected Device statuses remotely and via API.
1

Unbind from the cloud

Removes the device/owner association in the Plaud registry (visible on the Plaud developer portal). This does not require a BLE connection. Send an authenticated POST to the partner unbind endpoint on your regional domain. Unbinding an already-unbound device is an idempotent no-op, so this is safe to call best-effort.
Kotlin
String
required
Device type string derived from the SN prefix (881notepro, 882notepins).
String
required
Device serial number.
2

Depair the device over BLE

Clears the pairing/handshake on the device itself. Requires the device to be connected. On success the SDK disconnects and clears the session. The result is delivered on the bleDepair(status: Int) listener callback.
Kotlin
Boolean
Whether to also clear the device’s own stored bond list. Pass false for the normal unbind flow — this is what the Android Starter App does. Omit the argument to call the no-arg depair() overload.Reserve clear = true for recovering a device whose on-device pairing state is stale.
bleDepair is best-effort — a device that is out of range or unresponsive never answers. Pair the callback with a timeout (a few seconds) and call PlaudDeviceAgent.disconnect() either way, so the BLE link is always released.

File Synchronization

The exportAudio method exports audio files from the Plaud device to your users’ phone, reporting progress through the AudioExporter.ExportCallback.
Plaud devices will record up to 5 hours. Recordings longer should be broken up.
The .getFileList accesses files on your users’ Plaud device.
Kotlin
Long
required
Session ID
File
required
Output directory
AudioExportFormat
required
PCM | WAV | OPUS | MP3. We recommend MP3 — it plays everywhere and is accepted directly by the transcription upload API.
Int
Number of audio channels (1 = mono). Optional — an overload without this argument exists.
AudioExporter.ExportCallback
required
fun onProgress(progress: Int, message: String)fun onComplete(outputFile: File)
For large audio files, we recommend UX considerations:
  • Progress indicators and setting expectations for long transfers (i.e. “This file is large. May take ~X minutes”)
  • Supporting background/resumable transfer so closing the app doesn’t kill the session.
  • Using WiFi Fast Transfer (see below)

WiFi Fast Transfer

An alternative to a BLE (Bluetooth Low Energy) file transfer, WiFi Fast Transfer is ~10x faster than BLE transfers. A transfer spans two objects: PlaudDeviceAgent opens the hotspot, starts and ends the session, and decodes each recording; IWifiTransferAgent (reached with getWifiAgent()) lists and deletes files during the session.
getWifiAgent() returns IWifiTransferAgent? — it is null until the SDK has a WiFi agent to hand out. Always reach it with a safe call (getWifiAgent()?.…).
1

Ask the device to open its hotspot

The device opens a WiFi hotspot on request over BLE. The credentials arrive on the bleWiFiOpen listener callback.
Kotlin
Boolean
required
true opens the device hotspot, false closes it.
2

Start the transfer session

Start the session from the bleWiFiOpen callback. The SDK handles joining the hotspot and the secure handshake for you.
Kotlin
String
required
Identifier for the transfer session.
IWifiTransferAgent.WifiTransferCallback
required
Drives the rest of the flow. See WifiTransferCallback below.
Returns false if the session could not be opened.
3

Wait for READY, then list files

Connection state advances NONECONNECTINGCONNECTEDHANDSHAKINGREADY. No file command works before READY.
Kotlin
4

Export each recording

exportAudioViaWiFi takes the same arguments as exportAudio and reports on the same AudioExporter.ExportCallback, so your existing export handling works unchanged over WiFi.
Kotlin
Use exportAudioViaWiFi(...) rather than the raw downloadFile() / downloadAllFiles() path on IWifiTransferAgent. Those write undecrypted .opus bytes straight to disk; exportAudioViaWiFi runs the same decode pipeline as BLE.
5

End the session

Kotlin
End the session with endWiFiTransfer(), not getWifiAgent().stopWifiTransfer(). Only endWiFiTransfer() also tells the device to close its hotspot over BLE — otherwise it stays open and drains the device battery.
Use PlaudDeviceAgent.isWifiTransferActive() to check whether a session is currently open.

Deleting files over WiFi

IWifiTransferAgent.deleteFiles(...) removes several recordings in one call — the only batch delete in the SDK. The result arrives on onFileDeleteCompleted.
Kotlin
List<Long>
required
Session IDs of the recordings to delete from the device.

WifiTransferCallback

The WiFi Fast Transfer flow is driven by the IWifiTransferAgent.WifiTransferCallback. All members are required — there are no default implementations.
While faster than BLE transfers, we still recommend the following UX considerations for WiFi Fast Transfer syncs:
  • Progress indicators and setting expectations for long transfers (i.e. “This file is large. May take ~X minutes”)
  • Supporting background/resumable transfer so closing the app doesn’t kill the session.

Firmware Update (OTA)

The Embedded SDK handles the entire OTA flow across three calls: version query → download → MD5 verify → CRC → BLE packet push → device restart → reconnect. Each phase reports through the FirmwareUpdateCallback.

Check for Firmware Updates

Kotlin
FirmwareUpdateCallback
required
Callback that reports the check result as a FirmwareUpdateInfo.

Download Firmware Update

Kotlin
FirmwareUpdateInfo
required
The FirmwareUpdateInfo returned by checkFirmwareUpdate.
FirmwareUpdateCallback
required
Reports download progress and completion.

Install Firmware Update

Kotlin
File
required
The firmware file from FirmwareDownloadResult.file
FirmwareUpdateInfo
required
The FirmwareUpdateInfo returned by checkFirmwareUpdate
FirmwareUpdateCallback
required
Reports install progress and completion.

Interfaces and Callbacks

The Embedded SDK is callback-driven. Device events flow through a single global listener you assign to PlaudDeviceAgent.listener, while per-operation flows (audio export, WiFi transfer, firmware) take their own callback interface. These four cover most use cases.
Callbacks are delivered on the SDK’s internal threads — not the main thread. Marshal to the main thread (e.g. runOnUiThread { } / a Handler) before touching UI or view state.

PlaudDeviceAgentListener

The primary listener for PlaudDeviceAgent. Assign it once to PlaudDeviceAgent.listener and it drives the entire BLE lifecycle — scan, connect, bind, device state, recording, and file sync. A single global listener receives every device event; all methods return Unit.
Kotlin
The listener also delivers the WiFi auto-sync configuration results (onWifiSyncEnabled, onWifiSyncListReceived, onWifiSyncConfigReceived, onWifiSyncConfigSet, onWifiSyncDeleteResult, onWifiSyncTestStarted, onWifiSyncTestResult). These configure the device’s own scheduled background upload and are distinct from WiFi Fast Transfer.

AudioExporter.ExportCallback

Reports progress, completion, and errors for exportAudio(...) (BLE) and exportAudioViaWiFi(...) (WiFi).
Kotlin
fun
required
Export progress, 0100 (download bytes), with a human-readable status message.
fun
required
Called when decoding finishes; outputFile is the written file.
fun
required
Called if export fails, with a description of the error.
fun
Optional (has a default implementation). Language-neutral phase signal: DOWNLOADING (bytes still transferring off the device) → TRANSCODING (only local decode/encode remains).

IWifiTransferAgent.WifiTransferCallback

WiFi Fast Transfer is split across both high-level interfaces, so you will use IWifiTransferAgent directly for any fast transfer. PlaudDeviceAgent owns the session lifecycle and the audio pipeline; IWifiTransferAgent owns the file operations and the callback you implement to drive them.
Kotlin

WiFi Fast Transfer

The typical flow: open the hotspot over BLE, start the session, wait for READY, list files, then export each one.

WifiTransferCallback

12 required members for Wifi Transfers, generally driven by PlaudDeviceAgent.exportAudioViaWiFi. WifiFileInfo carries sessionId, fileName, fileSize, duration (ms), timestamp (epoch seconds), and scene — more per-file metadata than BleFile exposes over BLE.

FirmwareUpdateCallback

Reports each phase of the OTA flow across checkFirmwareUpdate(...), downloadFirmware(...), and installFirmware(...). Extend SimpleFirmwareUpdateCallback() to override only the methods you need — each has an empty default implementation.
Kotlin