WebView在Android 9.0中无法加载页面?

19
 public abstract class MainActivity extends AppCompatActivity {

        private static WebView web;
        private WebView mWebView;
        private java.lang.String url;
        Boolean isInternetPresent = false;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo i = manager.getActiveNetworkInfo();
            boolean hasConnect = (i != null && i.isConnected() && i.isAvailable());

            if (hasConnect) {
            } else {
            }
            Timer repeatTask = new Timer();
            repeatTask.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mWebView.loadUrl("http://www.smedk.ru/wp-content/uploads/files/education/rasp/1151.htm");
                        }
                    });
                }
            }, 0, 60000);

            setContentView(R.layout.activity_main);
            final ProgressDialog pd = ProgressDialog.show(MainActivity.this, "Загрузка расписания...", "Обновление данных...", true);
            mWebView = (WebView) findViewById(R.id.web1);
            mWebView.getSettings().setJavaScriptEnabled(true);
            if (savedInstanceState == null) {
                mWebView.loadUrl("http://www.smedk.ru/wp-content/uploads/files/education/rasp/1151.htm");
                mWebView.getSettings().setJavaScriptEnabled(true);
                mWebView.getSettings().setUseWideViewPort(true);
                String newUA = "User Agent";
                newUA = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/20100101 Firefox/4.0";
                mWebView.getSettings().setUserAgentString(newUA);
                mWebView.getSettings().setLoadWithOverviewMode(true);
                mWebView.clearCache(true);
                mWebView.getSettings().setBuiltInZoomControls(true);
                mWebView.getSettings().setSupportZoom(true);
                mWebView.getSettings().setDisplayZoomControls(false);
            }
            mWebView.setWebViewClient(new MyWebViewClient());
            mWebView.setWebViewClient(new WebViewClient() {
                public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl) {
                    try {
                        webView.stopLoading();
                    } catch (Exception e) {
                    }

                    if (webView.canGoBack()) {
                        webView.goBack();
                    }

                    webView.loadUrl("about:blank");
                    AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
                    alertDialog.setTitle("Нет интернет подключения!");
                    alertDialog.setMessage("Пожайлуйста убедитесть включен ли " +
                            "Wi-Fi или мобильные данные и повторите попытку. ");
                    alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    });

                    alertDialog.show();
                    super.onReceivedError(webView, errorCode, description, failingUrl);
                }

                @Override
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    pd.show();
                }

                @Override
                public void onPageFinished(WebView view, String url) {
                    pd.dismiss();
                    Toast.makeText(MainActivity.this, "Расписание загружено", Toast.LENGTH_SHORT).show();
                    Toast.makeText(MainActivity.this, "Обновление данных завершено", Toast.LENGTH_SHORT).show();
                    String webUrl = mWebView.getUrl();
                }
            });
        }




        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            mWebView.saveState(outState);
        }

        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            super.onSaveInstanceState(savedInstanceState);
            mWebView.restoreState(savedInstanceState);
            mWebView.setDownloadListener(new DownloadListener() {

                public void onDownloadStart(String url, String userAgent,
                                            String contentDisposition, String mimetype,
                                            long contentLength) {

                    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
                    request.allowScanningByMediaScanner();

                    request.setNotificationVisibility(
                            DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

                    request.setDestinationInExternalPublicDir(
                            Environment.DIRECTORY_DOWNLOADS,
                            "image.png");


                    DownloadManager dm = (DownloadManager) getSystemService(
                            DOWNLOAD_SERVICE);

                    dm.enqueue(request);

                }
            });
        }

        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
        }

        private void TakeScreenshot() {
            Picture picture = mWebView.capturePicture();
            Bitmap b = Bitmap.createBitmap(picture.getWidth(),
                    picture.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(b);

            picture.draw(c);
            FileOutputStream fos = null;
            try {

                fos = new FileOutputStream("mnt/sdcard/Download/image.jpg");
                if (fos != null) {
                    b.compress(Bitmap.CompressFormat.JPEG, 100, fos);

                    fos.close();
                }
            } catch (Exception e) {
            }
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.menu, menu);
            return super.onCreateOptionsMenu(menu);
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.exit:
                    finish();
                    break;
                case R.id.about:
                    Intent intent = new Intent(MainActivity.this, AboutActivity.class);
                    startActivity(intent);
                    break;
                case R.id.save:
                    Picture picture = mWebView.capturePicture();
                    Bitmap b = Bitmap.createBitmap(picture.getWidth(),
                            picture.getHeight(), Bitmap.Config.ARGB_8888);
                    Canvas c = new Canvas(b);
                    Toast.makeText(MainActivity.this, "Изображения сохранено в формате JPG", Toast.LENGTH_SHORT).show();
                    Toast.makeText(MainActivity.this, "Файл находится:" +
                            " /sdcard/image.jpg ", Toast.LENGTH_SHORT).show();
                    picture.draw(c);
                    FileOutputStream fos = null;
                    try {

                        fos = new FileOutputStream("mnt/sdcard/image.jpg");
                        if (fos != null) {
                            b.compress(Bitmap.CompressFormat.JPEG, 100, fos);

                            fos.close();
                        }
                    } catch (Exception e) {
                        break;
                    }
                    return true;
            }
            return false;
        }
    }

导入android.webkit.WebView; 导入android.webkit.WebViewClient;

public class MyWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
    @Override
    public void onPageFinished(WebView view, String url) {
        }
    }

我创建了一个查看通话时间表的应用程序,并决定在模拟器上测试我的应用程序。在旧版本中,WebView正常工作,但当我决定在Android 9上进行测试时,我发现网页无法使用。

在较旧的Android版本上,webView可以正常加载,但在Android 9上无法加载。这是什么原因?

8个回答

22

实际上,你应该避免使用http,但如果没有其他办法:

  1. 将@xml/network_security_config添加到你的资源中:

  2. <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config cleartextTrafficPermitted="true">
            <domain includeSubdomains="true">www.smedk.ru</domain>
        </domain-config>
    </network-security-config>
    
    将此安全配置添加到您的清单中,如下所示:
  3. <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
    
        ...
    </application>
    
  4. 现在您可以在www.smedk.ru子域上使用HTTP连接。

您可以在https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted查看更多信息。

注意:本节中的指导仅适用于目标为Android 8.1(API级别27)或更低版本的应用程序。从Android 9(API级别28)开始,默认情况下禁用明文支持。


像这样吗?<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:networkSecurityConfig="@xml/network_security_config"></meta-data> - Pxaml
我正在以相同的方式进行,但如果我在Webview中加载的URL内部路由到不在我的网络配置中的不同URL怎么办。 - yashkal

21

这种方法适用于所有领域,包括Android 9。将此属性添加到您的清单中,就像这样:

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

3
我已经使用了所有这些内容,但我的网络视图仍然是黑色的。如果我使用浏览器,则一切正常。 - Pxaml

6

请尝试使用安全的URL链接,即使用https而不是http。Android 9.0不允许使用不安全的URL链接。


2
在我的项目中出现了同样的问题,但以上所有答案都对我没有用。所以在这个问题上浪费了一整天之后,我得到的是:

在Android 8.1/9/10版本中,如果您在WebView中使用wrap_content属性来设置高度,则它将始终设置为0dp。在早期版本(8.1以下),WebView中的wrap_content正常工作。但从8.1及以上版本,您可以静态地给出高度,或者通过使用setLayoutParameters()动态地设置高度。并且在Android清单文件中添加额外的应用程序属性(android:usesCleartextTraffic="true")。

这是否意味着页面正在加载但未显示?在我的情况下,我可以看到服务器上从未请求URL... - Michael
@Michael 是的...在我的情况下,页面已经加载了,但由于WebView的大小默认设置为0(正如我所提到的,WebView的高度是“wrap_content”),所以我看不到那个WebView。 - vivek
如何设置 setLayoutParameters()。您能否提供任何示例? - Arya

0

我在Webview中遇到了按钮和组件无法渲染的问题,而唯一解决按钮和其他组件无法渲染的选项是:

webView.getSettings().setDomStorageEnabled(true);

希望这能帮助到某个人。


0
     //  Step 1:    in manifest :
  <application
        android:networkSecurityConfig="@xml/cleartextTrafficPermitted">
    //   Step 2:       
                  <uses-library
                         android:name="org.apache.http.legacy"
                        android:required="false" />
  </application>

    // Step 3 Create drawable XML>>cleartextTrafficPermitted  :

      <?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>

0

在 Android 10 中终于成功了,现在我可以加载完整的内容而不是部分内容了。

webView.loadDataWithBaseURL(null, contentText, "text/html", "UTF-8", null);

0

您可以使用Base64将HTML加载到WebView中。

String base64version = Base64.encodeToString(htmlString.getBytes(), Base64.DEFAULT);
webView.loadData(base64version, "text/html; charset=UTF-8", "base64");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接