Path clickPath = new Path();
clickPath.moveTo(x, y);
GestureDescription.StrokeDescription clickStroke = new GestureDescription.StrokeDescription(clickPath, 0, 1);
GestureDescription.Builder clickBuilder = new GestureDescription.Builder();
clickBuilder.addStroke(clickStroke);
dispatchGesture(clickBuilder.build(), null, null);
With this code I can perform clicks anywhere on the screen. Is there any way to perform touch and hold gesture using AccessibilityService?
Is there any way to perform touch and hold gesture using AccessibilityService?
I think that you need decide if the gesture willContinue or not. Then, based in your code i suggest change:
GestureDescription.StrokeDescription clickStroke = new GestureDescription.StrokeDescription(clickPath, 0, 1);
To:
GestureDescription.StrokeDescription clickStroke = new GestureDescription.StrokeDescription(clickPath, 0, 1, true);
Simply, add true to last parameter of StrokeDescription. PS: this works only from Android 8+.
Related
I was going through some of the awesome Android libraries and I found the Android BrokenView. It's quite simple to use and uses the touch events to show the broken animation. Here's the code that we're required to add in order to enable a View to behave as a BrokenView:
brokenView = BrokenView.add2Window(context);
listener = new BrokenTouchListener.Builder(brokenView).build();
view.setOnTouchListener(listener);
The problem that I've is that I want to perform the broken animation programmatically i.e, without any actual touch events. I tried looking at the source code but couldn't figure out how to achieve that as most of the methods are protected.
Any ideas on how can I do that?
I've achieved this using a motion event. It works, but I'd prefer to call createAnimator() directly, as I don't want the user to be able to trigger the smash via a touch event.
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis()+1000;
int[] coords = new int[2];
targetView.getLocationOnScreen(coords);
float x = coords[0] + targetView.getWidth()/2;
float y = coords[1] + targetView.getHeight()/2;
MotionEvent motionEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_DOWN,
x,
y,
0
);
mBrokenTouchListener = new BrokenTouchListener.Builder(mBrokenView)
.setEnableArea(mRootView)
.build();
mBrokenTouchListener.onTouch(targetView, motionEvent);
What I'd like to do is this:
Point point = new Point((int)x, (int)y);
BrokenConfig config = new BrokenConfig();
brokenView.createAnimator(mFLTargetView, point, config);
brokenView.setEnable(true);
// or
brokenView.start();
but BrokenConfig is package private, and there's no start() method.
HTH
Here is the situation, I want to set up the navigation mode to adjust the zoom to route according to the current speed. See my code:
SKZoomLevelConfiguration[] zoomConfgs = new SKZoomLevelConfiguration[4];
zoomConfgs[0] = new SKZoomLevelConfiguration(0.0f, 10.0f, 15.0f);
zoomConfgs[1] = new SKZoomLevelConfiguration(10.0f, 20.0f, 13.0f);
zoomConfgs[2] = new SKZoomLevelConfiguration(20.0f, 60.0f, 10.0f);
zoomConfgs[3] = new SKZoomLevelConfiguration(60.0f, 100.0f, 8.0f);
SKNavigationSettings navSettings = new SKNavigationSettings();
navSettings.setNavigationType(SKNavigationSettings.SKNavigationType.REAL);
navSettings.setNavigationMode(SKNavigationSettings.SKNavigationMode.CAR);
navSettings.setDistanceUnit(SKMaps.SKDistanceUnitType.DISTANCE_UNIT_KILOMETER_METERS);
navSettings.setZoomLevelConfigurations(zoomConfgs);
navSettings.setPositionerVerticalAlignment(-0.25f);
SKNavigationManager.getInstance().setNavigationListener(navListener);
SKNavigationManager.getInstance().setMapView(surfaceView);
surfaceView.getMapSettings().setMapDisplayMode(SKMapSettings.SKMapDisplayMode.MODE_3D);
SKNavigationManager.getInstance().startNavigation(navSettings);
isNavigating = true;
So the fact here is the map isn't zooming when the navigation is activated. Probably i'm doing something wrong.
In 2.5 there was an issue with this API - it was fixed for 2.6.
Here is a code snippet of how it works in 2.6:
/**
* Launches a navigation on the current route
*/
private void launchNavigation() {
if (TrackElementsActivity.selectedTrackElement != null) {
mapView.clearTrackElement(TrackElementsActivity.selectedTrackElement);
}
// get navigation settings object
SKNavigationSettings navigationSettings = new SKNavigationSettings();
// set the desired navigation settings
navigationSettings.setNavigationType(SKNavigationType.SIMULATION);
navigationSettings.setPositionerVerticalAlignment(-0.25f);
navigationSettings.setShowRealGPSPositions(false);
SKZoomLevelConfiguration[] configurations = new SKZoomLevelConfiguration[2];
configurations[0] = new SKZoomLevelConfiguration(0, 70, 10);
configurations[1] = new SKZoomLevelConfiguration(70, 100, 15);
navigationSettings.setZoomLevelConfigurations(configurations);
// get the navigation manager object
SKNavigationManager navigationManager = SKNavigationManager.getInstance();
navigationManager.setMapView(mapView);
// set listener for navigation events
navigationManager.setNavigationListener(this);
// start navigating using the settings
navigationManager.startNavigation(navigationSettings);
navigationInProgress = true;
}
Note: The speed values(km/h) set in SKZoomLevelConfigurations are correlated to the current speed(m/s) from SKNavigationState.
The onUpdateNavigationState(SKNavigationState navigationState) method provides notifications when data related to the current speed is updated.
I'm trying to place some clickable sprites on the HUD of my ZoomCamera.
The sprites detect the touch event just fine, but only if the ZoomCamera is placed in its original position.
If I zoom in, or pan the camera, it seems like the touch areas remain in their area relative to the scene, and not to the camera. Therefore the action only works if I click on the area where the sprites existed in the original state.
This is most of the relevant code -
FloorSelectorButton firstButton = new FloorSelectorButton(0, 100, 80, 80,
this.getVertexBufferObjectManager(), 3, this);
FloorSelectorButton secondButton = new FloorSelectorButton(0, 180, 80, 80,
this.getVertexBufferObjectManager(), 2, this);
FloorSelectorButton thirdButton = new FloorSelectorButton(0, 260, 80, 80,
this.getVertexBufferObjectManager(), 1, this);
mScene = new Scene();
mScene.setOnAreaTouchTraversalFrontToBack();
HUD hud = new HUD();
mZoomCamera.setHUD(hud);
hud.attachChild(firstButton);
hud.attachChild(secondButton);
hud.attachChild(thirdButton);
hud.registerTouchArea(firstButton);
hud.registerTouchArea(secondButton);
hud.registerTouchArea(thirdButton);
this.mScrollDetector = new SurfaceScrollDetector(this);
this.mPinchZoomDetector = new PinchZoomDetector(this);
this.mScene.setOnSceneTouchListener(this);
this.mScene.setTouchAreaBindingOnActionDownEnabled(true);
return mScene;
FloorSelectorButton is just a class that extends Sprite and implements the onAreaTouch method.
I hope you guys could help my out!
Thanks!
Apparently my problem was really dumb. It seems that for some reason the APK wasn't updated on the phone and it stayed with the old code (because of this - http://groups.google.com/group/android-developers/browse_thread/thread/2eb92316b474fa00) where I set the registerTouchArea on the scene instead of the HUD.
So now it's fixed! :)
Thanks anyways!
I have made an event injector for Android based on code from the AndroidScreencast project. I'm trying to simulate the Xperia Play touchpad on other devices. My code works great when I'm simulating normal touchscreen events, but does something unexpected when I try to actually simulate the touchpad. Here's my code:
MotionEvent.PointerCoords[] coords = { new MotionEvent.PointerCoords() };
coords[0].x = 200;
coords[0].y = 200;
int[] ptrs = { 0 };
MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), action, 1, ptrs, coords, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHPAD, 0);
windowManager.injectPointerEvent(event, false);
Here's the strange part: the event is sent, but in my little testing app, it shows up as SOURCE_TOUCHSCREEN!
Am I doing something wrong, or is this some Android quirk where it converts non-supported sources?
I'm trying to implement scroll animation for gallery programmatically.
Tried with setSelection(int pos, Boolean animate) and it's not working.
Is there anyway to override setSelection() method.
Just now I have got this problem. I was need to move just one element of the gallery, so the best solution to me was to emulate key down event
myGallery.onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
or
myGallery.onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, null);
Gallery.setSelection(int position, boolean animate);
Refer below URL:
http://groups.google.com/group/android-developers/browse_thread/thread/9140fd6af3061cdf/7f89e53ae53e455b?lnk=gst&q=setselection#7f89e53ae53e455b
Soln:
If you're still looking, I have two possible solutions for you, both
slightly unpleasant:
(1) You can make the gallery do a fling with a chosen velocity, thus:
myGallery.onFling(null, null, velocity, 0);
By tweaking the velocity, you can set up values to move the selection
by one or two in either direction. As the Gallery self-centers, you do
not need to get the destination exactly right.
(2) As the Gallery source is available, you can modify it in order to
implement your own Gallery. It doesn't look as though you need to add
much code to be able to control a fling so as to end at your chosen
selection.
I thought I was going to have to do (2), but found I could get away
with (1) for my problem.
Based on Kurru's excellent thinking of simulating clicking next or previous view.
//scroll forward or backward
private void scroll(int type){
View selectedV = mG.getSelectedView();
int idx = mG.indexOfChild(selectedV);
switch(type){
case FORWARD:
default:
if(idx<mG.getChildCount()-1)
idx++;
break;
case BACKWARD:
if(idx>0)
idx--;
break;
}
//now scrolled view's child idx in gallery is gotten
View nextView = mG.getChildAt(idx);
//(x,y) in scrolled view is gotten
int x = nextView.getLeft()+nextView.getWidth()/2;
int y = nextView.getTop()+nextView.getHeight()/2;
String out = String.format("x=%d, y=%d", x, y);
Log.i(TAG+".scroll", out);
//Kurru's simulating clicking view
MotionEvent event = MotionEvent.obtain(100, 100, MotionEvent.ACTION_DOWN, x, y, 0);
mG.onDown(event);
boolean res = mG.onSingleTapUp(null);
Log.i(TAG+".scroll", "onSingleTapUp return =" + res);
}
I was looking through the Gallery source to see if I could get this feature. It looks like something is possible with this code. However I gave up before I could get it working. It seems like I wasn't passing in the correct coordinates so res always returned false. Would return true if it worked.
Just posting this here in-case someone else wants to give a go at fixing it! (Please post your solution if you manage it!)
Rect rect = new Rect();
gallery.getHitRect(rect);
int x = rect.centerX()+getWindowManager().getDefaultDisplay().getWidth();
int y = rect.centerY();
MotionEvent event = MotionEvent.obtain(100, 100, MotionEvent.ACTION_DOWN, x, y, 0);
timesGallery.onDown(event);
boolean res = timesGallery.onSingleTapUp(null);
I made little change in code given by "Kurru". this is working now
Rect rect = new Rect();
gallery.getHitRect(rect);
int width = Math.abs(rect.width());
if(!isForwardScroll){
width = width * -1;
}
int x = rect.centerX()+width/2;
int y = rect.centerY();
MotionEvent event = MotionEvent.obtain(100, 100, MotionEvent.ACTION_DOWN, x, y, 0);
gallery.onDown(event);
boolean res = gallery.onSingleTapUp(null);