Android

Android PでtargetSdkVersionを28に指定した場合にHTTP通信が失敗する

弊社優秀なエンジニアが解決していただいて自分が代わりに書きます。

HTTP通信に失敗する

APIを叩いた時に下記のエラーが出力されました。

java.net.UnknownServiceException: CLEARTEXT communication to "接続先URL" not permitted by network security policy

原因

https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted

詳しくは上記のページを確認してほしいのですが、Android P から cleartextTrafficPermitted="false がデフォルトで設定されるため暗号化されていないHTTP通信(つまり、 httpsのsが付いてない通信)に失敗します。

解決方法

解決方法は3つあります。

  1. 叩くAPIをHTTPS通信にする

まあいうまでもなく。

  1. AndroidManifest.xmlに usesCleartextTraffic を設定する

AndroidManifestに設定することでも全ての通信に対して、暗号化されていない、HTTP通信を許可することができます。

<application
            android:usesCleartextTraffic="true">
</application>

<application> タグに usersCleartextTraffic=true を設定すれば全ての通信を許可できます。

  1. network_security_config.xml を設定する

network_security_config.xml を設定しれば細かく設定を書くことができます。

例えば
- このドメインだけHTTP通信を明示的に許可したい
- 開発環境だけ許可したい(ビルドバリアントごとに別に設定したい)

みたいな状況で使います。

res/xml/network_security_config.xml というファイルを作成して下記を記述します。

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!-- デファルトの設定 -->
    <base-config cleartextTrafficPermitted="false" />
    <!-- ドメイン毎の設定 -->
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">secure.example.com</domain>
    </domain-config>
</network-security-config>

上記の設定は <domain-config> でドメイン毎に設定しています。

ビルドバリアント毎に設定したい場合は、ビルドバリアントに適したパッケージに network_security_config.xml を置けば解決します。