Android 4.4で新しくなったevaluateJavascriptメソッドを使おうとしているのですが、返ってくるのはnullの結果ばかりです。
webView1.evaluateJavascript("return \"test\";", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Log is written, but s is always null
}
});
このメソッドに結果を返すにはどうしたらいいですか?
Update: 少しだけ情報を追加しました。
1.私はINTERNET権限を設定しています。
2.setJavascriptEnabled(true);を設定しています。 3.アポストロフィーの文字列を試してみました。
return 'test';としています。 4.JSオブジェクトを試してみた:
return { test: 'this' }。 5.5.
console.log('test');は正常に実行されています。 6.6. 次のように
targetSdkVersion`を19に設定します。アプリがWebViewを使用している場合を参照してください。
**端末:Nexus 7とNexus 5(純正)の両方
このサンプルでは、evaluateJavascriptメソッドが使われている例があります。
https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example
基本的には、WebViewで実行したJavascriptが値を返した場合、それがコールバックに渡されます。
注意すべき点は、OnReceiveValueで返される文字列が、何を返すかによってJSON Value、JSON Object、JSON Arrayのいずれかになるということです。
単一の値を返す場合は、JSONリーダーでsetLenient(true)を使用しないと動作しないことに注意してください。
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// In KitKat+ you should use the evaluateJavascript method
mWebView.evaluateJavascript(javascript, new ValueCallback<String>() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onReceiveValue(String s) {
JsonReader reader = new JsonReader(new StringReader(s));
// Must set lenient to parse single values
reader.setLenient(true);
try {
if(reader.peek() != JsonToken.NULL) {
if(reader.peek() == JsonToken.STRING) {
String msg = reader.nextString();
if(msg != null) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}
}
} catch (IOException e) {
Log.e("TAG", "MainActivity: IOException", e);
} finally {
try {
reader.close();
} catch (IOException e) {
// NOOP
}
}
}
});
}
文字列のレスポンスに対してパーサーを使用したい理由は、それがJSON値に変換されるため、引用符で囲まれてしまうからです。
例えば、あなたが行った場合
mWebView.evaluateJavascript("(function() { return 'this'; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints: "this"
}
});
と入力すると、二重引用符で囲まれた文字列「this」が表示されます。
他にも注目すべき例があります。
mWebView.evaluateJavascript("(function() { return null; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints the string 'null' NOT Java null
}
});
mWebView.evaluateJavascript("(function() { })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); //s is Java null
}
});
mWebView.evaluateJavascript("(function() { return ''; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints "" (Two double quotes)
}
});
さて、ここでいう「結果」とは、あたかもJavascriptのコンソールにコマンドを入力しているかのような、Javascriptの呼び出しの結果であることがわかりました。
したがって、結果を得るためには、関数でラップする必要があります。
webView1.evaluateJavascript("(function() { return \"this\"; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints 'this'
}
});
これでも動作します。
webView1.evaluateJavascript("window.variable = \"asd\";", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints asd
}
});
このメソッドは、Javascript オブジェクトも扱います。
webView1.evaluateJavascript("(function() { return { var1: \"variable1\", var2: \"variable2\" }; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints: {"var1":"variable1","var2":"variable2"}
}
});
AndroidJSCoreは、WebViewを使用しないJavaScriptを評価するのに適した代替手段です。
もしあなたがWebViewにこだわりたいと思い、以前のバージョンのAndroid(4+)でJavaScriptを評価する必要があるなら、ここに小さなライブラリがあります。
https://github.com/evgenyneu/js-evaluator-for-android
jsEvaluator.evaluate("put your JavaScript code", new JsCallback() {
@Override
public void onResult(final String result) {
// get result here (optional)
}
});