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.
Every phone ships with a dozen half-viewers that bounce your documents to cloud services. Gander is the opposite: one small APK (about 8 MB) that renders everything on the device. It cannot phone home because it does not even hold the INTERNET permission.
arjun.maniyani.com/gander · Privacy policy
| Home: recents and folders | Photos | |
|---|---|---|
![]() |
![]() |
![]() |
| Word (.docx) | PowerPoint (.pptx) | Excel (.xlsx) |
|---|---|---|
![]() |
![]() |
![]() |
- 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
- Checks its own promise: the About screen asks Android what the app requests and shows you the answer, next to the full licence text for every bundled library
- Modern Android: Material 3, dark mode, edge to edge, works on Android 8.0+
| Category | Formats | Renderer |
|---|---|---|
| Documents | pdf.js, offline in a sandboxed WebView | |
Word .docx |
docx-preview, offline in a sandboxed WebView | |
| Spreadsheets | .xlsx .xls .xlsm .xlsb .csv .ods |
SheetJS, offline |
| Slides | PowerPoint .pptx |
PPTXjs, offline |
| Photos | JPG, PNG, WebP, BMP, HEIC/HEIF | Tiled deep-zoom image view, EXIF aware |
| GIF (animated), SVG, AVIF, ICO | WebView | |
| Video | MP4, M4V, MOV, MKV, WebM, 3GP, AVI, FLV, MPEG-TS | Media3 ExoPlayer |
| Audio | MP3, M4A, AAC, FLAC, WAV, OGG, Opus, AMR | Media3 ExoPlayer |
| Markdown | .md rendered as formatted HTML |
marked + DOMPurify, offline |
| Text and code | .txt .json .xml logs, most source files |
Text viewer |
Anything else, including files with no extension at all, offers View as text, which shows the raw contents without renaming the file. Large files load 5 MB at a time with a Show more button, so they open instantly and can still be read end to end.
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.
Runs on Android 8.0 (API 26) and up.
Viewing PDFs also needs Android System WebView 125 or newer (May 2024). Any phone still receiving WebView updates is well past that; if yours is not, Gander says so when you open a PDF rather than failing quietly.
- Download the latest APK from Releases:
Gander-x.y.apkruns on every architecture, since the app ships no native code. - 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.
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.apkSigning 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
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.
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.
To build it yourself you need JDK 17+ and the Android SDK (platform 36). These are build requirements only. The installed app runs on Android 8.0 (API 26) and up.
./gradlew assembleDebug # installable debug build
./gradlew assembleRelease # unsigned without a keystoreRelease signing expects a local, untracked keystore at keystore/gander.jks,
alias gander. Generate your own with:
keytool -genkeypair -keystore keystore/gander.jks -alias gander \
-keyalg RSA -keysize 2048 -validity 10000 \
-storepass gander-local -keypass gander-local -dname "CN=Gander"That builds and signs with no further setup, because gander-local is the
fallback password in app/build.gradle.kts. To use a different one, set it in
~/.gradle/gradle.properties rather than in the build file:
GANDER_STORE_PASSWORD=…
GANDER_KEY_PASSWORD=…The keystore is gitignored on purpose: it is a personal signing key and must never land in a public repo. Neither should its password, which is why the real one lives outside the tree. Builds signed with your own key will not update an install of a release from here; the official signing certificate is above.
ViewerActivity routes by file extension first, MIME type second (FileKind.kt),
into one of three surfaces: 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/), PDF included. Documents
under 16 MB are handed to the WebView whole; larger ones are served in ranges so
only the pages being read are held in memory. 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: pdf.js (Apache-2.0), 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). The app ships no native code.
- F-Droid listing
- Legacy
.doc/.pptsupport if a usable offline renderer appears - iOS companion (thin QuickLook wrapper)
Issues and small PRs are welcome, see CONTRIBUTING.md. If Gander is useful to you, a star helps other people find it.
MIT, Copyright (c) 2026 Arjun Maniyani.
Vendored viewer libraries keep their own licenses, listed above; all are
MIT/Apache/BSD and compatible. The full text of every one of them ships inside
the app, in app/src/main/assets/licences.md, reachable from About.







