web-dev-qa-db-ja.com

Android WebViewでHTTPステータスコードを取得する

WebViewにWebサイトをロードするAndroidアプリを開発していますが、WebサイトがHTTPコード500を返すことがあります。

私の質問は:リスナーまたは別のクラスを使用してWebViewからHTTPステータスコードを取得する方法はありますか?

WebViewClientを実装しようとしましたが、WebViewが受信したHTTPステータスコードを取得できませんでした。

29
Victor Escobar

それは不可能です(現時点ではこれを書いています)。 onReceiveError()のドキュメントはせいぜいあいまいですが、この問題を見ると、

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

HTTPステータスコードがそのメカニズムを通じて報告されないことは明らかです。開発者がHTTPステータスコードを取得する方法なしでWebViewを作成したことがどのように可能であるかは、本当に心を打たれます。

16

Ajaxを使用してコンテンツをロードし、loadDataWithBaseURLを使用してコンテンツをWebビューに配置できます。

このようなWebページを作成します

<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 is 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エラーを処理できます。

13

これは、Android M API( https://code.google.com/p/Android/issues/detail?id= 82069#c7 )。

void onReceivedHttpError(WebViewビュー、WebResourceRequestリクエスト、WebResourceResponse errorResponse)

残念ながら、これはおそらくAndroid M以前のデバイスでは利用できません。

3
Jose Gómez

実際、コンテンツがWebビューにロードできるかどうかを確認するためにHTTPステータスをチェックすることはそれほど悪くありません。想定:Webビューを既に設定していて、ターゲット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();
        }

    }       
3
gman413

現時点では、通常の[〜#〜] http [〜#〜]応答コードを取得できません。

ただし、解決策として、webappサーバー側を変更できる場合は、以下を使用します。

サーバー上でJavaScript関数を作成します。たとえば、riseHttpErrorとします。

Android side use JavaScriptインターフェースで、http =エラーを処理するためにAndroidに伝える必要がある場合は、Android.riseHttpError()サーバー上。

Androidがこの機能を処理し、Android側で必要なアクションを実行できるようになります。

私の解決策では、エラーを取得する必要がありました。必要なコードを送信できます。 :)

もちろん、これはその方法のもう1つのバリエーションです。だから、おそらく他のもっと良い解決策があるでしょう。

ただし、サーバー側を変更できる場合は、URLHandlerを使用して二重リクエストを行う方が良いと思います。

2
Ken Shiro

可能であれば、webViewからステータスコードを簡単に取得することはできないと思います。

私の考えは、WebViewClientで定義されたエラーを使用して、WebViewClientからonReceivedError()メソッドを使用することです(あなたが言ったように)(エラーの完全なリストはここにあります: http://developer.Android.com/reference /Android/webkit/WebViewClient.html )そして、たとえば504ステータスコードがWebViewClient.ERROR_TIMEOUTなどに等しいと仮定します。

1
Mike

メソッドonReceivedHttpErrorをオーバーライドすると、ステータスコードを確認できます。

@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    super.onReceivedHttpError(view, request, errorResponse);
    int statusCode = errorResponse.getStatusCode();
    // TODO: dou your logic..
}
0
Jaroslav