simulate and dispatch touch event - android

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

Related

JQuery Mobile swipe event only firing every other swipe

I have set up a swipeleft event in my app to move between fields of a form. All of the fields are dynamically generated, so I'm not swapping between pages, I'm clearing and re-generating all the DOM elements. The problem is the swipe event only fires every other time I swipe on the page or if I touch or tap anything on the page.
Here's the code that sets up the events:
$(document).delegate("#scorePage", "pageshow", function() {
$.event.special.swipe.scrollSupressionThreshold = 10;
$.event.special.swipe.horizontalDistanceThreshold = 30;
$.event.special.swipe.durationThreshold = 500;
$.event.special.swipe.verticalDistanceThreshold = 75;
$('#divFoo').on("swipeleft", swipeLeftHandler);
$('#divFoo').on("swiperight", swipeRightHandler);
tableCreate(traits[0].keyboardID);
});
For context, tableCreate is putting a dynamically generated table into divFoo that contains information a user can pick from. Here's the event code itself:
function swipeLeftHandler() {
$("#divFoo").empty();
traitIndex++;
tableCreate(traits[traitIndex].keyboardID);
}
Why is my swipe event only firing every other time there is a swipe on the page?
Primarily testing on Android right now, if that makes a difference.
Edit I'm using JQuery Mobile version 1.4.4
I figured out a way around this problem by simply rolling my own implementation of these events. There's some sample code on how to do something similar here:
https://snipt.net/blackdynamo/swipe-up-and-down-support-for-jquery-mobile/
If anyone else uses this code to fix my same problem, make sure to be aware that the article is implementing swipeup and swipedown so you will have to adapt it. In the end, I'm not entirely sure about the differences between this code and the actual implementations of swipeleft and swiperight, but this works consistently so I'm cutting my losses and going with it.

Android longpress not being passed to webView as oncontextmenu event

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.

Communication between web view and titanium Android app

I have a titanium app where I load a web view. In this web view I load a html5 with a chart.
I want to show a vertical line and get some information about the position of the line. This line will be controlled by a slider in Titanium App, so the line would change its position very fast and very often.
You can see something similar here: graph
In html file, I write the graph and I add a listener for an event. When the event is fired, it draw a line in some position with this code:
function updateVerticalLine(posX) {
drawSeries(c);
c.strokeStyle = '#000000';
c.beginPath();
c.moveTo(getXPixel(posX), graph.height() - yPadding);
c.lineTo(getXPixel(posX), 0);
c.stroke();
}
In Titanium app, I only fire the event when I receive the change slider event and I pass the new position of the line:
slider.addEventListener('change', function(e) {
Ti.App.fireEvent('sliderhtml5line:change', {
value : e.value
});
});
It works ok on ios, but on Android, it is very slow and events are disorganized.
Do you know how I can solve it? Is there any better option for this?
Thanks!!
it should be done the otherway.
when the user changes the slider, you should call the method in the HTML page using the evaljs function to update the user interface directly

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).

What DOM events are available to WebKit on Android?

I'm building a mobile web app targeting Android users. I need to know what DOM events are available to me. I have been able to make the following work, but not terribly reliably:
click
mouseover
mousedown
mouseup
change
I have not been able to get the following to work:
keypress
keydown
keyup
Does anyone know the full list of what is supported and in what contexts (e.g., is onchange only available to form inputs?)? I can't find a reference for this on The Googles.
Thanks!
Update: I asked the same question on the Android developers list. I will be doing some more testing and will post my results both here and there.
OK, this is interesting. My use case is that I have a series of links (A tags) on a screen in a WebKit view. To test what events area available, using jQuery 1.3.1, I attached every event listed on this page (even ones that don't make sense) to the links then used the up, down, and enter controls on the Android emulator and noted which events fired in which circumstances.
Here is the code I used to attach the events, with results to follow. Note, I'm using "live" event binding because for my application, the A tags are inserted dynamically.
$.each([
'blur',
'change',
'click',
'contextmenu',
'copy',
'cut',
'dblclick',
'error',
'focus',
'keydown',
'keypress',
'keyup',
'mousedown',
'mousemove',
'mouseout',
'mouseover',
'mouseup',
'mousewheel',
'paste',
'reset',
'resize',
'scroll',
'select',
'submit',
// W3C events
'DOMActivate',
'DOMAttrModified',
'DOMCharacterDataModified',
'DOMFocusIn',
'DOMFocusOut',
'DOMMouseScroll',
'DOMNodeInserted',
'DOMNodeRemoved',
'DOMSubtreeModified',
'textInput',
// Microsoft events
'activate',
'beforecopy',
'beforecut',
'beforepaste',
'deactivate',
'focusin',
'focusout',
'hashchange',
'mouseenter',
'mouseleave'
], function () {
$('a').live(this, function (evt) {
alert(evt.type);
});
});
Here's how it shook out:
On first page load with nothing highlighted (no ugly orange selection box around any item), using down button to select the first item, the following events fired (in order): mouseover, mouseenter, mousemove, DOMFocusIn
With an item selected, moving to the next item using the down button, the following events fired (in order): mouseout, mouseover, mousemove, DOMFocusOut, DOMFocusIn
With an item selected, clicking the "enter" button, the following events fired (in order): mousemove, mousedown, DOMFocusOut, mouseup, click, DOMActivate
This strikes me as a bunch of random garbage. And, who's that cheeky IE-only event (mouseenter) making a cameo, then taking the rest of the day off? Oh well, at least now I know what events to watch for.
It would be great if others want to take my test code and do a more thorough run through, perhaps using form elements, images, etc.
Since this is the second most popular Android + JavaScript post on SO (which is just a sad commentary on the state of web development targeting the Android platform), I thought it may be worthwhile including a link to pkk's touch event test results at http://www.quirksmode.org/mobile/tableTouch.html and also http://www.quirksmode.org/mobile/ in general.
As of Android 1.5, the same touch(start|move|end|cancel) events that the iPhone supports work in Android as well.
One problem I found was that touchmove ends get queued up. No workaround yet.

Categories

Resources