概要
サーバーサイドのAPIと通信するAndroidアプリの開発中、ローカルでAPIサーバーを起動してアプリから接続しようとしたところ、次のエラーが発生しました。
Cleartext communication to 10.0.2.2 not permitted by network security policy
今回はこの原因と回避方法をメモとして残しておきます。
環境
- Android Studio 3.4
- Android 9 (API level 28)
原因
ドキュメントを確認したところ、Android 9 (API level 28) からはHTTP通信がデフォルトで無効になっていることがわかりました。
Starting with Android 9 (API level 28), cleartext support is disabled by default.
このため、http通信(httpsでない通信)はすべて失敗します。
対応
主な対応は2つあります。どちらかの対応を行えばHTTP通信が可能になります。
1. 属性 usesCleartextTraffic=“true”
AndroidManifest.xmlにusesCleartextTrafficeを設定します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.third.monitoring">
...
<uses-permission android:name="android.permission.INTERNET" />
...
<application
android:usesCleartextTraffic="true">
...
</application>
<application>タグの属性にandroid:usesCleartextTraffic="true"を設定します。こうすると、Androidアプリからのすべての通信でHTTPが許可されます。
2. ファイル res/xml/network_security_config.xml
設定ファイルres/xml/network_security_config.xml を作成し、HTTP通信を許可するドメインを定義します。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
</network-security-config>
今回の場合はAndroidアプリからローカルのAPIサーバーへのHTTPアクセスを許可するため、<domain>タグの要素に10.0.2.2を定義します。
ちなみに10.0.2.2は、Androidエミュレーターから見たホストPCのIPアドレスです。
そして、AndroidManifest.xmlに、このファイルへの参照を追加します。
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
</manifest>
これにより、ローカルのAPIサーバーとの通信のみHTTPアクセスを許可し、他のホストとの通信はHTTPSのみ許可する、という状態になります。
ホストやドメインを明示的に指定して許可することになりますので、こちらの方が良さそうですね。


コメント
[…] Android Emulatorでの「Cleartext HTTP traffic not permitted」エラー対策【メモ】概要サ… […]
Cleartext HTTP traffic not permittedで困っていました。
貴重な記事をありがとうございました!
素敵なGWをお過ごしください。
重ねてお礼を申し上げます。