Getting a VPN running on Android isn't hard; the hard part is what comes after. You paste in the subscription and the node list is empty, you tap Cancel on the system permission dialog, or the key icon sits in the notification bar while pages still won't load. What follows is the real order of operations, with what you should see at each step and where to look first when you don't.
- 120+Countries and regions
- 150+Available routes
- UnlimitedDevices online at once
- 7 daysNo-questions-asked refund
A few things to confirm before you start
An Android client does exactly three things: read the nodes out of the subscription, bring up a VPN tunnel in the system, and decide by rule which traffic enters that tunnel. When configuration fails, it almost always comes down to one of those three.
- ✅ Know your phone's Android version: Settings → About phone → Android version. You'll need it to judge where the permission dialog and the battery settings live.
- ✅ You have a working subscription link, or a complete node link.
- ✅ The phone can get online right now. Fetching a subscription is just an ordinary HTTPS request; with no connectivity, the node list won't update.
- ❌ No root and no bootloader unlock required — every permission is granted in system settings.
- ❌ No manual server address, port or password entry; all of that lives in the subscription.
A subscription link is an HTTP address. The client requests it and gets back Base64-encoded text; decoded, each line is a node URI: vless://, vmess://, trojan://, ss://, hysteria2://, tuic:// can all appear. The client only shows nodes whose prefixes it recognises. If the subscription contains Hysteria2 nodes and the client doesn't support them, the list will be a few entries short — that doesn't mean the subscription is broken.
The protocol doesn't decide whether you can connect; it decides how the link behaves. VMess, VLESS, Trojan and Shadowsocks run over TCP or WebSocket, which is the most compatible but more sensitive to packet loss; Hysteria2 and TUIC run over QUIC, i.e. UDP, which handshakes faster when the mobile network switches or the signal is weak — but if the carrier throttles UDP, they simply won't connect. When one route fails, change protocol family first, then region.
Activation only needs a username and password, no email address, so there's no waiting for a verification mail anywhere in the flow: the subscription link you get after activation goes straight into the client.
Install the client and import the subscription
Follow the order below and don't skip steps.
- Get the installer. Take the Android client from the official download entry, not a same-named package from a third-party app store. Expected result: the package opens normally and the system shows an install confirmation.
- Allow this install. Since Android 8, permission is granted per app: the system jumps to the “Install unknown apps” page, you flip the switch for your browser or file manager, then go back and continue.
- Open the client and find the subscription entry. Most clients put it in the sidebar or under a “Config” or “Subscription” tab at the bottom.
- Paste the subscription link. Make sure there are no leading or trailing spaces or line breaks. Some input fields treat a newline as part of the link and return a 404 on submit.
- Save and update the subscription. Expected result: a node list appears within seconds, grouped by region, with the same number of entries as the subscription.
- Pick a route. For the first run, use a TCP-family node to get the link working, then switch to a UDP protocol to compare — that way, if something breaks, you can tell whether it's the protocol or the route.
Open the subscription link directly in a browser and you'll see a block of Base64 text; decoded, it looks roughly like this, with the node name after #. The addresses and credentials below are format examples only:
vless://[email protected]:443?encryption=none&security=tls&type=ws&path=%2Fws#Japan-IEPL
trojan://[email protected]:443?sni=node.example.com#Singapore-Relay
hysteria2://[email protected]:8443?sni=node.example.com#US-Direct
Grant VPN permission and make the first connection
Tap the connect button next to a route and Android shows a system dialog titled “Connection request”, explaining that the client wants to set up a VPN connection and take over network traffic. That dialog is drawn by the system, not by the client. Tick “I trust this application” and tap OK — only then is the tunnel established.
Expected result: a key or VPN icon appears in the notification bar, the client shows connected, and it reports the bytes sent and received for this session.
If you tap Cancel by mistake, the client stays disconnected and tapping connect again may not bring the dialog back, because the system remembers the refusal. Fix: go to Settings → Network & internet → VPN, delete the client's entry if it's listed, then reconnect from the client and the dialog will appear again.
There are two more switches in the system worth turning on:
- Always-on VPN. The connection is established at boot, before apps start, so there's no window right after you unlock the phone where traffic goes over the local network.
- Block connections without VPN. When the tunnel drops, the phone goes offline instead of falling back to cellular. The trade-off: if the tunnel misbehaves, the phone has no connectivity at all until you turn this switch off.
The routing mode decides which traffic enters the tunnel. In global mode everything goes through the international exit, local apps included, so they take a detour — logins may ask you to verify more often and videos may load more slowly. Rule mode routes by domain and IP: local sites go direct, international sites go through the proxy, and that's the one to use day to day. “Bypass mainland” and “per-app proxy” in the client are both variants of rule mode.
DNS is the other easy thing to miss. If the client hands domain resolution to the local carrier, the page traffic may go through the tunnel while the lookups still happen locally — that's a DNS leak. Clients usually have a “Remote DNS” or “DNS over proxy” switch; turn it on so lookups leave through the tunnel too.
Add the client to the battery whitelist
Android's Doze restricts background networking after the screen has been off for a while, and manufacturers layer their own background management on top. The result: the client process gets frozen, the tunnel drops, and the UI still says connected. The menu names differ per vendor, but the switches to turn on are the same kind:
| System | Switch to turn on | Roughly where |
|---|---|---|
| Stock Android / Pixel | Battery → Unrestricted | Settings → Apps → client → Battery |
| Xiaomi HyperOS / MIUI | Battery saver → No restrictions; Autostart → Allow | Settings → Apps → Manage apps → client |
| Huawei HarmonyOS | App launch → Manage manually, enable Auto-launch, Associated launch and Run in background | Settings → Apps and services → App launch |
| OPPO / OnePlus ColorOS | Allow auto launch, allow background activity | Settings → Battery → App battery management |
| vivo OriginOS | Background power consumption → Allow | Settings → Battery → Background power management |
| Samsung One UI | Remove from “Sleeping apps” | Settings → Battery → Background usage limits |
Names change between OS versions. Search for “autostart”, “background activity” or “power consumption” — the setting is almost always under Apps or Battery.
Two more things to do at the same time: lock the client card in Recents (most systems support a long-press or swipe-down to lock) so a one-tap clean doesn't kill it; and if you run cleaner or battery-saver apps, add the client to their whitelists, or everything above gets undone.
Verify that traffic really takes the international route
A successful connection doesn't mean the configuration is right. The three checks below cover the tunnel, DNS and routing; only when all three pass is it set up properly.
Check the exit IP
Open any IP lookup page in a browser, note the result before connecting, then look again after connecting. If the two differ and the second one's location matches the region you picked, page traffic is genuinely going through the tunnel.
One exception: nodes that unblock streaming services often use a relay exit, so the IP's location may not match the region in the node name. The test is “different from your local IP”, not “identical to the node name”.
Check where DNS resolution lands
Use a DNS leak test page to look at the resolver list. If it still shows your local carrier's addresses, resolution isn't going through the tunnel. Fix: turn on remote DNS in the client, and set the system's Private DNS back to automatic — system-level DoT sometimes bypasses the client's DNS settings.
Check that routing rules behave as expected
Open a local site and an international site in turn. In rule mode the local site should go direct, with speed close to what you get when disconnected, while the international site goes through the proxy. If the local site also takes a detour, first check whether you've been switched to global mode, then check whether the rule set in the subscription has updated.
Common snags and troubleshooting
Match the symptom in the table below. Keep the order fixed: confirm the subscription is current, then check permissions and whether the tunnel is up, and finally check DNS and routing.
< class="table-scroll">| Symptom | Likely cause | Fix |
|---|---|---|
| Subscription update fails with a timeout or 404 | The link was truncated, has a stray space, or the subscription domain can't be reached directly on this network | Copy the full link again; retry over Wi-Fi or mobile data |
| Subscription updates fine but the node list is empty | The client doesn't recognise the protocol prefixes in the subscription | Switch to a client that supports them, or use nodes with a widely supported protocol |
| Tapping connect brings up no system dialog | The system remembered an earlier refusal | Delete the old entry in the system VPN settings and reconnect from the client |
| Key icon is there but pages won't load | DNS isn't going through the tunnel, or a routing rule sends that app direct | Turn on remote DNS; switch to global mode and test again |
| Disconnects a few minutes after the screen goes off | Battery optimisation froze the client process | Whitelist it using the table in the previous section and lock it in the background |
| Video opens but keeps buffering | UDP is throttled, or the node's exit is congested | Try a TCP-family node, or another region |
Once it's set up, only two things need regular attention: refresh the subscription now and then, and re-check the battery settings after a major OS upgrade, since upgrades often reset an app's background whitelist. The client handles the rest.