Adding Internet Access to an Android App in Flutter
Your Flutter app may fail to fetch APIs or load remote images if Android blocks network access. This guide shows exactly what to change and why so your app can make network requests reliably.
Why Android needs explicit Internet permission
Android uses a permission-based security model. Even though INTERNET is a "normal permission" (it won't pop up a runtime prompt), you must declare it in your app's AndroidManifest.xml file so the system grants your app network access.
Think of permissions like house keys: you can't enter the house without the right key, even if the door is unlocked for others.
Summary: Declare the permission in the manifest to get the system-level key for networking.
Add the INTERNET permission
Open android/app/src/main/AndroidManifest.xml and add the permission element above the tag:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="myapp"
android:icon="@mipmap/ic_launcher">
...
</application>
</manifest>
After editing, rebuild the app (flutter run or flutter build). The permission applies to the whole APK (Android application package).
Summary: Add and rebuild.
Allow cleartext (HTTP) traffic when needed
HTTP (Hypertext Transfer Protocol) is "cleartext" when it transmits unencrypted data. Since Android 9 (API level 28) the platform blocks cleartext by default. If your backend uses plain HTTP, you must explicitly allow it.
Option A — quick-and-broad (allow all cleartext):
<application
android:usesCleartextTraffic="true"
...>
...
</application>
Option B — targeted and safer: create a network security config to allow specific domains only.
res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain>dev.example.com</domain>
</domain-config>
</network-security-config>
Then reference it in AndroidManifest.xml:
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
Prefer HTTPS (TLS) in production. Allowing cleartext is like allowing postcards instead of sealed letters—ok for development, risky for production.
Summary: Use networkSecurityConfig for domain-level control, or usesCleartextTraffic for a quick dev fix; prefer HTTPS.
Check network state (optional)
If your app wants to detect connectivity (online vs offline), add the ACCESS_NETWORK_STATE permission:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
In Flutter use the http package (for simple requests) or connectivity_plus (to observe connectivity changes). Example GET with the http package:
import 'package:http/http.dart' as http;
Future<void> fetchExample() async {
final res = await http.get(Uri.parse('https://api.example.com/data'));
if (res.statusCode == 200) {
print(res.body);
} else {
throw Exception('Request failed: ${res.statusCode}');
}
}
Run the app on an emulator or device and watch logs (flutter run).
Summary: ACCESS_NETWORK_STATE lets you detect connectivity; use http or connectivity_plus as needed.
Common pitfalls and troubleshooting
Wrong manifest file: edit android/app/src/main/AndroidManifest.xml (not a library manifest).
Forget to rebuild: run flutter clean then flutter run if permission changes seem ignored.
Cleartext still blocked: ensure you referenced the network_security_config file and used the correct xml filename and path (res/xml/).
Testing on device: emulator usually has network by default; physical devices depend on Wi‑Fi / mobile data.
Plugin requirements: some plugins require ACCESS_NETWORK_STATE in addition to INTERNET.
If requests still fail, inspect Android logcat and Flutter run output.
Summary: Verify manifest location, rebuild, and check logs for concrete errors.
Conclusion and next steps
You now know how to give a Flutter Android app internet access, how Android treats cleartext traffic, and when to add ACCESS_NETWORK_STATE. Next, migrate dev HTTP endpoints to HTTPS and consider TLS certificate pinning if you need stronger guarantees.
Try adding the permission, run a simple GET from the Dart code above, and post the log output if you hit errors.🎯 Level: Intermediate
Adding Internet Access to an Android App in Flutter
Your Flutter app may fail to fetch APIs or load remote images if Android blocks network access. This guide shows exactly what to change and why so your app can make network requests reliably.
Why Android needs explicit Internet permission
Android uses a permission-based security model. Even though INTERNET is a "normal permission" (it won't pop up a runtime prompt), you must declare it in your app's AndroidManifest.xml file so the system grants your app network access.
Think of permissions like house keys: you can't enter the house without the right key, even if the door is unlocked for others.
Summary: Declare the permission in the manifest to get the system-level key for networking.
Add the INTERNET permission
Open android/app/src/main/AndroidManifest.xml and add the permission element above the tag:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="myapp"
android:icon="@mipmap/ic_launcher">
...
</application>
</manifest>
After editing, rebuild the app (flutter run or flutter build). The permission applies to the whole APK (Android application package).
Summary: Add and rebuild.
Allow cleartext (HTTP) traffic when needed
HTTP (Hypertext Transfer Protocol) is "cleartext" when it transmits unencrypted data. Since Android 9 (API level 28) the platform blocks cleartext by default. If your backend uses plain HTTP, you must explicitly allow it.
Option A — quick-and-broad (allow all cleartext):
<application
android:usesCleartextTraffic="true"
...>
...
</application>
Option B — targeted and safer: create a network security config to allow specific domains only.
res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain>dev.example.com</domain>
</domain-config>
</network-security-config>
Then reference it in AndroidManifest.xml:
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
Prefer HTTPS (TLS) in production. Allowing cleartext is like allowing postcards instead of sealed letters—ok for development, risky for production.
Summary: Use networkSecurityConfig for domain-level control, or usesCleartextTraffic for a quick dev fix; prefer HTTPS.
Check network state (optional)
If your app wants to detect connectivity (online vs offline), add the ACCESS_NETWORK_STATE permission:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
In Flutter use the http package (for simple requests) or connectivity_plus (to observe connectivity changes). Example GET with the http package:
import 'package:http/http.dart' as http;
Future<void> fetchExample() async {
final res = await http.get(Uri.parse('https://api.example.com/data'));
if (res.statusCode == 200) {
print(res.body);
} else {
throw Exception('Request failed: ${res.statusCode}');
}
}
Run the app on an emulator or device and watch logs (flutter run).
Summary: ACCESS_NETWORK_STATE lets you detect connectivity; use http or connectivity_plus as needed.
Common pitfalls and troubleshooting
Wrong manifest file: edit android/app/src/main/AndroidManifest.xml (not a library manifest).
Forget to rebuild: run flutter clean then flutter run if permission changes seem ignored.
Cleartext still blocked: ensure you referenced the network_security_config file and used the correct xml filename and path (res/xml/).
Testing on device: emulator usually has network by default; physical devices depend on Wi‑Fi / mobile data.
Plugin requirements: some plugins require ACCESS_NETWORK_STATE in addition to INTERNET.
If requests still fail, inspect Android logcat and Flutter run output.
Summary: Verify manifest location, rebuild, and check logs for concrete errors.
Conclusion and next steps
You now know how to give a Flutter Android app internet access, how Android treats cleartext traffic, and when to add ACCESS_NETWORK_STATE. Next, migrate dev HTTP endpoints to HTTPS and consider TLS certificate pinning if you need stronger guarantees.
Try adding the permission, run a simple GET from the Dart code above, and post the log output if you hit errors.

