2013年4月20日土曜日

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

WebView でステータスコードを取得する方法…書いてる人いないのかな?
ちょっと力尽くな感じだけど、できるよ。Honeycomb だけどね。

前に書いたコードからてきとーに抜粋してるので、どこか書き間違いくらいはあるかもしれないけど。基本的な考え方はこれで大丈夫。

webView.setWebViewClient(new WebViewClient() {
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        if (!url.matches("https?://[\\w\\.\\-]+(/.*)?")) {
            return super.shouldInterceptRequest(view, url);
        }
        HttpGet req = new HttpGet(url);
        DefaultHttpClient client = new DefaultHttpClient();
        String mimeType = null, encoding = null;
        byte[] data = null;
        try {
            HttpResponse res = client.execute(req);
            // ここでステータスコードを取得できるよ!
            if (HttpStatus.SC_OK == res.getStatusLine().getStatusCode()) {
                HttpEntity entity = res.getEntity();
                Header mimeHeader = entity.getContentType();
                if (null != mimeHeader) mimeType = mimeHeader.getValue();
                Header encodingHeader = entity.getContentEncoding();
                if (null != encodingHeader) encoding = encodingHeader.getValue();
                data = EntityUtils.toByteArray(entity);
            }
        } catch (Exception e) {
            String msg = e.getMessage();
            Log.e(this.getClass().getSimpleName(), (null != msg) ? msg : "");
        } finally {
            req.abort();
            client.getConnectionManager().shutdown();
        }
        InputStream stream = new ByteArrayInputStream(data);
        return new WebResourceResponse(mimeType, encoding, stream);
    }
});

細かい事は試してみたら分かると思うけど、念のため補足しておくと、最後の WebResourceResponse(mimeType, encoding, stream) のところはこのままだとダメかもしれない。元のコードではあれこれ処理した後、エラーにしたい時は WebResourceResponse(null, null, null) を返すようにしてるんだ。

あと、WebView の通信を短時間でタイムアウトさせたい場合もこの方法で対応すると上手くいくよ。HttpConnectionParams.setSoTimeout とかその辺で。

…もう少しスマートな方法があるといいんだけどね。