DEV Community

Vishal Solanki
Vishal Solanki

Posted on Edited on

I built an Android file viewer that has no internet permission

Most file viewer apps I tried on Android wanted access to all my storage, showed ads between pages, or asked me to sign in just to open a PDF someone sent me on WhatsApp. So I built my own. It's called Folio, it's free, and the one rule I set on day one was simple: the app gets no INTERNET permission. Not "we don't collect data". Android itself won't let it open a socket.

That one rule shaped almost every decision after it. Here's what it was like to build.

What it opens

  • PDF, with search and password-protected files
  • Word (.docx), Excel (.xlsx) and PowerPoint (.pptx)
  • CSV, TXT, Markdown, logs, subtitles, contacts (.vcf) and calendars (.ics)
  • JSON, XML, YAML, HTML and 40+ programming languages with syntax colours
  • Images including HEIC, AVIF and SVG
  • Audio and video
  • ZIP files: browse them and open what's inside

Text, Markdown, CSV and code can be edited. Word, Excel and PowerPoint stay view-only on purpose. I'd rather show you a slightly simplified slide than ship an editor that quietly breaks your layout when you save.

No storage permission either

Folio also doesn't ask for storage access. It only sees files you open with it (from WhatsApp, Gmail or the Files app), files you pick inside it, or folders you add yourself. All of that goes through Android's Storage Access Framework, so access is per file or per folder, and you can take it back.

The catch: a file can reach the app under several different URIs. The Downloads provider alone has more than one form. So Recents has to dedupe by name, size and type, or the same PDF shows up three times.

The stack

Kotlin and Jetpack Compose, one app module, no backend because there can't be one.

  • PDF: PDFium, the engine Chrome uses. All rendering runs on a single background thread so renders, search and close never overlap. Pages re-render sharper after you zoom, with a cap of about 8 MP per page so memory stays sane on a 200-page file.
  • Word: mammoth converts .docx to HTML, shown in a locked-down WebView. Mammoth didn't work on Android out of the box (Android's XML parser rejects one of the features it sets), so I ship a patched copy of one small class.
  • Excel: my own streaming XLSX reader. The grid draws each row in one pass instead of one composable per cell, which is the difference between smooth and unusable on a 50,000-row CSV.
  • PowerPoint: my own PPTX reader. Getting text styles right meant following inheritance from shape to layout to master, which was most of the work.
  • Code and text: Sora Editor with TextMate grammars from VS Code.
  • Images and media: Coil (without its network module) and Media3 ExoPlayer.

The WebView used for Word and HTML has JavaScript off, network loads blocked, and file access off. HTML files also get their scripts stripped before they're shown. If a page needs scripts, there's an "Open in browser" option that says so before you tap it.

Features you can't build the normal way offline

Some things every app has turned out to be interesting without internet.

Feedback. There's no API to call, so "Send feedback" opens an email draft in your mail app. You read it and decide whether to send it.

Crash reports. When the app crashes, it writes the stack trace to a local file. Next launch, it asks if you want to email it. Nothing leaves the phone unless you press send.

Updates. No push, no background checks. "Check for updates" opens my website in your browser with your installed version in the URL, and the page tells you if there's something newer. The page does the comparison in your browser, so the site stays static.

Shipping without the Play Store

I can't pay for a Play developer account right now, so Folio ships as an APK on GitHub Releases. Things I learned doing that:

  • The signing key is the app. Without Play App Signing, every update must be signed with the same key forever. Lose it and every user has to uninstall to update. Mine is backed up in two places.
  • Chrome can sit at 100% on APK downloads. It runs a safety check after the download finishes and can hang there. Closing the download panel and opening Chrome's Downloads usually unsticks it. Other browsers like Brave don't do it.
  • Play Protect will warn people. It says "App scan recommended" for any app it hasn't seen. My download page shows every warning screen in advance so nobody is surprised.
  • Obtainium can track GitHub releases and update the app automatically, which is the closest thing to auto-update outside the Play Store.

Try it

Folio needs Android 8.0 or newer and is about 25 MB. Screenshots, the download and step-by-step install instructions are here:

Download Folio

Built this because I was tired of file viewers full of ads and permissions. If you've felt the same, I hope it helps.

It's my first public app, so if it fails on one of your files or there's something you'd want it to do, let me know. There's a feedback form on the page, and I read all of it.

Top comments (0)