A tiny Android share-target app that reroutes any link you share through archive.is and renders the result in a built-in reader. Reader mode is the default, not an opt-in per article.
Share a link to Skip Paywall from any app. It:
- Rewrites the URL to
https://archive.is/newest/<url>, which usually bypasses the paywall. - Loads the archived page in an in-app
WebView. - The moment the DOM has real content, runs Mozilla's Readability.js and auto-renders a clean reader view.
- Toolbar actions: Show original (drop to raw archive), Open in browser (bounce the link to your chosen browser), Share.
Most browsers treat reader mode as opt-in, one article at a time. If you've deliberately shared a link through an archive-bypass app, reader mode is almost always what you wanted — so it's the default, and the toggle is the escape hatch.
Not on the Play Store. Build and sideload.
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apkMin Android 8.0 (API 26), target SDK 34, compileSdk = 34, Kotlin 2.0, JVM target 17.
Three activities, framework-only, no AndroidX.
| Activity | Purpose |
|---|---|
ShareActivity |
Invisible (Theme.NoDisplay) share target filtering ACTION_SEND / text/plain. Extracts the URL via Patterns.WEB_URL, builds the archive.is/newest/<url> URL, hands to the reader. |
ArchiveReaderActivity |
One WebView with a three-state machine (Loading / Original / Reader). |
MainActivity |
Launcher icon; description + browser picker for the "Open in browser" toolbar action. |
onPageStartedinjects a small watcher script into the page. The watcher usesMutationObserver+DOMContentLoaded+ short-interval polling, and fires a single callback via a@JavascriptInterfacebridge the momentdocument.body.innerTextcrosses a content-length threshold and the page doesn't look like a Cloudflare challenge.- On bridge callback, native immediately runs
Readability.parse()against several candidate subtrees — archive-is-specific containers (#CONTENT,.row), semantic tags (article,main), then the full document — and picks the candidate producing the longest article body. - Successful extraction: renders the article with a minimal template via
loadDataWithBaseURL(system font, ~38em column, respectsprefers-color-scheme). - Challenge / no-parse / too-short result: silently retries every 1.5s, up to 16 times. A 6s ceiling timer from
onPageStartedis a belt-and-suspenders fallback in case the watcher never fires.
- Legacy Android framework (
android.useAndroidX=false), zero third-party Gradle dependencies.Readability.jsis vendored atapp/src/main/assets/readability.js. - Kotlin sources live at
app/src/main/kotlin/(not the defaultsrc/main/java/), configured viasourceSetsinapp/build.gradle.kts.
- archive.is periodically serves Cloudflare challenges that
WebViewcan't auto-solve; the user interacts with them inline. - Some archive snapshots bury the article in structures Readability doesn't extract cleanly; extraction can fall back to the outer wrapper.
- No font-size controls, no scroll-position persistence, no offline cache.
- No support for archive snapshots served inside a cross-origin
<iframe>(Readability can't cross frame boundaries).
- Readability.js by Mozilla (Apache 2.0) — article extraction engine, vendored in
app/src/main/assets/readability.jswith upstream license header intact. - archive.is — the archive service this app routes through (not affiliated).