Gander: An Android File Viewer with Zero Permissions
Most Android phones ship with a dozen half-viewers that bounce documents to cloud services. Gander is the opposite: a tiny, open-source, fully offline file viewer that opens PDF, Word, Excel, PowerPoint, photos, videos, audio, Markdown, text, and code in one app. It requires zero permissions, has no ads, no tracking, and no internet access at all. The APK is about 15 MB.
The project, hosted on GitHub, was recently posted on Hacker News with 15 points and 8 comments. Its tagline: "Take a gander at any file."
The Zero-Permission Trick
Gander receives files through the Storage Access Framework (SAF) and "Open with" intents. 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.
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.
Supported Formats and Renderers
The app supports a wide range of formats, each rendered by a specific library:
- PDF: Pdfium (native)
- Word .docx: docx-preview, offline in a sandboxed WebView
- Spreadsheets (.xlsx .xls .xlsm .xlsb .csv .ods): SheetJS, offline
- Slides (.pptx): PPTXjs, offline
- Photos: JPG, PNG, WebP, BMP, HEIC/HEIF via tiled deep-zoom image view, EXIF aware; GIF (animated), SVG, AVIF, ICO via WebView
- Video: MP4, M4V, MOV, MKV, WebM, 3GP, AVI, FLV, MPEG-TS via Media3 ExoPlayer
- Audio: MP3, M4A, AAC, FLAC, WAV, OGG, Opus, AMR via Media3 ExoPlayer
- Markdown: .md rendered as formatted HTML via marked + DOMPurify, offline
- Text and code: .txt .json .xml logs, most source files via a text viewer
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.
Key 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+
Build from Source
Requirements: JDK 17+ and the Android SDK (platform 35).
./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"
The keystore is gitignored on purpose: it is a personal signing key and must never land in a public repo.
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).
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).
Installation and Updates
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. Optional: Play Protect may warn about an unknown developer; that is what sideloaded open source looks like. Tap "Install anyway".
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.
Roadmap
- F-Droid listing
- Legacy .doc / .ppt support if a usable offline renderer appears
- iOS companion (thin QuickLook wrapper)
Why This Matters
Gander addresses a fundamental privacy gap in mobile file viewing. Most apps either request broad storage permissions or upload your documents to cloud services for processing. By leveraging SAF and a sandboxed WebView, Gander proves that a fully offline, zero-permission viewer is possible. For developers, it's a model of how to build privacy-respecting Android apps without sacrificing functionality.
Editor's Take
I've been burned by document viewers that phone home with my files. The zero-permission approach is refreshing, and the technical execution is solid. I particularly appreciate the use of WebViewAssetLoader to intercept requests, ensuring no network calls even if a library tries. The lack of legacy .doc support is a minor annoyance, but the clear explanation and suggestion to re-save as .docx is pragmatic. I'd love to see this on F-Droid soon; that would make it a must-have for privacy-conscious users.
