Подтвердить что ты не робот

Получить код состояния HTTP в Android WebView

Я разрабатываю приложение для Android, которое загружает веб-сайт в WebView, но иногда веб-сайт возвращает HTTP-код 500.

Мой вопрос: есть ли способ получить код состояния HTTP из WebView с помощью прослушивателя или с другим классом?

Я попытался реализовать WebViewClient, но я не смог получить код статуса HTTP, полученный WebView.

4b9b3361

Ответ 1

Это невозможно (с момента, когда я пишу это). Документы для onReceiveError() в лучшем случае неоднозначны, но вы смотрите на эту проблему,

http://code.google.com/p/android/issues/detail?id=968

Это ясно, что коды статуса HTTP не будут передаваться через этот механизм. Как это возможно, что разработчики пишут WebView, не имея возможности получить код статуса HTTP, действительно ударяет мой разум.

Ответ 2

Вы можете загрузить контент с помощью ajax, а затем просто поместить его в webview с помощью loadDataWithBaseURL.

Создайте веб-страницу, подобную этой

<script type="text/javascript">
    function loadWithAjax() {
        var httpRequest = new XMLHttpRequest();
        var path = 'PATH';
        var host = 'HOST';
        var url = 'URL';

        httpRequest.onreadystatechange = function(){
            if (httpRequest.readyState === 4) { 
                if (httpRequest.status === 200) {
                    browserObject.onAjaxSuccess(host, url, httpRequest.responseText);
                } else {
                    browserObject.onAjaxError(host, url, httpRequest.status);
                }
            }
        };

        httpRequest.open('GET', path, true);
        httpRequest.send(null);
    }
</script>
<body onload="loadWithAjax()">

browserObject - это java-объект, введенный в javascript.

addJavascriptInterface(this, "browserObject");

И загрузите его в webView. Вы должны заменить path/url своими значениями.

ajaxHtml = IOUtils.toString(getContext().getAssets().open("web/ajax.html"));
            ajaxHtml = ajaxHtml.replace("PATH", path);
            ajaxHtml = ajaxHtml.replace("URL", url);
            ajaxHtml = ajaxHtml.replace("HOST", host);

loadDataWithBaseURL(host, ajaxHtmlFinal, "text/html", null, null);

Затем обработайте onAjaxSuccess/onAjaxError следующим образом:

    public void onAjaxSuccess(final String host, final String url, final String html)
    {
        ((Activity) getContext()).runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                loadDataWithBaseURL(url, html, "text/html", null, null);
            }
        });
    }

    public void onAjaxError(final String host, final String url, final int errorCode)
    {

    }

Теперь вы можете обрабатывать ошибки HTTP.

Ответ 3

На самом деле не так уж сложно проверить статус HTTP, чтобы узнать, доступен ли контент для загрузки в веб-просмотр. Предполагается: вы уже установили свой веб-просмотр и у вас есть строка для целевого URL-адреса, затем...

    AsyncTask<Void, Void, Void> checkURL = new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            pd = new ProgressDialog(WebActivity.this, R.style.DickeysPDTheme);
            pd.setTitle("");
            pd.setMessage("Loading...");
            pd.setCancelable(false);
            pd.setIndeterminate(true);

            pd.show();
        }
        @Override
        protected Void doInBackground(Void... arg0) {
            // TODO Auto-generated method stub
            int iHTTPStatus;

            // Making HTTP request
            try {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpGet httpRequest = new HttpGet(sTargetURL);

                HttpResponse httpResponse = httpClient.execute(httpRequest);
                iHTTPStatus = httpResponse.getStatusLine().getStatusCode();
                if( iHTTPStatus != 200) {
                    // Serve a local page instead...
                    wv.loadUrl("file:///android_asset/index.html");
                }
                else {

                    wv.loadUrl(sTargetURL);     // Status = 200 so we can loard our desired URL
                }

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "UNSUPPORTED ENCODING EXCEPTION", Toast.LENGTH_LONG).show();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "CLIENT PROTOCOL EXCEPTION", Toast.LENGTH_LONG).show();

            } catch (IOException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "I/O EXCEPTION", Toast.LENGTH_LONG).show();

            }  catch (Exception e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "GENERIC EXCEPTION", Toast.LENGTH_LONG).show();

            }

            return null;
        }


    };

    checkURL.execute((Void[])null);

В другом месте, в WebViewClient, отмените диалог выполнения

@Override  
    public void onPageFinished(WebView view, String url)  
    {
        // Do necessary things onPageFinished
        if (pd!=null) {
            pd.dismiss();
        }

    }       

Ответ 4

Похоже, что это возможно с помощью нового обратного вызова в API Android M (https://code.google.com/p/android/issues/detail?id=82069#c7).

void onReceivedHttpError (представление WebView, запрос WebResourceRequest, Ошибка запроса WebResourceResponseResponse)

К сожалению, это скорее всего не будет доступно на устройствах pre-Android M.

Ответ 5

В это время вы не можете получить нормальный код ответа HTTP.

Но в качестве решения, если вы можете изменить сервер веб-сервера, используйте следующее:

На сервере создайте некоторую функцию JavaScript, скажем, riseHttpError.

На стороне Android используйте JavaScript-интерфейс, и когда вам нужно сообщить об андроиде, чтобы обрабатывать HTTP-ошибку, просто вызовите Android.riseHttpError() на сервере.

Android будет обрабатывать эту функцию, и вы сможете выполнять необходимые действия на стороне Android.

В моем решении потребовались ошибки. Вы можете отправить любой код, который вы хотите.:)

Конечно, это просто еще один вариант, как это сделать. Итак, возможно, есть и другие, гораздо лучшие решения.

Но если вы можете изменить серверную часть, я думаю, это будет лучше сделать двойной запрос, используя URLHandler.

Ответ 6

Я не думаю, что можно легко получить код состояния (если это вообще возможно) из webView.

Моя идея - использовать метод onReceivedError() из WebViewClient (как вы сказали) с определенными ошибками в WebViewClient (полный список ошибок доступен здесь: http://developer.android.com/reference/android/webkit/WebViewClient.html) и предположим, что, например, код состояния 504 равен WebViewClient.ERROR_TIMEOUT и т.д.

Ответ 7

Вы должны использовать это после завершения на странице

@Override 
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error){
    //Your code to do
    Toast.makeText(
        getActivity(), 
        "Your Internet Connection May not be active Or " + error,
        Toast.LENGTH_LONG
    ).show();
}