WebView内でFacebookの「いいね」ボタンを押せるようにしたい

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,364

flaumig

score 46

実現したいこと

Android4.0〜5.1を対象に、アプリ内のWebViewで表示される「いいね」ボタンを押して「いいね」されるようにしたい

発生している問題

現在開発中のアプリではWebViewであるサイトを表示しているのですが、
そのサイト内にある「いいね」ボタンを押すと、Facebookログインページに遷移し、
ログイン後に画面が真っ白になるという問題が発生していました。

下記のページを参考にして、WebViewClientとWebChromeClientを継承した独自クラスを作成し、
それをWebViewにセットしたところ、Facebookログイン後に元の画面に戻ってくることが可能となり「いいね」できるようになりました。

http://ameblo.jp/rhythmicallife/entry-11955690155.html
http://stackoverflow.com/questions/12648099/making-facebook-login-work-with-an-android-webview

ところが実機で動作確認を行ったところ、Android4.4以降の端末では以前と変わらずFacebookログイン後に真っ白画面が表示されて、正しく動作しませんでした。
(Android4.0〜4.3までは想定通りに動作しました)

調べてみるとAndroid4.4からはWebViewのベースがChromiumに変更されたことにより、複数ウィンドウを開こうとした場合はWebViewClient#shouldOverrideUrlLoadingが呼ばれなくなったとのことでした。

http://hello-hello-world.blogspot.jp/2014/09/android44webviewshouldoverrideurlloading.html

Android 4.4以降で「いいね」が動作するようしたいのですが、何か回避策等はあるのでしょうか?

ソースコード

Android4.0~4.3までは動くようになったソースコードは下記の通りです。

public class HogeFragment extends Fragment {

    private FrameLayout mContainer;
    private WebView mWebView;
    private WebView mWebViewPop;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mContainer = (FrameLayout) getActivity().findViewById(R.id.webview_frame);
        mWebView = (WebView) getActivity().findViewById(R.id.webview);
        setWebSettings(mWebView.getSettings());
        mWebView.setWebViewClient(new UriWebViewClient());
        mWebView.setWebChromeClient(new UriChromeClient());
        if (getArguments() != null) {
            mWebView.loadUrl(getArguments().getString(KEY_URL));
        }
    }

    // WebSettings 設定
    @SuppressLint("SetJavaScriptEnabled")
    private void setWebSettings(WebSettings settings){
        if (settings == null) {
            return;
        }
        settings.setSupportZoom(true);
        settings.setPluginState(WebSettings.PluginState.ON);
        settings.setJavaScriptEnabled(true);
        settings.setSavePassword(false);
        settings.setLoadWithOverviewMode(true);
        settings.setBuiltInZoomControls(true);
        settings.setGeolocationEnabled(true);
        settings.setDomStorageEnabled(true);
        settings.setDatabaseEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setSupportMultipleWindows(true);
    }

    private class UriWebViewClient extends WebViewClient {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon){
        }

        @Override
        public void onPageFinished(WebView view, String url) {
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // ***** Android4.4以降だとここの処理が呼ばれない!! *****
            if (url.contains("close_popup.php")) {//"close_popup.php"はFacebookのログイン処理時、最後に呼び出されるリソース
                // Facebookログイン完了後はポップアップウィンドウを閉じる
                if(mWebViewPop != null) {
                    mWebViewPop.setVisibility(View.GONE);
                    mContainer.removeView(mWebViewPop);
                    mWebViewPop = null;
                }
            }
            // WebViewで開く
            return false;
        }
    }

    private class UriChromeClient extends WebChromeClient {
        @Override
        public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
            // ポップアップウィンドウが新しく開かれる場合に呼ばれる(Facebookログイン時など)
            mWebViewPop = new WebView(getActivity().getApplicationContext());
            mWebViewPop.setVerticalScrollBarEnabled(false);
            mWebViewPop.setHorizontalScrollBarEnabled(false);
            mWebViewPop.setWebViewClient(new UriWebViewClient());
            mWebViewPop.getSettings().setJavaScriptEnabled(true);
            mWebViewPop.getSettings().setSavePassword(false);
            mWebViewPop.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT));
            mContainer.addView(mWebViewPop);
            WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
            transport.setWebView(mWebViewPop);
            resultMsg.sendToTarget();
            return true;
        }
    }
}

開発環境

Android Studio 1.5.1
compileSdkVersion:22(Android 5.1)
対象端末:Android:4.0〜5.1

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる