Android Gestures, Single stroke & Multi-stroke produce inconsistent results - java

I'm having a really weird problem while following the Gestures tutorial here: http://developer.android.com/resources/articles/gestures.html.
4 unique gestures are created in Gesture Builder: + - × /
Add and multiply are multi-stroke. Subtract and divide are single stroke.
The Activity loads the pre-built GestureLibrary (R.raw.gestures), adds an OnGesturePerformedListener to the GestureOverlayView, and ends with onGesturePerformed() when a gesture is detected & performed.
Activity layout in XML
<android.gesture.GestureOverlayView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gestures"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gestureStrokeType="multiple"
android:eventsInterceptionEnabled="true"
android:orientation="vertical"
/>
Located in onCreate()
mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
if (!mLibrary.load()) {
finish();
}
GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures.addOnGesturePerformedListener(this);
Located in onGesturePerformed()
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
// We want at least one prediction
if (predictions.size() > 0) {
Prediction prediction = predictions.get(0);
// We want at least some confidence in the result
if (prediction.score > 1.0) {
// Show the spell
Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
}
}
The main problem is the pre-built gestures are not being recognized correctly. For example, onGesturePerformed() is never performed if a horizontal gesture is followed by a vertical (addition). The method is called if a vertical gesture is followed by a horizontal. This is how GesturesListDemo behaves too (GesturesDemos.zip # code.google.com).
Furthermore, the predicted gesture ends up being the incorrect gesture. Add is recognized as subtract; multiply as divide; Subtract as add. It's completely inconsistent.
Finally, add and subtract gestures typically share similar Prediction.score's, which is weird since they differ by an entire stroke.
Sorry about the long post -- wanted to be thorough. Any advice would be greatly appreciated, thanks all.

I realize this is a really old question, but it hasn't been answered yet and this might help someone. I just came across a similar problem and my solution was to use gesture.getStrokesCount() to differentiate between single- and multi-stroke gestures.
Example:
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
// We want at least one prediction
if (predictions.size() > 0) {
Prediction prediction = predictions.get(0);
// We want at least some confidence in the result
if (prediction.score > 1.0) {
if (gesture.getStrokesCount() > 1) {
// This is either add or multiply
}
else {
// This is either subtract or divide
}
}
}

Building on Drew Lederman his answer, you can use this implementation of onGesturePerformed to always get the best result:
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = store.recognize(gesture);
double highScore = 0;
String gestureName = "";
for (Prediction prediction : predictions) {
if (prediction.score > SCORE && prediction.score > highScore &&
store.getGestures(prediction.name).get(0).getStrokesCount() == gesture.getStrokesCount()) {
highScore = prediction.score;
gestureName = prediction.name;
}
}
// Do something with gestureName
}

Yes, are supported, at least from Android 2.3.3. But it is heavily imprecise. Check the second example.

Related

Checking if a different region exists at the specified radius

I create plots based on worldguard regions. I am looking for a good method of checking if there is no other region within a radius of 50 counts in each direction. My point is that someone does not create a plot and someone else's plot. Currently, I checked it in a strange way for me, but it practically worked.
Location p3 = p.getLocation();
p3.setX(p3.getBlockX());
p3.setY(60);
p3.setZ(p3.getBlockZ()+size);
if(region.getApplicableRegions(p3).size() == 0) {
plotsCheck.put(p.getUniqueId(), plotsCheck.get(p.getUniqueId())+1);
}
Location p3a = p.getLocation();
p3a.setX(p3a.getBlockX());
p3a.setY(60);
p3a.setZ(p3a.getBlockZ()+10);
if(region.getApplicableRegions(p3a).size() == 0) {
plotsCheck.put(p.getUniqueId(), plotsCheck.get(p.getUniqueId())+1);
}
Location p4 = p.getLocation();
p4.setX(p4.getBlockX());
p4.setY(60);
p4.setZ(p4.getBlockZ()-size);
if(region.getApplicableRegions(p4).size() == 0) {
plotsCheck.put(p.getUniqueId(), plotsCheck.get(p.getUniqueId())+1);
}
In this way, I checked if it was empty. If so, I added 1 point to the hashmap.
Unfortunately, this does not always work and ends with the fact that several plot plots belong to 2 people. Does anyone of you propose a different solution for this?
WorldGuard already has some built in features for that.
RegionContainer container = getWorldGuard().getRegionContainer();
RegionManager manager = container.get(world);
Region newRegion = //create your region somehow
manager.addRegion(newRegion);
List<ProtectedRegion> regions = new ArrayList<ProtectedRegion>(manager.getRegions().values());
List<ProtectedRegion> overlappingRegions = newRegion.getIntersectingRegions(regions);
if (overlappingRegions.size() > 0) {
//delete region newRegion
} else {
//region is valid
}
This of course works only after the region has already been created.
Code has not been tested. Just searched through the WorldGuard API wiki.
https://worldguard.enginehub.org/en/latest/developer/regions/protected-region/#finding-intersecting-regions

Android OrientationEventListener making to many calls

I have a video on my app and I'm trying to achieve that when the user rotates his device from portrait to landscape the video changes to full-screen.
I'm using OrientationEventListener like this:
orientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int orientation) {
if (orientation <= 45 && playerManager.isFullscreen()) {
onPlayerFullscreenChange(false); //ORIENTATION_PORTRAIT
} else if (orientation <= 135 && !playerManager.isFullscreen()) {
onPlayerFullscreenChange(true); //ORIENTATION_LANDSCAPE
} else if (orientation <= 225 && playerManager.isFullscreen()) {
onPlayerFullscreenChange(false); //ORIENTATION_PORTRAIT
} else if (orientation <= 315 && !playerManager.isFullscreen()) {
onPlayerFullscreenChange(true); //ORIENTATION_LANDSCAPE
}
}
};
The problem is that this listener gets called so many times that my video can't play normally. The activity ends up going throw the OnCreate multiple times unlike before.
The onOrientationChanged(int orientation) method notifies you everytime the sensor detects a change in the way you are holding the Android device.
It is nearly impossible for a user to hold the device still, thus the onOrientationChanged() gets called multiple times.
What I have understood from your question is that, you only want to display a video in fullscreen when the user holds the device horizontally.
Thus consider angular values of 0-45, 135-255, and 315-360 as VERTICAL.
And, angles between 45-135 and 225-315 as HORIZONTAL.
This will make sense if you give it some thought.
Store the "previous orientation", which you can set to null initially for example, if you use String. Then compare it with the currently detected orientation, if they are not the same, take an action (set video to full screen or vice-versa) and save the current orientation values as "previous orientation".
This problem really comes down to better implementing your algorithm. All the best!

Click on a button to chance textfield 50% chance

im very new to java & android development,
I want a textfield that changes 50% to "You win!" or 50% to "You Lose!" when i click/tap a button.
And a image rotating randomly, like it is 0° then it will get a number between 0 and 100 (higher then 50 is clockwise lower then 50 is counter-clockwise)
i might be asking to much xD but i really dont know how i do this.
How do i do this ?
I actually dont want very advanced answers because im very new to java.
Theres is pretty much nothing in my code except for a button and a textfield.
Here a little help to start off.
First you should add an OnClickListener to your button:
yourButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handleButtonClick();
}
});
The handleButtonClick()-method could look like this:
private void handleButtonClick() {
// Here we get a random integer between 0 and 99 (including 0 and 99)
int randomNumber = new Random().nextInt(100);
// Here we check if the random number is even
boolean isEven = randomNumber % 2 == 0;
// Now you can do stuff depending on the integer itself (rotation)
// and depending on whether it's even or not.
if(randomNumber < 50){
// do this
} else {
// do that
}
if(isEven){
// do this
} else {
// do that
}
}
To change the text you use:
yourText.setText(...);
But this is really basic stuff you could read on Android TextView
And rotating images was discussed here Android: Rotate image in imageview by an angle
Please read tutorials or refer to this before asking every little thing you could easily look up. Feel free to ask again when you get stuck.
Good luck.
Math.random() method gives you a floating point number between 0-1 but not included 1.
All you have to do is:
int randomNumber = (int)(Math.random()*101);
if(randomNumber < 50)
...
else
...

GWT infinite scroll with discarding start-of-list results

Looking for a GWT DataGrid component which implements infinite scroll, BUT also makes sure to discard the results no longer visible on the screen : such as the previously loaded results that are not shown anymore.
This is to avoid a memory hog.
I've been trying to find this on Google, but no luck so far.
Please note : I could take a JS library and adapt it to what I need, but I don't think it would work good with GWT's DataGrid component.
Edit: I am interested specifically in an infinite scroll which ALSO discards/releases the topmost results that are not visible (and loads them up as appropriate).
Any ideas ?
As a matter of fact the showcase example has an infinite scrolling CellList. (you can find the code there).
Although this was done with a CellList the same principles should also apply to a DataGrid.
Check out the ShowMorePagerPanel.java file.
Update:
The onScroll function of ShowMorePagerPanel.java will add the new records at the bottom. However you can easily change the behavior:
Something along the lines (not tested tough):
HasRows display = getDisplay();
if (display == null) {
return;
}
boolean loadData = false;
// If scrolling up, change newStart
int oldScrollPos = lastScrollPos;
lastScrollPos = scrollable.getVerticalScrollPosition();
// get the current visible Range
Range currentRange = display.getVisibleRange();
if (oldScrollPos >= lastScrollPos) {
int newStart = Math.max(
currentRange.getStart() - incrementSize,0);
loadData = true;
}
int maxScrollTop = scrollable.getWidget().getOffsetHeight()
- scrollable.getOffsetHeight();
if (lastScrollPos >= maxScrollTop) {
// We are near the end, so increase the page size.
int newPageSize = Math.min(
display.getVisibleRange().getLength() + incrementSize,
display.getRowCount());
loadData = true;
}
if (loadData) {
display.setVisibleRange(newStart, newPageSize);
}

small lags when starting the next moveTo action

[UPDATE] i changed the order a bit so i call the super.act(delta) at the end of the method and it seems to help a bit! But not that sure about it yet.
I got a square system for my map. So its an 2D array and i i make one move the figure does move from one square to the next. While that it's not possible to "stop" the figure between 2 squares. When my characters made one move i check if the Touchpad is touched and if yes i start the next move. While that it seems to lag sometimes and i dont know why!? I really hope you may find the "lag". Here is how i calculate the next move inside the act()of my Actor Character:
#Override
public void act(float delta) {
super.act(delta); // so the actions work
if (moveDone) {
if (screen.gameHud.pad.isTouched()) {
// check in which direction is the touchcontroller
if (screen.gameHud.pad.getKnobPercentX() < 0
&& Math.abs(screen.gameHud.pad.getKnobPercentY()) < Math
.abs(screen.gameHud.pad.getKnobPercentX())) {
// checkt if the |x|>|y|
if (checkNextMove(Status.LEFT)) {
this.status = Status.LEFT;
move(Status.LEFT);
this.screen.map.mapArray[(int) (this.mapPos.x)][(int) this.mapPos.y] = Config.EMPTYPOSITION;
this.screen.map.mapArray[(int) (this.mapPos.x - 1)][(int) this.mapPos.y] = Config.CHARSTATE;
this.mapPos.x--;
moveDone = false;
}
} else if //.... rest is the same just with other directions
else{ //if touchpad isnt touched!
setIdle();
}
updateSprite(delta); //just change the textureRegion if its time for that
} //methode end
Okay so you need some more informations i am sure. Checkmoves like this:
case LEFT:
if (this.mapPos.x - 1 >= 0)
if (this.screen.map.mapArray[(int) (this.mapPos.x - 1)][(int) this.mapPos.y] == Config.EMPTYPOSITION)
return true;
break; //same for all other just direction changin
And the last you need to know is the move(_) i guess. It does add an moveTo Action to my figures.
public void move(Status direction) {
switch (direction) {
case LEFT:
this.addAction(Actions.sequence(
Actions.moveTo((getX() - Config.BLOCK_SIZE), getY(), speed),
moveDoneAction));
break;
moveDoneAction is a simple RunnableAction that set the boolean moveDone to true if its done moving.
i really hope you can help. If you need some more informations please let me know as comment!
There are better tools than StackOverflow for optimizing Android code. Use a profiler and see what is actually happening. Specifically, the traceview profiler: how to use traceview in eclipse for android development? (If you're not using Eclipse, you can use traceview directly via the ADT.)

Categories

Resources