web-dev-qa-db-ja.com

Android Pie:usesClearTextTraffic = "true"であっても、一部のサイトでプレーンHTTPのWebViewエラーが表示される

AndroidアプリにWebViewがあり、エンドユーザーは好きなサイトを閲覧できます。Androidマニフェストの「真」。

これはgoogle.comなどの一部のサイトでは機能しますが、他のサイトでは機能しません!動作しないサイトでは、マニフェスト設定を設定していないかのようにnet :: ERR_CLEARTEXT_NOT_PERMITTEDを取得します。

Screenshot of webview HTTP error

HSTSに関連しているのではないかと思いましたが、その場合は、WebViewがすぐにHTTPSにリダイレクトすることを期待しています。

だから問題は、なぜAndroid WebViewは、マニフェストでusesClearTextTrafficがオンになっていても、プレーンなHTTPでいくつかのサイトを閲覧できないのですか?

(PSネットワークセキュリティ設定がありません)

Google Pixel 1XLでテストしています。

プレーンHTTPが機能しない:

単純なhttpの動作:

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
      package="com.umajin.umajinviewer">

    <permission Android:name="com.umajin.umajinviewer.permission.C2D_MESSAGE"
        Android:protectionLevel="signature" />
    <uses-permission Android:name="com.umajin.umajinviewer.permission.C2D_MESSAGE" />

    <application Android:label="Umajin Preview"
                 Android:icon="@mipmap/ic_launcher"
                 Android:theme="@Android:style/Theme.NoTitleBar">
        <activity Android:name="Umajin"
                  Android:label="Umajin Preview"
                  Android:configChanges="orientation|screenSize|keyboardHidden"
                  Android:screenOrientation="fullSensor"
                  Android:icon="@mipmap/ic_launcher"
                  Android:largeHeap="true"
                  Android:windowSoftInputMode="stateHidden|adjustPan"
                  Android:launchMode="singleTask"
                  Android:usesCleartextTraffic="true"
                  >
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />
                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action Android:name="Android.nfc.action.TAG_DISCOVERED"/>
                <category Android:name="Android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action Android:name="Android.nfc.action.NDEF_DISCOVERED" />
                <category Android:name="Android.intent.category.DEFAULT" />
                <data Android:mimeType="text/plain" />
            </intent-filter>
            <intent-filter>
                <action Android:name="Android.hardware.usb.action.USB_DEVICE_ATTACHED" />
                <action Android:name="Android.hardware.usb.action.USB_DEVICE_DETACHED" />
            </intent-filter>
        </activity>

        <receiver
            Android:name=".GcmBroadcastReceiver"
            Android:permission="com.google.Android.c2dm.permission.SEND" >
            <intent-filter
                Android:priority="1">
                <action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
                <category Android:name="com.umajin.umajinviewer" />
            </intent-filter>
        </receiver>
        <service Android:name=".MyIntentService" />

        <meta-data
            Android:name="com.google.Android.gms.version"
            Android:value="@integer/google_play_services_version" />

        <meta-data
            Android:name="com.google.Android.maps.v2.API_KEY"
            Android:value="<redacted>"/>

        <!-- Specify which class to instantiate for the alarm messages -->
        <receiver Android:name="com.umajin.app.AlarmReceiver" >
        </receiver>

        <!-- Use this receiver if you to excute something at boot -->
        <!-- Required if you want alarms to survive a device restart -->
        <receiver
           Android:name="com.umajin.umajinviewer.BootReceiver"
           Android:enabled="true"
           Android:exported="true"
           Android:label="BootReceiver">
           <intent-filter>
              <action Android:name="Android.intent.action.BOOT_COMPLETED" />
           </intent-filter>
        </receiver>
        <!-- end boot receiver -->

        <!-- Add this to play private video files in fullscreen externally through intents. -->
        <provider
            Android:name="Android.support.v4.content.FileProvider"
            Android:authorities="com.umajin.umajinviewer.files"
            Android:grantUriPermissions="true"
            Android:exported="false">
            <meta-data
                Android:name="Android.support.FILE_PROVIDER_PATHS"
                Android:resource="@xml/filepaths" />
        </provider>
        <!-- Android Pie specific fix for crash on Google Maps. Throws a ClassNotFoundException when it fails to
             find "org.Apache.http.ProtocolVersion".
             See https://stackoverflow.com/questions/50782806/Android-google-maps-Java-lang-noclassdeffounderror-failed-resolution-of-lorg-a -->
        <uses-library Android:name="org.Apache.http.legacy" Android:required="false"/>
    </application>

    <uses-feature Android:glEsVersion="0x00020000" /> 
    <uses-feature Android:name="Android.hardware.camera" Android:required="false" />
    <uses-feature Android:name="Android.hardware.camera.autofocus" Android:required="false" />
    <uses-feature Android:name="Android.hardware.location" Android:required="false" />
    <uses-feature Android:name="Android.hardware.location.gps" Android:required="false" />
    <uses-permission Android:name="com.google.Android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE"/>
    <supports-screens Android:largeScreens="true" Android:normalScreens="true" Android:anyDensity="true" Android:smallScreens="true"/>
    <uses-permission Android:name="Android.permission.INTERNET"/>
    <uses-permission Android:name="Android.permission.CALL_PHONE"/>
    <uses-permission Android:name="Android.permission.SEND_SMS"/>
    <!-- WRITE no longer implies READ. By agreement, we always ask 
         for both at a time as the user prompts are identical and it can appear to 
         a user that they have been asked for the same thing twice even though the
         underlying permission asked for may be different. -->
    <uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE"/>
    <!-- FINE and COARSE permissions result in the same Prompt being displayed to the
         user. It can appear to the user that they have been asked for the same thing
         twice. By agreement, we always ask for both in one request
         to the user to avoid confusing the user. -->
    <uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission Android:name="Android.permission.GET_ACCOUNTS" />
    <uses-permission Android:name="Android.permission.CAMERA" />
    <uses-permission Android:name="Android.permission.WAKE_LOCK" />
    <uses-permission Android:name="com.google.Android.c2dm.permission.RECEIVE" />
    <uses-permission Android:name="Android.permission.NFC" />
    <!-- Used for Samsung fingerprint scanner. -->
    <uses-permission Android:name= "com.samsung.Android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY"/>

    <!-- Required for Bluetooth LE -->
    <uses-feature Android:name="Android.hardware.bluetooth_le" Android:required="false" />
    <uses-permission Android:name="Android.permission.BLUETOOTH"/>
    <uses-permission Android:name="Android.permission.BLUETOOTH_ADMIN"/>

    <!-- Use this permission if you want your applications to launch on startup -->
    <!-- Required if you want alarms to survive a device restart -->
    <uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED"/>

    <!-- Required for WIFI scanning -->
    <uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission Android:name="Android.permission.ACCESS_WIFI_STATE" />
    <uses-permission Android:name="Android.permission.CHANGE_WIFI_STATE" />

    <uses-permission Android:name="Android.permission.RECORD_AUDIO" />
</manifest> 
7
O'Rooney

解決策:

あなたのManifest.xmlを確認したように、Android:usesCleartextTraffic="true"タグで<activity>を使用しました。

アクティビティタグのドキュメント を見るとわかるように、ドキュメントで提供されている構文の機能は提供されていません。

以下のスクリーンショットでわかるように、cleartexttrafficの説明は非常に単純です。

About Clear Text Traffic

また、 アプリケーションタグのドキュメント を見ると、Android:usesCleartextTrafficApplication Tagの属性の1つであることがわかります。

したがって、ここで必要な唯一の修正は、activityタグから属性を削除し、applicationタグ、およびAndroid:usesCleartextTrafficのアクティビティタグのサポートはありません。

Android 9(Pie)Clear Text Trafficはデフォルトで無効になっています。

したがって、ソリューションは次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission Android:name="Android.permission.INTERNET" />
    <application
        ...
        Android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

これを試してください。これに関連する問題がある場合はコメントしてください。

14