Android Pie:WebView在某些站点上显示纯HTTP错误,即使使用useClearTextTraffic =“ true”

O'R*_*ney 7 android http webview

我们的android应用程序中有一个WebView,最终用户可以浏览到他们想要的任何站点。Android Pie默认情况下禁用纯HTTP,因此我们在清单中添加了useClearTextTraffic =“ true”。

这适用于某些网站,但不适用于google.com等其他网站!在不起作用的站点上,我们仍然会得到net :: ERR_CLEARTEXT_NOT_PERMITTED,好像我们没有设置清单设置一样。

webview HTTP错误的屏幕截图

我认为这可能与HSTS有关,但在那种情况下,我只希望WebView立即重定向到HTTPS。

因此问题是,即使清单中的useClearTextTraffic已打开,为什么Android WebView仍然无法通过纯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 /sf/ask/3554796451/ -->
        <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> 
Run Code Online (Sandbox Code Playgroud)

Üma*_*mån 14

解:

正如我观察到的Manifest.xml,您已经android:usesCleartextTraffic="true"<activity>标签中使用了。

如您在activity标签Documentation中所见,它没有提供docs中提供的语法中的任何功能。

如下面的屏幕截图所示,cleartexttraffic的描述非常简单。

关于明文流量

另外,如果您查看application标签Documentation,您会注意到这android:usesCleartextTraffic是的属性之一Application Tag

因此,此处所需的唯一解决方法是从活动标记中删除属性,然后在应用程序标记中使用它,并且不支持的活动标记android:usesCleartextTraffic

从Android 9(Pie)开始,默认情况下禁用明文流量。

因此,解决方案将是:

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

尝试一下,如果有任何与此相关的问题,请发表评论。