android-md-reader:基于 Kotlin 与 Jetpack Compose 的 Android 离线 Markdown 阅读器项目

Android 离线 Markdown 阅读器:Kotlin + Jetpack Compose,零权限/零网络/零收集,支持 Mermaid 离线渲染、系统 TTS 朗读与 MP3 导出(不引入 NDK)

Branch1Tags0

android-md-reader

Android 平台上的 离线 Markdown 阅读器,Kotlin + Jetpack Compose 编写,零权限、零网络、零数据收集。

一款"小而美"的纯本地 Markdown 阅读应用,是 harmonyos-md-reader 的 Android 移植版(由 HarmonyOS 1.1.4 版本逐项对齐实现)。打开 .md 文件即可阅读:完整 Markdown 语法、表格列宽自适应、Mermaid 图表离线渲染、系统 TTS 语音朗读与 MP3 导出。

✨ 核心特性

类别 能力
🔒 隐私 不申请任何权限(无存储、无网络、无位置、无通讯录);AndroidManifest.xml 中 uses-permission 数量为 0
🌐 离线 Markdown 解析、Mermaid 渲染、语音朗读、MP3 编码 100% 在设备本地完成,无任何远端调用
📝 Markdown 标题 / 段落 / 列表 / 引用 / 代码块 / 分割线 / 图片 / 链接 / 表格
📊 表格 列宽自适应(与鸿蒙端、WEB 端共享同一套列宽常量),同行等高、超宽横向滚动
🧜 图形 ```mermaid 围栏块离线渲染为 SVG;内置 SVG 净化器(SvgSanitizer)剔除脚本与事件属性
🔍 图形全屏 点击图形进入全屏查看,支持缩放与拖动
🔊 语音朗读 调用系统 TTS(TextToSpeech)逐句合成播放,支持语速/音色设置、断点续读;朗读脚本由 ReadScript 从 Markdown 结构生成(跳过代码块与纯符号行)
💾 MP3 导出 逐句 synthesizeToFile → 解析 RIFF/WAVE → 分块 PCM → WebView 内 lamejs 编码 → SAF 流式落盘;不引入 NDK、不新增权限,内存峰值恒定(单段上限 64KB)
🎛 三态视图 预览 / 源码 / 分屏,源码编辑实时同步预览
🗂 打开本地文件 系统文件选择器(SAF)+ 系统"用其他应用打开"(VIEW intent,支持 text/markdown、text/plain)
🎨 主题 浅色/深色跟随系统;字号、行距、页边距可调
ℹ️ 关于页 品牌区 / 定位语 / 可点击署名 / 版本历史(从 CHANGELOG 提取)

📁 项目结构

android-md-reader/
├── app/
│   ├── build.gradle.kts              # 应用模块(compileSdk 35 / minSdk 26 / targetSdk 34)
│   ├── proguard-rules.pro            # release 混淆规则入口
│   └── src/main/
│       ├── AndroidManifest.xml       # 零 uses-permission;仅一个 Activity + VIEW intent
│       ├── assets/
│       │   ├── demo.md               # 内置示例文档(首屏加载)
│       │   ├── graph.html            # Mermaid 渲染宿主页(WebView)
│       │   ├── mermaid.min.js        # Mermaid 离线渲染引擎(MIT)
│       │   ├── mp3enc.html           # MP3 编码宿主页(WebView)
│       │   └── lamejs.js             # LAME MP3 编码器(LGPL-3.0,见 NOTICE)
│       ├── java/com/bzm/mdreader/android/
│       │   ├── MainActivity.kt       # 入口 Activity + 状态编排
│       │   ├── core/
│       │   │   ├── MarkdownParser.kt     # Markdown → 块结构(与鸿蒙端同源逻辑)
│       │   │   ├── SvgSanitizer.kt       # SVG 净化(去 script / on* 事件属性)
│       │   │   ├── ReadScript.kt         # 朗读脚本生成与时长估算
│       │   │   ├── TtsPlayer.kt          # 系统 TTS 编排(逐句合成 / 播放 / 流控)
│       │   │   ├── AudioExporter.kt      # WAV → MP3 流式导出编排
│       │   │   └── Mp3EncoderBridge.kt   # WebView + lamejs 编码桥
│       │   └── ui/
│       │       ├── ReaderScreen.kt       # 阅读主界面与手势
│       │       ├── ReadCard.kt           # 朗读卡片(进度 / 控制)
│       │       ├── MarkdownRender.kt     # 块级渲染
│       │       ├── GraphView.kt          # 图形内联渲染
│       │       ├── GraphFullScreen.kt    # 图形全屏查看
│       │       ├── SettingsDialog.kt     # 设置弹窗
│       │       └── AboutDialog.kt        # 关于页
│       └── res/                          # 图标 / 主题 / 字符串
├── build.gradle.kts                  # 根构建脚本(AGP 8.7.3 / Kotlin 2.0.21)
├── settings.gradle.kts
└── gradle.properties

🚀 快速开始

环境要求

组件 版本
JDK 17(compileOptions / jvmTarget 均为 17)
Gradle 8.9+
Android Gradle Plugin 8.7.3
Kotlin 2.0.21
Android SDK compileSdk 35、build-tools 35,minSdk 26(Android 8.0)

构建

# 1. 指定 Android SDK 位置(该文件已被 .gitignore 排除)
echo "sdk.dir=/path/to/Android/sdk" > local.properties

# 2. Debug 包(首次执行会按 gradle-wrapper.properties 下载 Gradle 8.9)
./gradlew :app:assembleDebug          # Windows: gradlew.bat :app:assembleDebug
# 产物:app/build/outputs/apk/debug/app-debug.apk

# 3. Release 包(需自行配置签名,见下)
./gradlew :app:assembleRelease

签名(Release)

仓库不包含任何签名材料。请自行生成 keystore 并在 app/build.gradle.kts 的 android { signingConfigs { ... } } 中配置,或使用 ~/.gradle/gradle.properties 注入口令:

MDREADER_STORE_FILE=/absolute/path/to/your.jks
MDREADER_STORE_PASSWORD=******
MDREADER_KEY_ALIAS=your_alias
MDREADER_KEY_PASSWORD=******

⚠️ 切勿把 .jks / .keystore / 口令写入仓库——.gitignore 已排除常见签名文件与 local.properties。

🔐 隐私说明

  • 应用不申请任何系统权限(AndroidManifest.xml 无 uses-permission 节点)。
  • 打开文件使用系统文件选择器 / ACTION_VIEW,由系统(SAF)授权单次读取,应用自身无存储权限。
  • 不访问网络:代码中不存在任何 HTTP/Socket 客户端;mermaid.min.js 与 lamejs.js 均为随包内置。
  • 不采集、不上报任何数据;无第三方统计 SDK、无广告 SDK。
  • 导出的 MP3 / 另存的 Markdown 全部经系统文件选择器由用户指定落盘位置。

🧩 与其它端的关系

端 仓库 形态
HarmonyOS harmonyos-md-reader ArkTS / ArkUI
HarmonyOS(彻底本地化分支) harmonyos-md-reader-lite ArkTS / ArkUI
Android 本仓库 Kotlin + Jetpack Compose
WEB md-reader-web 原生 JS + HTML + CSS

三端的解析规则、表格列宽常量、图形渲染策略保持一致,行为可交叉验证。

📄 许可证

本项目采用 Apache License 2.0,详见 LICENSE。

第三方组件:assets/mermaid.min.js(MIT)、assets/lamejs.js(LGPL-3.0)——详见 NOTICE。

assets/lamejs.js 与 assets/mp3enc.html 仅服务于「导出 MP3」这一可选特性。若不需要该特性,删除这两个文件并移除 ui/SettingsDialog.kt 中对应入口即可,其余功能不受影响。

Introduction

Android 离线 Markdown 阅读器:Kotlin + Jetpack Compose,零权限/零网络/零收集,支持 Mermaid 离线渲染、系统 TTS 朗读与 MP3 导出(不引入 NDK)

Customize your domain