HTTPS & Network Security Config
Every networking lesson in this section – OkHttp, Retrofit, Volley, WebSockets – assumed requests travel over a secure connection. This lesson explains why that assumption matters, and how Android lets you control it precisely.
Why Plain HTTP Is Risky
Regular HTTP traffic is sent as plain text. Anyone sharing the same network – a public Wi-Fi hotspot, a compromised router, anyone between the phone and the server – can read every byte, including recipe data, auth tokens, or session cookies your RecipeBox app sends. Worse, they can also modify the traffic in transit, injecting fake responses your app would trust completely. HTTPS encrypts the connection so that eavesdropping and tampering both become impractical. For any app handling real user data, HTTPS is not an optional nicety – it is the baseline.
usesCleartextTraffic Defaults to false
Recognizing how risky plain HTTP is, modern Android blocks it by default. The manifest attribute android:usesCleartextTraffic controls this, and starting with apps targeting Android 9 (API 28) and above, it defaults to false – meaning a plain http:// request from your app is refused by the OS before it even leaves the device.
<!-- AndroidManifest.xml -->
<application
android:usesCleartextTraffic="false"
android:networkSecurityConfig="@xml/network_security_config"
... >
Network Security Config for Fine-Grained Control
Sometimes you genuinely need an exception – most commonly, allowing cleartext traffic only against a local development server while still blocking it everywhere else. A Network Security Config XML file gives you that precision instead of an all-or-nothing switch.
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
<base-config cleartextTrafficPermitted="false" />
</network-security-config>
- The <domain-config> block permits cleartext only for 10.0.2.2, the Android emulator's alias for your development machine's localhost.
- The <base-config> at the bottom blocks cleartext for every other domain – including your real RecipeBox production API.
- This is far safer than flipping usesCleartextTraffic to true app-wide, which would weaken security for every connection, not just your local server.
Referencing the Config from the Manifest
<application
android:networkSecurityConfig="@xml/network_security_config"
... >
...
</application>
Certificate Pinning (Conceptual)
Even over HTTPS, an app normally trusts any certificate signed by a certificate authority the device already trusts. Certificate pinning adds an extra layer: you tell the app to only trust one or a few specific certificates for a domain, via a <pin-set> entry in the config. This guards against certain man-in-the-middle scenarios where an attacker has obtained a technically-valid certificate from a different authority.
<domain-config>
<domain includeSubdomains="true">api.recipebox.example.com</domain>
<pin-set>
<pin digest="SHA-256">base64EncodedPinHere==</pin>
</pin-set>
</domain-config>
Trusting Self-Signed Certificates the Right Way
During local development it is common to run a server with a self-signed certificate. The tempting shortcut is to disable certificate validation entirely in code – don't do this. It silently makes every HTTPS connection in that build insecure, and this kind of shortcut has a habit of accidentally surviving into a release build.
The correct approach is an explicit <trust-anchors> entry naming exactly the self-signed certificate you want trusted, scoped to your development domain only:
<domain-config>
<domain includeSubdomains="true">10.0.2.2</domain>
<trust-anchors>
<certificates src="@raw/dev_cert" />
</trust-anchors>
</domain-config>