> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stmlink.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> 对外开放的服务端接口有两组前缀，都用同一套鉴权：`/server/v1/...`（SRTC 与 SMeeting 的主接口）和 `/stm/srvapi/v1/...`（SMeeting 的用户体系，服务端极简对接会用到）。鉴权是 app_id + nonce + timestamp + signature 四个请求头，用 app_key 做 HMAC-SHA256 签名，只能从业务方自己的后端调用。除这两组前缀外的接口均为内部接口，不要建议客户调用。
> app_key 是服务端密钥，绝不能出现在客户端代码、前端配置或移动 App 里。客户端加入频道用的 token 必须由业务方后端签发后下发（SRTC 走 `/server/v1/channel/grant`，SMeeting 走 `/stm/srvapi/v1/member/grant`）。
> SRTC 与 SMeeting 是上下两层不同的产品，术语不通用：SRTC 是音视频底座，说「频道 channel」「加入 / 退出」；SMeeting 建在 SRTC 之上，说「房间 room」「会议 meeting」「进入 / 退出」。回答时按用户所在的层用对应术语，不要把「房间」「会议」安到 SRTC 的接口上。
> 同一能力在各端 SDK 里的包名、类名、方法名并不相同。写示例代码时请使用文档中该端自己的 API，不要把一个端的写法套到另一个端上。苹果平台每个产品都有两套 SDK（Swift 原生与 Objective-C），两套 API 不能混用。

# 白板共享

> 会议里怎么开白板：用 requestShareBoard() 拿到白板地址并用 WebView 承载，处理他人共享与中途入会，以及 WebView 需要的 JS 接口

会议里的电子白板是一个**由服务端托管的 H5 页面**，Android 端用 `WebView` 承载。笔迹同步走白板自己的通道，不产生媒体流，也不占用摄像头 / 屏幕采集。

<Note>
  白板页面本身的能力（URL 参数、桌面批注模式、生命周期与销毁时机）与 SRTC 层完全一致，见 [SRTC · 电子白板](/zh/rtc/whiteboard)。本页只讲会议层的用法。
</Note>

***

### 发起白板共享

`requestShareBoard()` 做两件事：向会议广播「我在共享白板」，并在回调里返回白板地址。

```kotlin theme={null}
meetingEngine.requestShareBoard(object : BoardShareCallback {
    override fun onSucceed(whiteBoard: String) {
        // whiteBoard 是拼好授权码的完整 URL，直接加载
        showBoard(whiteBoard)
    }

    override fun onFail(code: Int, errorMsg: String?, showMsg: String?) {
        // 常见失败：主持人开启了「房间禁共享」、已有他人在共享
        toast(showMsg)
    }
})
```

同一时刻一个会议只允许一位成员共享，屏幕共享与白板互斥。

停止共享：

```kotlin theme={null}
meetingEngine.stopShareWhiteBoard()
```

<Note>
  主持人处理他人的共享申请，用 [`confirmStartWhiteBoardShareAgree()`](/zh/meeting/android/api-reference/MeetingEngine) / `confirmStartWhiteBoardShareRefuse()`，同意时同样会在回调里拿到白板地址。
</Note>

***

### 响应他人的白板共享

自己不是发起者时，从房间事件里得知，地址从 `infosManager` 读：

```kotlin theme={null}
override fun onRoomShareStart(shareUid: String, shareType: ShareType) {
    if (shareType == ShareType.WhiteBoardShare) {
        showBoard(meetingEngine.infosManager.whiteBoard ?: return)
    }
}

override fun onRoomShareStop(shareUid: String, shareType: ShareType) {
    if (shareType == ShareType.WhiteBoardShare) {
        hideBoard()
    }
}
```

**中途入会的人收不到这个事件**，进会后要自己补一次判断：

```kotlin theme={null}
val info = meetingEngine.infosManager.getMeetingInfo()
if (info?.shareState == ShareType.WhiteBoardShare) {
    // 会议中已经有人在共享白板
    showBoard(meetingEngine.infosManager.whiteBoard ?: return)
}
```

***

### 用 WebView 承载

白板页是一个标准的 Web 应用，**必须启用 JavaScript**；白板销毁时要通知宿主关掉视图，所以还要注入一个名为 `AndroidInterface` 的 JS 接口：

```kotlin theme={null}
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.addJavascriptInterface(object {
    /** 白板被销毁（有人主动销毁或到期清理），宿主应关掉白板视图 */
    @JavascriptInterface
    fun onWbDestroy(reason: String?) {
        runOnUiThread { hideBoard() }
    }

    /** 用户点了导出按钮（需在 URL 上加 export_btn=1），回传图片 base64 */
    @JavascriptInterface
    fun onExportImage(base64: String) {
        saveImage(base64)
    }
}, "AndroidInterface")

webView.loadUrl(whiteBoard)
```

退出会议或收到 `onRoomShareStop` 时，记得销毁 WebView，避免它在后台继续保持白板连接。

***

### 相关

* [SRTC · 电子白板](/zh/rtc/whiteboard) —— 白板页面的 URL 参数、状态同步原理、生命周期与销毁
* [MeetingEngine](/zh/meeting/android/api-reference/MeetingEngine) —— `requestShareBoard()` / `stopShareWhiteBoard()` 接口签名
* [BoardShareCallback](/zh/meeting/android/api-reference/BoardShareCallback) —— 共享结果回调
* [RoomEvent](/zh/meeting/android/api-reference/RoomEvent) —— 共享开始 / 结束事件
