@blog.justoneplanet.info

日々勉強

androidのWebViewで取得したCookieをHTTP通信に使う

そろそろ忘れそうだからメモしておく。

■WebViewで取得したCookieの保存

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.web);
        
        webView = (WebView) findViewById(R.id.webview);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setBuiltInZoomControls(false);
        webView.setHorizontalScrollBarEnabled(false);
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // cookie取得後にwebviewのloadingをstopしたい場合などはこちらで処理した方が良い
            }
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon){
                // URLがログアウトの時SharedPreferenceに保存されているCookieを削除する
                if(url.indexOf(LOGOUT) > -1){
                    SharedPreferences.Editor editor = getSharedPreferences(PREF_KEY, 0).edit();
                    editor.putString(LOGIN_KEY, "");
                    editor.commit();
                }
            }
            
            @Override
            public void onPageFinished(WebView view, String url){
                // 自ドメインの時CookieをCheckする
                if(url.indexOf(DOMAIN) > -1){
                    String cookie = CookieManager.getInstance().getCookie(url);// 文字列でCookieを取得
                    String[] oneCookie = cookie.split(";");
                    for(String pair : oneCookie){
                        pair = pair.trim();
                        String[] set = pair.split("=");
                        set[0] = set[0].trim();
                        // ログイン用Cookie名で
                        // 値がセットされているとき
                        // SharedPreferenceにログイン用tokenを保存する
                        if(set.length > 1 && set[0].equals(LOGIN_KEY) && !set[1].equals("")){
                            set[1] = set[1].trim();// 前後空白文字の削除
                            Editor editor = getSharedPreferences(PREF_KEY, MODE_PRIVATE).edit();
                            editor.putString(LOGIN_KEY, set[1]);
                            editor.commit();
                        }
                    }
                }
            }
        });
        webView.loadUrl(URL);
    }

■保存したCookieを使ってHTTP通信

DefaultHttpClient httpClient = new DefaultHttpClient();
BasicClientCookie bCookie = new BasicClientCookie(
    LOGIN_KEY,
    getSharedPreferences(
        PREF_KEY,
        MODE_PRIVATE
    ).getString(LOGIN_KEY, "")
);
HttpGet get = new HttpGet(URL);
byte[] result = null;
String str = "";
try {
    // Cookieを取得してhttpにbind
    CookieStore store = new BasicCookieStore();
    bCookie.setDomain(DOMAIN);
    bCookie.setPath("/");
    store = httpClient.getCookieStore();
    store.addCookie(bCookie);
    HttpContext httpContext = new BasicHttpContext();
    httpContext.setAttribute(ClientContext.COOKIE_STORE, store);
    
    // 通信->結果の取得
    HttpResponse response = httpClient.execute(get, httpContext);
    StatusLine statusLine = response.getStatusLine();
    if (statusLine.getStatusCode() == HttpURLConnection.HTTP_OK) {
        result = EntityUtils.toByteArray(response.getEntity());
        str = new String(result, "UTF-8");
    }
}
catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
catch (ClientProtocolException e) {
    e.printStackTrace();
}
catch (IOException e) {
    e.printStackTrace();
}
return str;

HTTPヘッダを読み取る

public class WebViewActivity extends Activity {
    WebView webView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        webView = new WebView(this);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setBuiltInZoomControls(false);
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean  shouldOverrideUrlLoading (WebView  view, String urlStr) {
                Log.e("shouldOverrideUrlLoading", urlStr);
                URL url;
                URLConnection connection;
                try {
                    url = new URL(urlStr);
                    connection = url.openConnection();
                    connection.setConnectTimeout(3000);
                    connection.connect();
                    int size = connection.getContentLength();
                }
                catch (MalformedURLException e) {
                    e.printStackTrace();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                
                /**
                 * HTTP通信を実行して
                 * responseからheaderを読み取り
                 * ストリームから内容を読み出す
                 */
                String htmlContent = "";
                HttpGet httpGet = new HttpGet(urlStr);
                HttpResponse response;
                HttpClient client = new DefaultHttpClient();
                try {
                    response = client.execute(httpGet);
                    Header[] headers = response.getAllHeaders();
                    for (int i = 0; i < headers.length; i++) {
                        Log.e("header", headers[i].getName() + ":" + headers[i].getValue());
                    }
                    if (response.getStatusLine().getStatusCode() == 200) {
                        HttpEntity entity = response.getEntity();
                        if (entity != null) {
                            InputStream inputStream = entity.getContent();
                            htmlContent = convertToString(inputStream);
                        }
                    }
                }
                catch (ClientProtocolException e) {
                    e.printStackTrace();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                view.loadDataWithBaseURL(urlStr, htmlContent, "text/html", "utf-8", "");
                return true;
            }
            
            private String convertToString(InputStream inputStream) {
                StringBuffer buffer = new StringBuffer();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                try {
                    while((line = reader.readLine()) != null) {
                        buffer.append(line + "\n");
                    }
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                return buffer.toString();
            }
            
            @Override
            public void onPageStarted(WebView webView, String url, Bitmap favicon) {
                super.onPageStarted(webView, url, favicon);
                Log.e("onPageStarted", url);
            }
        });
        webView.loadUrl("http://www.google.co.jp");
        setContentView(webView);
    }

    /**
     * キーイベントが発火した時
     */
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {// 戻るボタン
            if (event.getAction() == KeyEvent.ACTION_DOWN) {// 押された時
                webView.goBack();// WebViewを戻す
            }
            return true;
        }
        return super.dispatchKeyEvent(event);
    }
}
public boolean shouldOverrideUrlLoading (WebView view, String url)

Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView. If WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the url. If WebViewClient is provided, return true means the host application handles the url, while return false means the current WebView handles the url.

ホストアプリケーションに現在のWebViewに新しいURLが読み込まれる時にコントロールを取るチャンスを与える。もし、WebViewClientが与えられていない場合、デフォルトではURLに適切なハンドラを選択するようにActivity Managerに依頼する。もし、WebViewClientが与えられている場合、trueを返すとホストアプリケーションがURLを操作し、falseを返すと現在のWebViewがURLを操作する。

ちなみにここで、loadUrl、loadData、loadDataWithBaseURLなどの処理を行わない場合、WebViewに遷移先のページがロードされない。

loadData(String data, String mimeType, String encoding)

Load the given data into the WebView using a ‘data’ scheme URL.
Note that JavaScript’s same origin policy means that script running in a page loaded using this method will be unable to access content loaded using any scheme other than ‘data’, including ‘http(s)’. To avoid this restriction, use loadDataWithBaseURL() with an appropriate base URL.
If the value of the encoding parameter is ‘base64’, then the data must be encoded as base64. Otherwise, the data must use ASCII encoding for octets inside the range of safe URL characters and use the standard %xx hex encoding of URLs for octets outside that range. For example, ‘#’, ‘%’, ‘\’, ‘?’ should be replaced by %23, %25, %27, %3f respectively.
The ‘data’ scheme URL formed by this method uses the default US-ASCII charset.
If you need to set a different charset, you should form a ‘data’ scheme URL which explicitly specifies a charset parameter in the mediatype portion of the URL and call loadUrl(String) instead. Note that the charset obtained from the mediatype portion of a data URL always overrides that specified in the HTML or XML document itself.

与えられたデータをdataスキームURLを使ってWebViewに読み込む。
JavaScriptのsame origin policyは、このメソッドを使って読込されたスクリプトが走っているページが、dataやhttp(s)以外のどんなスキームを使ったコンテンツにアクセスできないであろう事を意味する。この制限を避けるために、適切なURLとともにloadDataWithBaseURL()を使うように。もし、エンコーディングがbase64の場合、データはbase64としてエンコードされる必要がある。その他にも、データが安全なURL文字の範囲で8ビットのASCIIエンコーディングを使わなければならず、安全な範囲外の文字列に対してはスタンダードな%xx hexエンコーディングを用いなければならない。例えば’#’, ‘%’, ‘\’, ‘?’は%23, %25, %27, %3fに置き換えられる必要がある。
このメソッドでdataスキームはUS-ASCIIを使う。もし、他の文字コードをセットする場合、URLのmediatype部分の文字コードを明記するdataスキームURLを用いて、loadUrlを用いるべきである。data URLのmediatype部分から手にいれた文字コードはHTMLやXMLのドキュメントに明記された(文字コード)をいつも上書きすることを覚えておくように。

loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)

Load the given data into the WebView, using baseUrl as the base URL for the content. The base URL is used both to resolve relative URLs and when applying JavaScript’s same origin policy. The historyUrl is used for the history entry.
Note that content specified in this way can access local device files (via ‘file’ scheme URLs) only if baseUrl specifies a scheme other than ‘http’, ‘https’, ‘ftp’, ‘ftps’, ‘about’ or ‘javascript’.
If the base URL uses the data scheme, this method is equivalent to calling loadData() and the historyUrl is ignored.

baseUrlをコンテンツのURLとして、与えられたデータをWebViewに読み込む。base URLは相対URLを解決したりJavaScriptのsame originポリシーを適用するときに用いられる。historyUrlは履歴に使用される。
baseUrlが’http’, ‘https’, ‘ftp’, ‘ftps’, ‘about’ or ‘javascript’うがいのスキームで明記している場合に限って、この手法で明記されたコンテントはローカルのデバイスのファイルにアクセスできる。
base URLがdata schemeを使っている場合、このメソッドはloadDataを呼ぶのと等価でありhistoryUrlは無視される。

loadUrl(String url)

Load the given url.

与えられたURLを読み込む。

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment