diff --git a/app/src/main/kotlin/top/yeij/cyrene/ui/chat/ChatScreen.kt b/app/src/main/kotlin/top/yeij/cyrene/ui/chat/ChatScreen.kt index 7acc3d2..6c06e69 100644 --- a/app/src/main/kotlin/top/yeij/cyrene/ui/chat/ChatScreen.kt +++ b/app/src/main/kotlin/top/yeij/cyrene/ui/chat/ChatScreen.kt @@ -178,9 +178,13 @@ fun ChatScreen( val previewFileName = previewTarget?.suggestedFileName() ?: FALLBACK_PREVIEW_FILE_NAME // 「保存到下载目录」走系统 SAF:用户自己挑落点,本端不申请任何存储权限。 - // 契约带上的 MIME 用文档自己的类型(服务端嗅探所得,不按扩展名猜)。 + // ⚠️ 这里的 MIME **不能用 `previewType`**:那是**字节嗅探所得的基类型**(`.md` 也报 + // `text/plain`),而 SAF 的 Downloads provider 会按该 mime 给文件名**补扩展名** ⇒ + // 2026-10-05 实机复现:存的 `…e.md` 变成了 `…e.md.txt`。传 `*/*` 就没有可补的扩展名, + // 原扩展名因此保真。(「用其它应用打开」那条路刻意相反:那里要的正是「能读懂这段内容的 + // 类型」,所以照旧用嗅探所得 mime。) val createDocument = rememberLauncherForActivityResult( - remember(previewType) { ActivityResultContracts.CreateDocument(previewType) }, + ActivityResultContracts.CreateDocument("*/*"), ) { destination -> val ready = previewState as? DocumentPreviewState.Ready if (destination == null || ready == null) return@rememberLauncherForActivityResult