Approach Docs
Proof of Concept Lab
Proof of Concepts / Production Case Study

AutoDNS: Android Private DNS Automation

Solving the public Wi-Fi captive portal dilemma with low-level Android IPC, zero battery drain, and zero-telemetry architecture.

APK Size
1.29 MB
R8 Proguard Aggressive Shrinking
Battery Impact
< 0.1%
Reactive NetworkCallback (No Polling)
Privacy Profile
0 Trackers
Exclusively Local Execution
OS Compatibility
API 28 – 35
Android 9 Pie to Android 15
01 / The Pathology (Problem)

The Android Private DNS Captive Portal Failure

Android introduced TLS-encrypted Private DNS (DNS-over-TLS) in Android 9 to protect users against ISP snooping and malware. However, enabling a custom Private DNS provider (such as NextDNS or AdGuard) introduces a severe daily usability failure:

❌ Captive Portal Breakage Public Wi-Fi networks (airports, cafes, hotels, universities) require a captive portal login. Because Private DNS attempts TLS handshakes to foreign hostnames before authentication, the portal cannot resolve, leaving the device stranded with no connectivity.
❌ Friction-Heavy Workaround Users must manually open Android Settings > Network & Internet > Private DNS, switch it off, complete the login, and remember to re-enable it afterwards.
02 / The Prescription (Architecture)

Autonomous, Reactive Network Context Switching

Rather than running continuous battery-draining CPU loops, AutoDNS registers event-driven OS network callbacks with Android's ConnectivityManager. The moment an active Wi-Fi network's BSSID or SSID transitions, our state engine evaluates configured rules and alters the system settings table in less than 50 milliseconds.

// Core Automation Engine - Sub-millisecond reactive transition
val request = NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .build()

connectivityManager.registerNetworkCallback(request, object : ConnectivityManager.NetworkCallback() {
    override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
        val currentSsid = resolveSsid(network, caps)
        evaluateAndApply(targetSsid = config.targetSsid, currentSsid = currentSsid)
    }
})

Target Wi-Fi Rule

When connected to your trusted home network, automatically apply Custom Private DNS (AdGuard / NextDNS / Cloudflare).

Untrusted Wi-Fi Rule

When connecting to airport or public Wi-Fi, immediately revert Private DNS to "Automatic" or "Off" so captive portals render instantly.

Mobile Data Fallback

Automatically enforces your cellular DNS policy the instant Wi-Fi drops.

03 / Surgical Engineering Rigor

Key Technical Highlights

  • Direct Android Framework Integration (`Settings.Global`): Manipulates OS-level Private DNS modes without relying on local VPN tunnels, preventing the throughput bottlenecks and battery penalties associated with VPN-based DNS blockers.
  • Seamless Shizuku & ADB One-Time Authorization: Compatible with unrooted production consumer phones (Samsung One UI, Google Pixel, OnePlus, Xiaomi) using Shizuku wireless debugging or standard ADB shell.
  • State-Preserving Foreground Service: Compliant with Android 14/15 Foreground Service types (`SPECIAL_USE`) to survive aggressive OEM battery-killing daemons while consuming negligible power.
  • R8 Code Minification: Aggressive Proguard configuration eliminated 85% of standard library bloat, shrinking the release binary down to a lightweight 1.29 MB.

Want to test AutoDNS on your device?

Install the APK and grant system settings permission once via ADB (or click one button in Shizuku):

adb shell pm grant com.approachdocs.autodns android.permission.WRITE_SECURE_SETTINGS

Need low-level Android engineering or system automation?

Whether you are developing hardware accessories, enterprise fleet MDM apps, background sync engines, or performance-critical mobile products, Approach Docs delivers production-grade code.