Show HN: Gander, an Android file viewer that asks for no permissions

Show HN: Gander, an Android file viewer that asks for no permissions

Gander 🪿 Take a gander at any file. A tiny, open source, fully offline file viewer for Android that opens PDF, Word (.docx), Excel, PowerPoint (.pptx), photos, videos, audio, Markdown, text and code in one app, with zero permissions, no ads, no tracking and no internet access at all.

Gander 🪿 随心查看任何文件。这是一款小巧、开源且完全离线的 Android 文件查看器,可以在一个应用内打开 PDF、Word (.docx)、Excel、PowerPoint (.pptx)、照片、视频、音频、Markdown、文本和代码文件。它无需任何权限、无广告、无追踪,且完全无法访问互联网。

Every phone ships with a dozen half-viewers that bounce your documents to cloud services. Gander is the opposite: one small APK (about 15 MB) that renders everything on the device. It cannot phone home because it does not even hold the INTERNET permission.

每部手机都预装了十几个“半吊子”查看器,它们会将你的文档上传到云端服务。Gander 则完全相反:它是一个小巧的 APK(约 15 MB),所有内容均在设备本地渲染。它无法向外发送数据,因为它甚至没有申请“互联网”权限。

Screenshots

截图

  • Home: recents and folders

  • Folder browsing

  • PDF

  • Word (.docx)

  • PowerPoint (.pptx)

  • Excel (.xlsx)

  • 主页:最近文件与文件夹

  • 文件夹浏览

  • PDF

  • Word (.docx)

  • PowerPoint (.pptx)

  • Excel (.xlsx)

Features

功能特性

  • One viewer for everything: documents, spreadsheets, slides, images, video, audio, Markdown, code

  • Pinch zoom and smooth scrolling everywhere, with deep zoom into huge photos (tiled decoding)

  • Recent files with thumbnail previews (image, video frame, PDF first page)

  • Folder browsing through one-time system grants, still without any storage permission

  • Share sheet and “Open with” integration: share a file from any app (chat, mail, browser) into Gander, or tap it in a file manager

  • Find in document: search inside Word, Excel, slides, Markdown, text and code with match navigation

  • Share and locate: send the open file to any app, or jump to its folder in the file manager

  • Private by construction: no permissions, no INTERNET, no analytics, no accounts, nothing leaves the phone

  • Modern Android: Material 3, dark mode, edge to edge, works on Android 8.0+

  • 万能查看器: 支持文档、电子表格、幻灯片、图片、视频、音频、Markdown 和代码。

  • 全方位缩放与平滑滚动: 支持对超大图片进行深度缩放(平铺解码)。

  • 带缩略图预览的最近文件: 支持图片、视频帧及 PDF 首页预览。

  • 通过系统一次性授权浏览文件夹: 无需任何存储权限。

  • 共享表单与“打开方式”集成: 可从任何应用(聊天、邮件、浏览器)分享文件至 Gander,或在文件管理器中直接点击打开。

  • 文档内查找: 支持在 Word、Excel、幻灯片、Markdown、文本和代码中搜索并导航匹配项。

  • 分享与定位: 可将打开的文件发送至任何应用,或在文件管理器中跳转至其所在文件夹。

  • 原生隐私保护: 无权限、无互联网、无分析、无账户,没有任何数据离开手机。

  • 现代 Android 特性: Material 3 设计、深色模式、沉浸式布局,支持 Android 8.0+。

Supported formats

支持格式

CategoryFormatsRenderer
DocumentsPDFPdfium (native)
DocumentsWord .docxdocx-preview, offline in a sandboxed WebView
Spreadsheets.xlsx .xls .xlsm .xlsb .csv .odsSheetJS, offline
SlidesPowerPoint .pptxPPTXjs, offline
PhotosJPG, PNG, WebP, BMP, HEIC/HEIFTiled deep-zoom image view, EXIF aware
PhotosGIF (animated), SVG, AVIF, ICOWebView
VideoMP4, M4V, MOV, MKV, WebM, 3GP, AVI, FLV, MPEG-TSMedia3 ExoPlayer
AudioMP3, M4A, AAC, FLAC, WAV, OGG, Opus, AMRMedia3 ExoPlayer
Markdown.md rendered as formatted HTMLmarked + DOMPurify, offline
Text and code.txt .json .xml logs, most source filesText viewer
分类格式渲染引擎
文档PDFPdfium (原生)
文档Word .docxdocx-preview, 沙盒 WebView 离线渲染
电子表格.xlsx .xls .xlsm .xlsb .csv .odsSheetJS, 离线
幻灯片PowerPoint .pptxPPTXjs, 离线
照片JPG, PNG, WebP, BMP, HEIC/HEIF平铺深度缩放视图, 支持 EXIF
照片GIF (动图), SVG, AVIF, ICOWebView
视频MP4, M4V, MOV, MKV, WebM, 3GP, AVI, FLV, MPEG-TSMedia3 ExoPlayer
音频MP3, M4A, AAC, FLAC, WAV, OGG, Opus, AMRMedia3 ExoPlayer
Markdown.md 渲染为格式化 HTMLmarked + DOMPurify, 离线
文本与代码.txt .json .xml 日志, 大多数源码文件文本查看器

Legacy binary .doc and .ppt are not supported (no faithful offline renderer exists); the app explains this and suggests re-saving as .docx / .pptx. Binary .xls works.

旧版二进制格式 .doc 和 .ppt 不受支持(目前不存在可靠的离线渲染器);应用会提示用户将其另存为 .docx / .pptx。二进制 .xls 格式则可以正常工作。

Install

安装

Runs on Android 8.0 (API 26) and up. Download the latest APK from Releases: Gander-x.y-arm64.apk fits practically every phone from 2017 onward (use the universal APK for very old or x86 devices). Copy it to your phone, tap it, and allow “install unknown apps” when asked.

支持 Android 8.0 (API 26) 及以上版本。请从 Releases 下载最新的 APK:Gander-x.y-arm64.apk 适用于 2017 年以后的几乎所有手机(极旧设备或 x86 设备请使用通用版 APK)。将其复制到手机,点击安装,并在提示时允许“安装未知来源应用”。

Optional: Play Protect may warn about an unknown developer; that is what sideloaded open source looks like. Tap “Install anyway”.

可选:Play 保护机制可能会提示开发者未知;这是侧载开源软件的常见现象。点击“仍然安装”即可。

Updating: install the new APK over the old one; recents and folder grants survive. Automatic updates without a store: install Obtainium and add https://github.com/mokshablr/gander as an app source. It follows the tagged GitHub releases here and updates Gander like a store would.

更新:直接覆盖安装新版 APK 即可;最近文件记录和文件夹授权会保留。若需在无应用商店的情况下自动更新:安装 Obtainium 并添加 https://github.com/mokshablr/gander 作为应用源。它会追踪 GitHub 上的标签发布,像应用商店一样更新 Gander。

Verify before installing: every release is signed with the same key, so you can confirm an APK really came from this repo. Obtainium can pin the fingerprint below, and for a file you have already downloaded: apksigner verify --print-certs Gander-x.y-arm64.apk

安装前验证:每个版本都使用相同的密钥签名,因此你可以确认 APK 确实来自此仓库。Obtainium 可以固定下方的指纹信息。对于已下载的文件,可使用命令:apksigner verify --print-certs Gander-x.y-arm64.apk

Signing certificate SHA-256: 5B:5C:F6:4A:94:23:7C:D5:F0:E0:85:76:00:38:BC:1C:EB:DF:18:DA:BA:5C:B3:EA:CA:7C:15:9F:22:A7:E2:4B

签名证书 SHA-256: 5B:5C:F6:4A:94:23:7C:D5:F0:E0:85:76:00:38:BC:1C:EB:DF:18:DA:BA:5C:B3:EA:CA:7C:15:9F:22:A7:E2:4B

How the zero-permission trick works

“零权限”技巧是如何实现的

Gander receives files through the Storage Access Framework and “Open with” intents, so the OS hands it exactly the documents you chose and nothing else. Office formats render inside a locked-down WebView whose every request is intercepted by WebViewAssetLoader: bundled JS libraries load from app assets and the document streams from the content URI. No network stack is ever touched, and the app does not declare the INTERNET permission, so there is nothing to audit or trust.

Gander 通过存储访问框架 (SAF) 和“打开方式”意图接收文件,因此操作系统只会将你选定的文档交给它,不会泄露其他内容。Office 格式在受限的 WebView 中渲染,其所有请求均被 WebViewAssetLoader 拦截:捆绑的 JS 库从应用资源加载,文档则通过内容 URI 流式传输。应用从不触碰网络栈,且未声明 INTERNET 权限,因此无需审计或信任任何网络行为。

Folder browsing uses ACTION_OPEN_DOCUMENT_TREE grants. Note that Android itself refuses to grant the Downloads root to any app; grant Documents, DCIM or a subfolder of Downloads instead.

文件夹浏览使用 ACTION_OPEN_DOCUMENT_TREE 授权。请注意,Android 系统本身拒绝向任何应用授予“下载”根目录的权限;请改为授权“文档”、“DCIM”或“下载”文件夹下的子目录。

Build from source

从源码构建

To build it yourself you need JDK 17+ and the Android SDK (platform 35). These are build requirements only. The installed app runs on Android 8.0 (API 26) and up.

若要自行构建,你需要 JDK 17+ 和 Android SDK (platform 35)。这些仅为构建要求,安装后的应用可在 Android 8.0 (API 26) 及以上版本运行。

./gradlew assembleDebug # installable debug build
./gradlew assembleRelease # unsigned without a keystore

Release signing expects a local, untracked keystore at keystore/gander.jks (store and key password gander-local, alias gander); generate one with: keytool -genkeypair -keystore keystore/gander.jks -alias gander \ -keyalg RSA -keysize 2048 -validity 10000 \ -storepass gander-local -keypass gander-local -dname “CN=Gander”

发布签名需要一个本地的、未被 git 追踪的密钥库文件 keystore/gander.jks(存储和密钥密码均为 gander-local,别名为 gander);使用以下命令生成: keytool -genkeypair -keystore keystore/gander.jks -alias gander -keyalg RSA -keysize 2048 -validity 10000 -storepass gander-local -keypass gander-local -dname "CN=Gander"

The keystore is gitignored on purpose: it is a personal signing key and must never land in a public repo.

密钥库被故意加入 .gitignore:这是个人签名密钥,绝不能上传到公共仓库。

Architecture in one paragraph

架构简述

ViewerActivity routes by file extension first, MIME type second (FileKind.kt), into one of four surfaces: a native Pdfium view for PDF, a tiled SubsamplingScaleImageView for photos, Media3 ExoPlayer for video and audio, or a sandboxed WebView for everything rendered by vendored JS libraries (app/src/main/assets/viewer/). The home screen (MainActivity) lists recents (persisted SAF grants) and granted folders (DocumentsContract child queries), with thumbnails generated off-thread and cached (Thumbs.kt).

ViewerActivity 首先根据文件扩展名,其次根据 MIME 类型(FileKind.kt)进行路由,将其导向四个界面之一:用于 PDF 的原生 Pdfium 视图、用于照片的平铺 SubsamplingScaleImageView、用于音视频的 Media3 ExoPlayer,或用于由第三方 JS 库渲染内容的沙盒 WebView(app/src/main/assets/viewer/)。主屏幕(MainActivity)列出最近文件(持久化的 SAF 授权)和已授权文件夹(DocumentsContract 子查询),缩略图在后台线程生成并缓存(Thumbs.kt)。

Vendored viewer libraries and their licenses: JSZip (MIT), docx-preview (Apache-2.0), SheetJS CE (Apache-2.0), PPTXjs + divs2slides (MIT), jQuery 1.11 (MIT), D3 3.x + NVD3 (BSD/Apache), marked (MIT), DOMPurify (Apache-2.0/MPL).

第三方查看器库及其许可证:JSZip (MIT), docx-preview (Apache-2.0), SheetJS CE (Apache-2.0), PPTXjs + divs2slides (MIT), jQuery 1.11 (MIT), D3 3.x + NVD3 (BSD/Apache), marked (MIT), DOMPurify (Apache-2.0/MPL)。

Roadmap

路线图

  • F-Droid listing

  • Legacy .doc / .ppt support if a usable offline renderer appears

  • iOS companion (thin QuickLook wrapper)

  • 上架 F-Droid

  • 若出现可用的离线渲染器,将支持旧版 .doc / .ppt

  • iOS 伴侣应用(轻量级 QuickLook 封装)

Contributing

贡献

Issues and small PRs are welcome, see CONTRIBUTING.md. If Gander is useful to you, a star helps other people find it.

欢迎提交 Issue 和小型 PR,请参阅 CONTRIBUTING.md。如果 Gander 对你有帮助,点个 Star 可以让更多人发现它。

License

许可证

MIT. Vendored viewer libraries keep their own licenses, listed above; all are MIT/Apache/BSD and compatible.

MIT 许可证。第三方查看器库保留其各自的许可证(如上所列);所有许可证均为 MIT/Apache/BSD 且相互兼容。