web-dev-qa-db-ja.com

呼び出しJava JavaScriptからの関数Android WebView

いくつかのJavaのコードをAndroidアプリで同期呼び出しします。

私はこのソリューションを使用しています: https://stackoverflow.com/a/3338656

My Javaコード:

final class MyWebChromeClient extends WebChromeClient {
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            Log.d("LogTag", message);
            result.confirm();
            return true;
        }
    }

私のJavaScriptコード:

<html>
<script>
function Java_request(){
    alert('test');
}
</script>
<body>
<h2>Welcome</h2>
<div id="area"></div>
<form>
<input type="button" value="Java_call" onclick="Java_request()">
</form>
</body>
</html>

Java_callボタンをタップすると、ボタンは押された状態になります。コンソールログで'test'を確認できます。ここまではすべて正常です。

問題は、ボタンが通常の状態に戻らないことです。押された状態のままです。たぶん、JavaScriptの実行が壊れているのでしょうか?

ボタンが通常の状態に戻らないのはなぜですか?

70
ozkolonur

これがJavaScriptにJavaコードを実行させるための最良の解決策だとは思わない。ここを参照:

ネイティブコードをHTMLに公開し、javascriptを介して呼び出し可能にする場合は、Webビュー宣言の周りで以下を実行します。

JavaScriptInterface jsInterface = new JavaScriptInterface(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(jsInterface, "JSInterface");

クラスJavaScriptInterfaceを宣言します。

public class JavaScriptInterface {
    private Activity activity;

    public JavaScriptInterface(Activity activity) {
        this.activity = activity;
    }

    @JavascriptInterface
    public void startVideo(String videoAddress){
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse(videoAddress), "video/3gpp"); 
        activity.startActivity(intent);
    }
}

私はビデオを再生するための単一の関数を宣言していますが、あなたは好きなことをすることができます。

最後に、単純なjavascript呼び出しを介してWebViewコンテンツでこれを呼び出します。

<video width="320" height="240" controls="controls" poster='poster.gif'
       onclick="window.JSInterface.startVideo('file:///sdcard/test.3gp');" >
   Your browser does not support the video tag.
</video>

この例は、ビデオの再生に関する私の別の答えから取られていますが、十分に説明する必要があります。

[〜#〜] edit [〜#〜] @CedricSoubrieのコメントによると:アプリケーションのターゲットバージョンが17以上に設定されている場合、注釈を追加する必要があります@JavascriptInterface Webビューにエクスポートする各メソッドの上。

98
Boris Strandjev

YourJavaScriptInterface」クラスで定義されているメソッドは、公開する各メソッドに「@JavascriptInterface」で注釈を付けることを忘れないでください。そうしないと、メソッドはトリガーされません。

たとえば、次のコードは、webviewページからの呼び出し用のGoogleクラウドプリントJavaScriptインターフェースからのものです。

        final class PrintDialogJavaScriptInterface {
        @JavascriptInterface
        public String toString() { return JS_INTERFACE; }

        @JavascriptInterface
        public String getType() {
            return cloudPrintIntent.getType();
        }

        @JavascriptInterface
        public String getTitle() {
            return cloudPrintIntent.getExtras().getString("title");
        }

        @JavascriptInterface
        public String getContent() {
            try {
                ContentResolver contentResolver = getActivity().getContentResolver();
                InputStream is = contentResolver.openInputStream(cloudPrintIntent.getData());
                ByteArrayOutputStream baos = new ByteArrayOutputStream();

                byte[] buffer = new byte[4096];
                int n = is.read(buffer);
                while (n >= 0) {
                    baos.write(buffer, 0, n);
                    n = is.read(buffer);
                }
                is.close();
                baos.flush();

                return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }

        @JavascriptInterface
        public String getEncoding() {
            return CONTENT_TRANSFER_ENCODING;
        }

        @JavascriptInterface
        public void onPostMessage(String message) {
            if (message.startsWith(CLOSE_POST_MESSAGE_NAME)) {
                finish();
            }
        }
    }
1
tyolab

関数は「true」を返します。これにより、HTMLコードの「onclick」プロパティがtrueに等しくなるため、ボタンは「クリックされたまま」になります。

1
R. Maynard