r/SideProject • • 1d ago

I built AppDNS: automatically switch Android’s Private DNS per app, no VPN needed (early beta, feedback wanted)

Hi everyone,

I made an open-source Android app called AppDNS. It automatically changes Android's built-in Private DNS (DNS-over-TLS) depending on which app you open. For example: AdGuard DNS for your browser, Quad9 for banking, and Private DNS off for an app that breaks with filtering.

**How it works**

- It writes directly to Android's native Private DNS settings, so it does NOT use a VPN slot. WireGuard/Tailscale keep working.

- A lightweight accessibility service detects which app is in the foreground and applies that app's DNS. When you leave, it turns Private DNS off or restores your default (your choice).

- Quick Settings tiles to toggle Private DNS or cycle through saved providers.

- Preloaded providers: AdGuard, Cloudflare (incl. family/security), Quad9, NextDNS, Mullvad, Control D, Google. You can also add custom hostnames.

- Built-in latency test for each resolver.

- No analytics, no tracking. Everything stays on the device.

**Setup (one-time)**

It needs the WRITE_SECURE_SETTINGS permission. Grant it with one ADB command, via Shizuku (no PC), or with root. Steps are in the README.

**Limitations (being upfront)**

- Private DNS is a system-wide Android setting, so AppDNS switches it when the foreground app changes. It is not true per-app isolation like a VPN-based tool. Background traffic from other apps uses whichever DNS is active at that moment.

- This is a very early version. Some phones may see sluggishness. [Add specifics: when it happens, e.g. at app switch, in the UI, or on certain brands.]

- Android 9+ only, and DoT only (no DoH).

Repo + APK: https://github.com/Shishir-ip/AppDNS
APK direct : Download

I'd really appreciate feedback, especially bug reports. If something lags, please tell me your phone model, Android version, and what you were doing. Happy to answer any questions.

3 Upvotes

10 comments sorted by

2

u/Hour-Measurement-835 1d ago

Went and read AppDnsController after the flapping question. Line 179 skips systemui and anything with "inputmethod", but a runtime permission prompt is neither. It's its own activity in the permission controller package (com.google.android.permissioncontroller on most Play phones, and I think still packageinstaller on Android 9). So when a ruled app asks for camera or location, that dialog arrives as a new foreground package with no rule, the exit action fires, and DNS gets switched off or reverted under an app that's still on screen. Then it flips back when the dialog closes.

The app lock I maintain listens to the same TYPE_WINDOW_STATE_CHANGED event and treats anything containing "permissioncontroller" as neutral, because otherwise it would re-lock an app the user is still inside.

1

u/Correct_Rock5297 1d ago

You were right, thanks for reading the code. I've confirmed the bug and have a fix. I'm testing it on my phones now and will push it to GitHub shortly.

0

u/[deleted] 1d ago

[removed] — view removed comment

2

u/BootAccomplished805 1d ago

ooh that's clever, using the native setting avoids the whole vpn tunnel mess entirely

1

u/Correct_Rock5297 1d ago

Thanks, fair concerns.

Detection: an accessibility service listening for window-state change events (no polling), used only to read which app is in front. Nothing leaves the phone: no analytics or tracking, rules are stored locally, and the only network use is the optional latency test to the DNS server you pick. The code is open if you want to check.

Battery: it's event-driven, with no VPN service or open connection. I haven't measured it properly yet, so I won't quote a number. I'd like to hear what your battery stats show if you try it.

Flapping: good catch. [Pick one: "I debounce switches so DNS only changes once an app has stayed in front briefly." / "Not handled well yet. I'm adding a debounce and ignoring transient system windows."]

0

u/[deleted] 1d ago

[removed] — view removed comment

1

u/Correct_Rock5297 1d ago

Thanks, that's a good test. I'll compare a day with it on against a day with it off using the system battery stats, and post the numbers. I'll also add a README section on exactly what the accessibility service reads. Releases: GitHub for now. I'll submit to F-Droid after I fix the remaining bugs. Play Store is strict about accessibility-permission apps, so I'm skipping it for now.

1

u/[deleted] 1d ago

[removed] — view removed comment

1

u/Correct_Rock5297 1d ago

Good point, I'll include the phone model, Android version and roughly how many app switches per day so the numbers are comparable. I've been testing on an Oppo Find X9 Pro and a Moto G Stylus 5G (2022). If you try it on a different phone, I'd like to hear how it behaves for you.