Phandroid — the Phanpy Mastodon web client, wrapped as a native Android app with Capacitor. Install via Obtainium; see the README.
  • JavaScript 80.6%
  • CSS 18.4%
  • Kotlin 0.6%
  • Shell 0.1%
  • HTML 0.1%
  • Other 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-06 08:22:33 +00:00
.forgejo/workflows fix: give each channel its own F-Droid listing, independent of the checkout 2026-09-05 21:55:55 +00:00
.github feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
android chore(release): bump to 2.0.45 (auto, upstream merge) 2026-09-06 08:22:33 +00:00
assets feat(android): branded adaptive launcher icon and splash screens 2026-07-07 18:42:24 +02:00
compose feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
design feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
fastlane/metadata/android feat(dev): distinct launcher + F-Droid icon for the dev channel 2026-07-26 20:37:16 +00:00
fdroid fix: give each channel its own F-Droid listing, independent of the checkout 2026-09-05 21:55:55 +00:00
public feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
readme-assets feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
scripts Merge remote-tracking branch 'upstream/main' 2026-09-04 08:18:37 +00:00
src Merge remote-tracking branch 'upstream/main' 2026-09-06 08:17:30 +00:00
tests Possibly fix issues with playwright 2026-08-18 13:48:58 +08:00
.env fix: privacy policy, native localisation, pruning, watcher state, failure reporting 2026-08-22 16:10:13 +00:00
.env.production feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
.gitattributes fix: resolve package.json by computation instead of line-based merge 2026-08-16 21:14:43 +00:00
.gitignore chore: gitignore mail.env (never commit mail config) 2026-07-09 15:43:27 +02:00
.oxfmtrc.json feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
.release.env.example fix(dist): release-gitea.sh works on bash 3.2 + auto-loads token 2026-07-08 10:24:40 +02:00
capacitor.config.json release: 2.0.0 — rename applicationId to dev.umrath.android.phanpy; drop self-host refs 2026-07-11 07:23:33 +00:00
CHANGELOG.md chore(release): bump to 2.0.45 (auto, upstream merge) 2026-09-06 08:22:33 +00:00
CHANGELOG.phanpy.md feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
crowdin.yml feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
env.schema.json feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
i18n-volunteers.json feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
index.html feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
LICENSE Initial commit 2026-07-07 17:48:47 +02:00
lingui.config.js feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
package-lock.json chore(release): bump to 2.0.42 (auto, upstream merge) 2026-09-02 08:23:41 +00:00
package.json Merge remote-tracking branch 'upstream/main' 2026-09-02 08:18:31 +00:00
PHANDROID_CUSTOMIZATIONS.md fix: privacy policy, native localisation, pruning, watcher state, failure reporting 2026-08-22 16:10:13 +00:00
playwright.config.js feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
PRIVACY.MD fix: privacy policy, native localisation, pruning, watcher state, failure reporting 2026-08-22 16:10:13 +00:00
README.md Update README.md 2026-08-30 00:03:52 +00:00
rollbar.js security: drop inherited Phanpy Rollbar client token from rollbar.js 2026-07-23 16:41:43 +00:00
SECURITY.md feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
vite.config.js Weird fix 2026-09-02 14:36:35 +08:00
wrangler.jsonc feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00

Phandroid

This is a fork of Phanpy, with the goal of making it installable as an Android app.

It uses Capacitor to wrap the Phanpy web app into a native Android app — the same approach iPhanpy takes for iOS. Rather than reimplementing the UI natively, Phandroid ships the proven Phanpy web client inside an Android WebView shell and adds a thin, well-isolated layer of Android-specific tweaks (deep-link OAuth, native camera, in-app browser, hardware back button, edge-to-edge insets).

Built with LLM: this Android port — the Capacitor integration, the Android-specific override layer and the surrounding tooling — was created with the assistance of a large language model.

Status: released and installable from the self-hosted F-Droid repository at fdroid.umrath.dev — works with F-Droid clients and Obtainium (see Installation). Supports OAuth login, native camera, an in-app browser, an Android share target, edge-to-edge UI and optional FOSS push (UnifiedPush). See CHANGELOG.md and PHANDROID_CUSTOMIZATIONS.md for details.

Channels

Phandroid ships as two side-by-side apps, each tracking a different Phanpy branch. Install either — or both; they don't conflict (separate app id, data and OAuth scheme).

Phandroid (stable) Phandroid Dev (bleeding)
applicationId dev.umrath.android.phanpy dev.umrath.android.phanpy.dev
OAuth scheme phandroid:// phandroiddev://
tracks Phanpy production Phanpy main
updates curated releases — F-Droid repo / Obtainium automatic, every upstream change — F-Droid repo / Obtainium

Start with Phandroid. Phandroid Dev sees new Phanpy changes sooner but may break more often; it installs next to the stable app with its own accounts and settings.

Installation

⚠️ Upgrading from a pre-2.0.0 build? Reinstall required. Version 2.0.0 changes the app package id to dev.umrath.android.phanpy. Android treats the new package as a different app, so it cannot update in place: uninstall the old Phandroid, then install this one from the F-Droid repository below. Logged-in accounts, settings and push registration do not transfer and must be set up again (the signing key and the phandroid:// login are unchanged). If you added the app in Obtainium from the old source, remove it there and re-add it from the F-Droid repository below.

Phandroid is distributed as a signed APK — not on the Play Store.

  1. Install Obtainium (from F-Droid or its GitHub releases).

  2. In Obtainium tap Add App, choose the source type F-Droid Third-Party Repo, and paste the URL for the channel you want:

    https://fdroid.umrath.dev/repo?appId=dev.umrath.android.phanpy
    
  3. Tap Add, then Install — this gives you the stable Phandroid, updated automatically.

To follow Phandroid Dev (instead of, or alongside, the stable app), add a second app the same way with:

https://fdroid.umrath.dev/repo?appId=dev.umrath.android.phanpy.dev

The ?appId= in the URL selects the channel — no further options needed. Phandroid Dev installs alongside the stable app as a separate package.

Via the F-Droid repo (auto-updates)

Add the self-hosted F-Droid repository once, then install Phandroid from it — a compatible client (the F-Droid app, Droid-ify or Neo Store) then checks it for updates automatically.

  1. In your F-Droid client open Settings → Repositories → Add repository and paste:

    https://fdroid.umrath.dev/repo?fingerprint=732DC12007C2873A07AA5E27DB47667F5A08E392C882E13C46D1480C7727CF19
    

    The fingerprint pins the repo to its signing key — keep it in the URL.

  2. Refresh the repo — it lists both apps: Phandroid (stable) and Phandroid Dev (bleeding). Install whichever you want, or both side by side.

All APKs are signed with the developer's own key, so you can move between the F-Droid client, Obtainium and a sideloaded APK without reinstalling.

Direct APK (sideload)

Download the latest phandroid-vX.Y.Z.apk (the stable Phandroid) from the releases page and open it to install (allow "install unknown apps" for your browser / file manager if prompted). The …-vX.Y.Z-dev.apk releases are Phandroid Dev — a separate app, not an update to the stable one.

Push notifications (optional, FOSS — no Google)

Phandroid uses UnifiedPush: encrypted Web Push, decrypted on-device, with no Google/FCM.

  1. Install a UnifiedPush distributor, e.g. Sunup. Open it once and grant its permissions (notifications + battery-optimization exemption — it keeps the push connection alive).
  2. In Phandroid go to Settings → Push Notifications (beta), turn it on and choose which notification types you want.
  3. Allow the two prompts Phandroid then shows: the notification permission and the battery-optimization exemption (so push keeps working reliably).

Building

Phandroid is a Capacitor app: the web client is built with Vite, then wrapped by the native Android project under android/.

Prerequisites

  • Node.js 22+ and npm 10.x
  • Android Studio with an Android SDK (platform android-35 and build-tools 35) — required to compile and run the APK
  • A JDK 1721 (Android Studio bundles a suitable JDK; JDK 21 is known to work)

1. Install and build the web app

npm install
npm run build          # outputs to dist/
npx cap sync android
npx cap open android

Then run the app on an emulator or a connected device from Android Studio.

2b. Or build a debug APK from the command line

Point Gradle at your SDK by creating android/local.properties with sdk.dir=/absolute/path/to/Android/sdk, then:

npx cap sync android
JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" \
  ./android/gradlew -p android :app:assembleDebug

The APK is written to android/app/build/outputs/apk/debug/app-debug.apk.

Live reload during development

npx cap run android --livereload --external

Regenerating the launcher icon / splash

npx capacitor-assets generate --android

(reads assets/logo.png; the adaptive icon background colour is set in android/app/src/main/res/values/ic_launcher_background.xml).

Credits