Client Android API Reference
Primary Path Overview
Android v1 documents a single client-role primary path:
TiRtc: initialize and shut down the global runtimeTiRtcConn: create one outbound connection, send and receive commands or stream messages, request key framesTiRtcAudioOutput: consume remote audioTiRtcVideoOutput: consume remote video and bind rendering throughattachView(container)TiRtcLogging: write SDK logs and upload log bundles
Typical flow:
TiRtc.initialize(context)TiRtcConn()- Assign listener properties
connect(remoteId, token)TiRtcAudioOutput.attach(connection, streamId)TiRtcVideoOutput.attach(connection, streamId)TiRtcVideoOutput.attachView(container)- Call
release()on owned objects, thenTiRtc.shutdown()
Minimal Example
kotlin
val initCode = TiRtc.initialize(applicationContext)
check(initCode == 0)
val conn = TiRtcConn()
val audioOutput = TiRtcAudioOutput()
val videoOutput = TiRtcVideoOutput()
conn.onStateChanged = TiRtcConnStateListener { state ->
println("conn state=$state")
}
conn.onDisconnected = TiRtcConnDisconnectedListener { code ->
println("disconnected code=$code")
}
conn.onCommand = TiRtcConnCommandListener { command, data ->
println("command=$command bytes=${data.size}")
}
conn.onStreamMessage = TiRtcConnStreamMessageListener { streamId, timestampMs, data ->
println("streamId=$streamId ts=$timestampMs bytes=${data.size}")
}
conn.onError = TiRtcConnErrorListener { code ->
println("conn error=$code")
}
check(conn.connect(remoteId, token) == 0)
check(audioOutput.attach(conn, audioStreamId) == 0)
check(videoOutput.attach(conn, videoStreamId) == 0)
check(videoOutput.attachView(videoContainer) == 0)Callback And Lifecycle Rules
- Client-facing listeners are always delivered on the Android main looper
disconnect(),detach(), andrelease()are cleanup-friendly; repeated calls in the already-clean state succeed as no-ops- When a connection closes,
TiRtcConnalways deliversonDisconnected(code)beforeonStateChanged(DISCONNECTED) TiRtc.shutdown()succeeds only after every object that still owns a native handle has been cleaned up; any unreleasedTiRtcConn,TiRtcAudioOutput,TiRtcVideoOutput, or retained server-side object keeps shutdown inINVALID_STATE
TiRtc
initialize(context, endpoint = "", environment = 0, consoleLoggingEnabled = false): Int
kotlin
val code = TiRtc.initialize(
context = applicationContext,
endpoint = "",
environment = 0,
consoleLoggingEnabled = BuildConfig.DEBUG,
)context: required; the SDK storesapplicationContextendpoint: optional; an empty string lets the runtime resolve its default endpoint for the selectedenvironmentenvironment: optionalInt, default0; Android no longer exposes publicENV_*constants on the primary pathconsoleLoggingEnabled: optional console log mirroring switch, defaultfalse- Java callers consume the generated
@JvmOverloadsoverloads
shutdown(): Int
- Shuts the global runtime down
- If the runtime is already uninitialized,
shutdown()succeeds as a no-op - Call it only after every connection, output, and retained server-side object has been cleaned up
- The SDK does not force-destroy live objects; shutdown returns
INVALID_STATEwhile any live object remains
TiRtcConn
States
IDLECONNECTINGCONNECTEDDISCONNECTED
Listener Properties
kotlin
var onStateChanged: TiRtcConnStateListener?
var onDisconnected: TiRtcConnDisconnectedListener?
var onCommand: TiRtcConnCommandListener?
var onStreamMessage: TiRtcConnStreamMessageListener?
var onError: TiRtcConnErrorListener?ObserverandsetObserver(...)are no longer part of the client primary path- Listeners can be assigned or cleared independently after construction
- Accepted connections follow the same listener contract; the SDK replays early events so a late listener assignment does not lose the initial
CONNECTED, the following disconnect, the first command, or the first stream message
TiRtcConn()
- Public no-arg constructor
- Requires a successful
TiRtc.initialize(...) - Throws
IllegalStateExceptionif the runtime is unavailable, the native bridge is not ready, or the native handle cannot be created
connect(remoteId: String, token: String): Int
remoteId: remote peer identifiertoken: externally issued connection token- Blank strings return
INVALID_ARGUMENT
disconnect(): Int
- Disconnects transport only
- Does not release the object itself
- Returns success when already
IDLEorDISCONNECTED
release(): Int
- Releases connection resources
- Repeated calls succeed as no-ops
- A disconnected
TiRtcConnstill blocksTiRtc.shutdown()untilrelease()has been called
sendCommand(command: Long, data: ByteArray = byteArrayOf()): Int
- Sends a one-way raw command
commandis exposed as an opaqueuint32_tcommand word; Android does not interpret bit semantics- Valid range:
0..0xFFFF_FFFFL
sendStreamMessage(streamId: Int, timestampMs: Long, data: ByteArray): Int
- Sends one in-stream message
streamId: remote stream identifiertimestampMs: non-negative millisecond timestampdata: application payload
requestKeyFrame(streamId: Int): Int
- Requests a key frame from the selected remote video stream
- Returns a stable error when the connection is not ready, the object has been released, or the arguments are out of range
TiRtcAudioOutput
States
IDLEBUFFERINGPLAYINGFAILED
TiRtcAudioOutputOptions
kotlin
class TiRtcAudioOutputOptions @JvmOverloads constructor(
val volumePercent: Int = 100,
val gainLevel: Int = 0,
val noiseReductionLevel: Int = 0,
)Listener Properties
kotlin
var onStateChanged: TiRtcAudioOutputStateListener?
var onError: TiRtcAudioOutputErrorListener?TiRtcAudioOutput()
- Public no-arg constructor
- Requires
TiRtc.initialize(...) - Throws
IllegalStateExceptionon construction failure
attach(connection: TiRtcConn, streamId: Int): Int
- Binds the output to one remote audio stream on the selected connection
- One output consumes only one remote audio route at a time
detach(): Int
- Removes the current remote audio route
- Keeps the output reusable
- Repeated calls succeed as no-ops
updateOptions(options: TiRtcAudioOutputOptions): Int
- Updates playback options
volumePercentmust be greater than or equal to0
release(): Int
- Releases the output and automatically detaches the current route
- Repeated calls succeed as no-ops
TiRtcVideoOutput
States
IDLEBUFFERINGRENDERINGFAILED
Listener Properties
kotlin
var onStateChanged: TiRtcVideoOutputStateListener?
var onRenderSizeChanged: TiRtcVideoOutputRenderSizeListener?
var onError: TiRtcVideoOutputErrorListener?renderSize: Size?
- Current render output size
- This is an advanced observability signal; the primary rendering mental model remains “bind a container and render”
TiRtcVideoOutput()
- Public no-arg constructor
- Requires
TiRtc.initialize(...) - Throws
IllegalStateExceptionon construction failure
attach(connection: TiRtcConn, streamId: Int): Int
- Binds the output to one remote video stream on the selected connection
- Container binding is separate, so
attach(...)may happen beforeattachView(...)
detach(): Int
- Removes the current remote video route
- Does not release the object and is not equivalent to
detachView() - Repeated calls succeed as no-ops
attachView(container: ViewGroup): Int
- The Android public rendering entry point
- Must run on the main thread
- The argument is a parent
ViewGroup, not aTextureView - The SDK creates and manages the internal
TextureViewand render host inside that container - One
TiRtcVideoOutputsupports only one currently bound container; rebinding to a different container fails instead of performing implicit re-parenting
detachView(): Int
- Unbinds the internal render host from the container
- Does not affect the remote stream route
- Does not release the
TiRtcVideoOutputobject itself
release(): Int
- Releases the output
- Also cleans up the remote route, the internal render host, and the native resources
- Repeated calls succeed as no-ops
TiRtcLogging
d(tag, message) / i(tag, message) / w(tag, message) / e(tag, message)
- Write messages into the SDK logging system
TiRtcDebuggingis no longer the client primary logging surface; the public entry point is nowTiRtcLogging
upload(callback: TiRtcLogUploadCallback): Int
kotlin
val submitCode =
TiRtcLogging.upload { code, logId ->
if (code == 0) {
println("logId=$logId")
} else {
println("upload failed code=$code")
}
}- The return value only reports whether the upload task was accepted
- The completion callback shape is fixed to
(code, logId) - When
code == 0,logIdmay be non-null - When
code != 0,logIdmust benull - The callback is also dispatched on the main looper
Public Error Codes
| Code | Name | Meaning |
|---|---|---|
0 | OK | Operation succeeded |
-1 | INVALID_ARGUMENT | Invalid or out-of-range argument |
-2 | INVALID_STATE | The current runtime or object state does not allow the call |
-3 | NATIVE_UNAVAILABLE | Native bridge or dynamic library is unavailable |
-4 | NOT_READY | The underlying object is not ready yet |
-5 | OPERATION_FAILED | Generic failure |
-9 | TRANSPORT_INVALID_LICENSE | Invalid service-side license |
-10 | TRANSPORT_TIMEOUT | Transport timeout |
-11 | TRANSPORT_BUSY | Transport is busy |
-12 | TRANSPORT_CONNECTION_TIMEOUT_CLOSED | Connection closed due to timeout |
-13 | TRANSPORT_REMOTE_CLOSED | Connection closed by the remote side |
-14 | TRANSPORT_CONNECTION_OTHER_ERROR | Connection closed for another transport error |
-15 | TRANSPORT_TOKEN_EXPIRED | Token expired |
Retained APIs That Still Ship In The Artifact
The following APIs still ship in the same com.tange.ai:tirtc-av artifact, but they are not part of the Android v1 client primary path:
TiRtcConnServiceTiRtcAudioInputTiRtcVideoInputTiRtcCredentialTiRtcCredentialResultRtcCredentialIssueTokenOptionsRtcLocalAudioOptionsRtcCameraFacing
They remain the retained server-side or auxiliary surface:
TiRtcConnService: device-side listener service that delivers accepted connections throughonConnected(connection)TiRtcAudioInputandTiRtcVideoInput: local capture and uplink bindingsTiRtcCredential: issue tokens from input parameters;accessIdandsecretKeymust not be embedded in production clients
These APIs were not removed from the artifact in this redesign, but the primary docs and example-client no longer use them to define the client-role integration model.