Android longpress not being passed to webView as oncontextmenu event - android

My app is designed to be used outdoors (yachting) and displays a web page in a WebView (so I can use all the display area, fix in landscape, disable extraneous inputs like the BACK_KEY etc.).
In the web page, I want to capture the oncontextmenu event on an image like:
<img src="start_line_pin.png" width=55px
id="pinButton"
oncontextmenu = 'startLinePress("PIN"); return false'\>
When I open the page in my app's webview, a long press doesn't fire the event. Android doesn't seem to be passing the longpress event to the web page.
If I open the page directly in Chrome, my startLinePress function is called with a long press as I intended.
So, can anyone suggest how I get the longpress to be passed into the HTML in my WebView instead of it being handled by Android?

One of the most beneficial features of a forum such as this is that it makes you really think about your problem from another point of view.
The answer to my problem lies in the fact that I was trying to use an undocumented feature - the longClick on the web page invoking the oncontextmenu event.
The answer is to use the onLongClick event in java and then pass the event to the javascript function by using the WebView.loadUrl method. My WebView is contentView and the javascript function is javascript:startLinePress as follows:
contentView.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
WebView.HitTestResult hr = ((WebView)v).getHitTestResult();
if(hr.getType() == 5){
contentView.loadUrl("javascript:startLinePress(\"ACTIVITY\")");
}
It needs a little more work to identify which element was clicked, by examining hr.getExtra() but you get the general idea.
Thanks stackoverflow for the great forum.

Related

simulate and dispatch touch event

I have loaded a HTML page (say it has a text and a button at the end of the page to share the text) inside a WebView.
The thing is i want to simulate the touch event of that share button and dispatch it to webview. That is (once the user spends some time in reading the text i would like to simulate the share button click (onClick method should be called) in an automated fashion so that even if user doesn't click share i have made it mandatory to be shared.
That's the logic. I refereed to some questions reg touch events in Stack Overflow and found that dispatchTouchEvent and MotionEvent should be used but not clear how to use them and apply my logic.
It would be really helpful if someone could explain its usage with respect to the above quoted idea in a detailed manner.
This is possible if you know the x,y coordinates where to click.
in this java example (not mine) it shows that given a rectangle of a DOM element, it will simulate a click:
The advantage here is that you can simulate the click even if the user didnt initiate an action (which is restricted by the browser itself)
https://github.com/46cl/cordova-android-focus-plugin/blob/master/src/android/Focus.java
This is a cordova example. See here for an example on how to call it from a regular android program:
Android Webview: Execution of javascript from java method called from javascript
runOnUiThread(new Runnable() {
public void run() {
final long uMillis = SystemClock.uptimeMillis();
webView.dispatchTouchEvent(MotionEvent.obtain(uMillis, uMillis,
MotionEvent.ACTION_DOWN, centerLeft, centerTop, 0));
webView.dispatchTouchEvent(MotionEvent.obtain(uMillis, uMillis,
MotionEvent.ACTION_UP, centerLeft, centerTop, 0));
}
});
you would need to dispatch the call from your javascript passing the rect to your java code:
here is an example (of a cordova app) calling the java method from javascript:
https://github.com/46cl/cordova-android-focus-plugin/blob/master/www/focus.js

Button in a webview without Javascript

I have an android application that loads a webview from a server. I do not have the server code so I cannot change anything in Javascript. I want to figure out when a button is being clicked in a webview and what is the label in the button. I do not know the Id, I just want to get the label.
I tried searching for this but could not find an answer. I found solutions where you can work in the javascript but in my case I cannot.
This suggestion may help to find useful information that could lead to determination of your button label. Override shouldOverrideUrlLoading(), shouldInterceptRequest() and/or onLoadResource() for the WebViewClient so you can get at the URL of any redirects.
Example:
webview.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Try to learn something useful from the 'url' here.
// Continue as normal, loading the 'url' within this WebView.
view.loadUrl(url);
return false; // Allow the WebView to handle the request.
}
// Optional: Add similar for "shouldInterceptRequest()" and/or "onLoadResource()".
});
Note: Overriding shouldOverrideUrlLoading() as above is the standard way to keep redirects within the same WebView rather than redirecting to the default browser application.
You might really want to check this page:
Building Web Apps in WebView (Google API Guides)
Specifically, it seems that addJavascriptInterface might be what you are looking for:
addJavascriptInterface(Object object, String name)
It allows you to execute your Java code from javascript and, paired with the ability to insert code in a page, it's an incredibly powerful tool for granting you a high level of coupling between your Activity and your page.
I think that at this point you will already know what to do, but I'll sketch a possible course of action anyway:
create a javascript interface with the callbacks you want executed in your activity when a button is pressed
as soon as your page loads, install the code to call your javascript interface in each button (or link) by injection
Hope this helps

Capturing webview clicks (not just from links)

Is there some way to set an onClickListener for a webview? I've seen code here to intercept url clicks but I would just like to intercept anytime a user clicks the area the webview's on or swipes across it with their finger. I load html directly into the webview (as opposed to giving it a url) for formatting reasons and I'd really like to be able to tell any time the user clicks anywhere on the screen. I had been using a textview and that works fine, but is it doable with a webview?
Have you tried instead of an onClick, an onLongClick listener?
Taken from my recent project:
printMessageTextView.setOnLongClickListener(new OnLongClickListener() {
int active = 0;
#Override
public boolean onLongClick(View v) {
In this case, the int active = 0; is probably not needed. But should be able to listen for you.

Is there any way to capture Android's back button in mobile webkit browsers?

I know that in PhoneGap there's a way to do this, but can it be done for an HTML5 web app? I'd like to have Android users be able to use the back button within the webapp to provide a consistent UX, but of course the default is to go back in the browser history and leave the app...
Edit: tried, didn't do anything on any button press on a Google Nexus S:
document.onkeydown = checkKeycode;
function checkKeycode(e) {
var keycode;
if (window.event) keycode = window.event.keyCode;
else if (e) keycode = e.which;
alert("keycode: " + keycode);
}
Edit again: The ultimate answer seems to be to create history points at each UX interaction -- using URL hashes like #!/main/about_us in the URL. This then allows for back-button use, so long as you make sure that the UI triggers a history.back() when a UI back button is tapped.
The ultimate answer seems to be to create history points at each UX interaction -- using URL hashes like #!/main/about_us in the URL. This then allows for back-button use, so long as you make sure that the UI triggers a history.back() when a UI back button is tapped.
Override the OnKeyDown Event in your app and look for KEYCODE_BACK.
If you are handling the event then return true else false.

Limit WebView touch handling to links

Is it possible to capture touch events over a WebView in the activity that contains it, without loosing link functionality?
Consider a WebView showing a webpage with links. If the user taps on a link I would like the WebView to handle the touch event. If the user taps somewhere else I would like the activity to handle the touch event.
How can this be done?
Yes, it is.
(I can't elaborate more on this unless you are more specific on your question.)
If i understand your question correctly it'd seem difficult to interpret whether something is a link or not in the onTouchEvent() since all it knows about is X,Y coordinates (not html). However, off the top of my head it seems you could probably use the javascript binding piece in WebView to have javascript decide if the something is a link or not and act accordingly. Again, I haven't done this before nor tested it...just thinking out loud.
When initializing your WebView, try:
mWebView.setWebViewClient(new WebViewClientOverrider());
Then create a private class:
private class WebViewClientOverrider extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//TODO handle the link
return true;
}
}
Lastly, replace the TODO handle the link line with your own code for handling the link selection.
Or you can monitor the stack trace for:
android.webkit.CallbackProxy.uiOverrideUrlLoading()
See http://www.javapractices.com/topic/TopicAction.do?Id=78 for how to determine your stack trace from a throwable (created in an overriden WebView.loadUrl() method).

Categories

Resources