问题
Is it possible to handle software keyboard events from a webview in a host Android application?
For example, can my application's Activity listen the typed content in the search field of a webview displaying Google website?
Considering the method described below this would be possible if I overwrite it returning true, but unfortunatelly I was not able to do it. Any ideas?
public boolean shouldOverrideKeyEvent (WebView view, KeyEvent event)
Added in API level 1
Give the host application a chance to handle the key event synchronously. e.g. menu shortcut key events need to be filtered this way. If return true, WebView will not handle the key event. If return false, WebView will always handle the key event, so none of the super in the view chain will see the key event. The default behavior returns false.
Parameters
view The WebView that is initiating the callback.
event The key event.
Returns
True if the host application wants to handle the key event itself, otherwise return false
回答1:
I think the shouldOverrideKeyEvent
method simply tells the system which "window" should be getting notified of key events; this does NOT pass WebView javascript events back to the Activity.
If you need to pass information from a WebView to your Activity, you can use the JavascriptInterface. Note that this is only possible on a website that you control; otherwise it would be a security loophole, providing your app with access to sensitive data.
First, create a class to act as your interface:
class MyJavaScriptInterface{
//Methods to call via js in the WebView go here
}
Then initialize the interface on your WebView:
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new MyJavaScriptInterface(), "JSInterface");
Now, you said you wanted to pass the typed content from a text field back to the Activity. For that, register an event listener for the text field on blur, which will fire when the field loses focus.
<!-- HTML element to listen for blur -->
<input id="field" type="text" />
<script>
//Communicate with Javascript Interface
var jsFieldBlur = function(field){
//Only call if the interface exists
if(window.JSInterface){
window.JSInterface.onFieldBlur(field.id, field.value);
}
};
//Obtain reference to DOM element
var field = document.getElementById("field");
//Attach blur listener
field.addEventListener("blur", function( event ) {
jsFieldBlur(event.target);
}, true);
</script>
Finally, we need to add the onFieldBlur
method to the MyJavascriptInterface class so it can be called via javascript. Any methods defined this way must be preceded by @JavascriptInterface
in order to be visible to the WebView.
class MyJavaScriptInterface{
@JavascriptInterface
public void onFieldBlur(String fieldId, String fieldValue){
//Do something with value
Toast.makeText(getContext(), fieldId+"="+fieldValue, Toast.LENGTH_LONG).show();
}
}
回答2:
public class WebViewDemo extends Activity {
WebView myWebView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("file:///android_asset/test.html");
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
// myWebView.setWebViewClient(new WebViewClient());
myWebView.setWebViewClient(new MyWebViewClient());
}
public class JavaScriptInterface {
Context mContext;
/** Instantiate the interface and set the context */
JavaScriptInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
startActivity(new Intent(WebViewDemo.this, WebViewDemo.class));
}
}
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals("www.google.com")) {
// This is my web site, so do not override; let my WebView load the page
Toast.makeText(getApplicationContext(), "www.google.com", Toast.LENGTH_SHORT).show();
return false;
}
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the BACK key and if there's history
if ((keyCode == KeyEvent.KEYCODE_ENTER)) {
// here you can got key event of enter key ( whether you used as for search of any other option
return true;
}
// If it wasn't the BACK key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
}
来源:https://stackoverflow.com/questions/26346070/listen-webview-key-events-from-software-keyboard-in-android-activity