質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

90.32%

  • Android

    6739questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android WebViewでのJavascriptInterface挙動

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 755

yryuu

score 139

以下のアクティビティで@android.webkit.JavascriptInterfaceを用いて、checkメソッドを呼ぼうとしています。

デバッグ上で動かしているときにはダイアログが出て正しい挙動になるのですが、apkにするとダイアログが表示されません。

おそらく apkにする段階で難読化されているのだと考えて
proguardに以下のように設定しましたが、うまくいきませんでした。

adb logcatでは
I/chromium(23819): [INFO:CONSOLE(1)] "Uncaught TypeError: window.login.check is not a function", source:  (1)
のようなエラーも出ています。

解決方法をご存じの方、ぜひ教えてください。
よろしくお願いいたします。

package com.example.activity;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.ConsoleMessage;
import android.webkit.CookieManager;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebViewClient;

import com.example.R;

public class WebView extends AppCompatActivity {

    android.webkit.WebView myWebView;
    AlertDialog.Builder alertDialogBuilder;
    String myurl;
    boolean check_flg = false;

    //初回起動時に実行
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webaccess);

        alertDialogBuilder = new AlertDialog.Builder(this);
        myWebView = (android.webkit.WebView)findViewById(R.id.web);

        //標準ブラウザをキャンセル
        myWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onReceivedHttpAuthRequest(android.webkit.WebView view, HttpAuthHandler handler, String host, String realm) {
            }


            //ページの読み込み完了
            @Override
            public void onPageFinished(android.webkit.WebView view, String url) {
                    myWebView.loadUrl("javascript:window.login.check(1)");
            }
        });

        myWebView.addJavascriptInterface(this, "login");
        //ViewPortの適応
        myWebView.getSettings().setUseWideViewPort(true);
        myWebView.getSettings().setJavaScriptEnabled(true);
        //GPS機能の適応
        myWebView.getSettings().setGeolocationEnabled(true);
        //javascriptの有効化
        myWebView.getSettings().setLoadWithOverviewMode(true);
        //スクロールバーの非表示化
        myWebView.setScrollBarStyle(android.webkit.WebView.SCROLLBARS_INSIDE_OVERLAY);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            myWebView.setWebContentsDebuggingEnabled(true);
        }

        myWebView.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onGeolocationPermissionsShowPrompt( String origin, GeolocationPermissions.Callback callback) {
                callback.invoke(origin, true, false);
            }
        });


        String userAgent = myWebView.getSettings().getUserAgentString();
        //アプリ起動時に読み込むURL
        myWebView.loadUrl("https://example.jp");


    }


    @Override
    protected void onResume() {
        super.onResume();
    }


    public boolean onKeyDown(int keyCode, KeyEvent event) {
        android.webkit.WebView myWebView = (android.webkit.WebView)findViewById(R.id.web);
        // 端末のBACKキーで一つ前のページヘ戻る
        if(keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack()) {
            myWebView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode,  event);
    }

    @android.webkit.JavascriptInterface
    void check(final int returnValue) {
        new AsyncTask<Void, Void, Boolean>() {
            @Override
            protected Boolean doInBackground(Void... params) {

                if (returnValue == 1) {
                    return true;
                }
                return false;
            }

            @Override
            protected void onPostExecute(Boolean bool) {
                // アラートダイアログのタイトルを設定します
                alertDialogBuilder.setTitle("test");
                // アラートダイアログのメッセージを設定します
                alertDialogBuilder.setMessage("移動してもよろしいでしょうか");
                // アラートダイアログの肯定ボタンがクリックされた時に呼び出されるコールバックリスナーを登録します
                alertDialogBuilder.setPositiveButton("移動する",
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                myWebView.loadUrl("http://example/next");

                            }
                        });
                // アラートダイアログのキャンセルが可能かどうかを設定します
                alertDialogBuilder.setCancelable(true);
                AlertDialog alertDialog = alertDialogBuilder.create();
                // アラートダイアログを表示します
                alertDialog.show();
            }
        }.execute();
    }
}
-keep class com.example.activity.WebView$JavascriptInterface { *; }

# Javascript interface
-keepattributes JavascriptInterface
-keepclasseswithmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

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

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

同じタグがついた質問を見る

  • Android

    6739questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。