Reputation: 12717
From Android 9 Pie now, requests without encryption will never work. And by default, the System will expect you to use TLS by default.You can read this feature here So if you only make requests via HTTPS you are safe. But what about apps that make requests through different sites, for instance, browser-like apps.
How can I enable requests to all types of connections HTTP and HTTPS in Android 9 Pie?
Upvotes: 231
Views: 270638
Reputation: 6768
The idea is to override the HTTP Security Context for the entire application.
Step 1: implement CustomHttpOverrides
class which extend the default dart HttpOverrides
class
import 'dart:io';
// extend `HttpOverrides` class
class CustomHttpOverrides extends HttpOverrides{
@override
HttpClient createHttpClient(SecurityContext? securityContext){
return super
.createHttpClient(securityContext)
..badCertificateCallback =
(X509Certificate certificate, String hostName, int hostPort)=> true;
}
}
Step 2: Override the default dart HttpOverrides
class with the CustomHttpOverrides
in the main()
method within the main.dart
file
void main() {
HttpOverrides.global = CustomHttpOverrides();
runApp(const MyApp());
}
Use cases:
In the Android Emulator you can access your services / API's running on your local machine via http and https protocols simply by send the http requests to 10.0.2.2
just like:
http://10.0.2.2:<port>/endpoint
https://10.0.2.2:<port>/endpoint
I have a web API implemented with C#, .NET 8 running on local machine with this http launch settings:
For https requests I have the port 1000 and for http requests I have the port 5197
To be able to send http requests to my API endpoints, I have temporarily disabled the Https Redirection:
// app.UseHttpsRedirection();
To fetch data from the Android Emulator, I attempted to send requests from Chrome to my endpoint:
http://10.0.2.2:5197/contracts/retrieve-contracts
https://10.0.2.2:1000/contracts/retrieve-contracts
To send the http requests from a Flutter application:
// HTTP request
Response responseViaHttp =
http.get(Uri.parse('http://10.0.2.2:5197/contracts/retrieve-contracts'))
as http.Response;
// HTTPS request
Response responseViaHttps =
http.get(Uri.parse('https://10.0.2.2:1000/contracts/retrieve-contracts'))
as http.Response;
Upvotes: 1
Reputation: 109
Add usesCleartextTraffic to AndroidManifest.xml
e.g.
<application
...
android:usesCleartextTraffic="true"
...>
in
<application
android: allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="AndroidLearning"
android: supportsRtl="true"
android:UsesCleartextTraffic="true" <-----
android: theme="@style/Theme.AndroidLearning"
tools:targetApi="31">
<activity
android:name=" MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android. intent.action.MAIN" />
‹catedorv android:name="android.intent.catedorv.LAUNCHFR" />
Upvotes: 1
Reputation: 1737
This worked for me,
add this xml file to: andriod/app/src/main/res/xml/network_security_config.xml
network_security_config.xml
xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">your_domain1</domain>
</domain-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">your_domain2</domain>
</domain-config>
</network-security-config>
then add this code to AndroidMenifest.xml
<application
...
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
...
>
<!-- for http support-->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
...
</application>
Upvotes: 5
Reputation: 12717
The easy way to implement this is to use this attribute to your AndroidManifest.xml
where you allow all http
for all requests:
<application android:usesCleartextTraffic="true">
</application>
But in case you want some more configurations for different links for instance, allowing http
for some domains but not other domains you must provide res/xml/networkSecurityConfig.xml
file.
To do this in Android 9 Pie you will have to set a networkSecurityConfig
in your Manifest application
tag like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config">
</application>
</manifest>
Then in your xml
folder you now have to create a file named network_security_config
just like the way you have named it in the Manifest and from there the content of your file should be like this to enable all requests without encryptions:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
From there you are good to go. Now your app will make requests for all types of connections. For additional information on this topic read here.
Upvotes: 430
Reputation: 5069
The FULLY WORKING SOLUTION for both Android
or React-native
users facing this issue just add this
android:usesCleartextTraffic="true"
in AndroidManifest.xml file like this:
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning">
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
in between <application>
.. </application>
tag like this:
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning">
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"/>
</application>
Upvotes: 58
Reputation: 732
i got the same problem and i notice that my security config has diferent TAGS like the @Xenolion answer says
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
so i change the TAGS "domain-config" for "base-config" and works, like this:
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
</base-config>
</network-security-config>
Upvotes: 4
Reputation: 10037
Easy Way
Add usesCleartextTraffic
to AndroidManifest.xml
<application
...
android:usesCleartextTraffic="true"
...>
Indicates whether the app intends to use cleartext network traffic, such as cleartext HTTP. The default value for apps that target API level 27 or lower is "true". Apps that target API level 28 or higher default to "false".
Upvotes: 19
Reputation: 1764
Just set usesCleartextTraffic
flag in the application tag of AndroidManifest.xml
file.
No need to create config file for Android.
<application
android:usesCleartextTraffic="true"
.
.
.>
Upvotes: 11
Reputation: 1141
A simple way is set android:usesCleartextTraffic="true"
on you AndroidManifest.xml
android:usesCleartextTraffic="true"
Your AndroidManifest.xml
look like
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.dww.drmanar">
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme"
tools:targetApi="m">
<activity
android:name=".activity.SplashActivity"
android:theme="@style/FullscreenTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I hope this will help you.
Upvotes: 28
Reputation: 1
You may check if you are sending clearText through HTTP
Fix : https://medium.com/@son.rommer/fix-cleartext-traffic-error-in-android-9-pie-2f4e9e2235e6
OR
In the Case of Apache HTTP client deprecation (From Google ) :
With Android 6.0, we removed support for the Apache HTTP client. Beginning with Android 9, that library is removed from the bootclasspath and is not available to apps by default.
To continue using the Apache HTTP client, apps that target Android 9 and above can add the following to their AndroidManifest.xml:
Source https://developer.android.com/about/versions/pie/android-9.0-changes-28
Upvotes: 0
Reputation: 141
For React Native
applications while running in debug add the xml block
mentioned by @Xenolion to react_native_config.xml
located in <project>/android/app/src/debug/res/xml
Similar to the following snippet:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">localhost</domain>
<domain includeSubdomains="false">10.0.2.2</domain>
<domain includeSubdomains="false">10.0.3.2</domain>
</domain-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
Upvotes: 14