So, I have plotted a GPX route in my MapView, and I am listening for location changes.
Ultimately I want to give my user notification when they are off/on course.
So, I can imagine just brute-force going through all my GPX coordinates and do a Location.distanceTo for each for each of them. But that seems expensive.
I could reduce the cost by doing it infrequently.
I am wondering if someone has a clever idea for achieving this?
You can use the function distanceTo but not inside onLocationChanged (because it is called very frequent) , you should do a timer and check if the user going off course in each 5 seconds (for example), this is how to implement the timer:
1- declare this as global variable:
private Timer myTimer;
2- add this code in your onCreate():
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
TimerMethod();
}
}, 0, 5000);
3- add these two functions in your class:
private void TimerMethod()
{
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
//do your test for off course here
}
};
Good luck
I would probably keep track of three coordinates: Last, Current, Next. You can calculate the distance and direction from Last to Current and the location and direction the user is going and come up with some algorithm to ensure the user is going the right way (ensure that the user is approaching Current, ensure that they're within some distance of the line from Last to Current, etc.)
Then at some point you need to realize that the user has come as close as they're ever going to towards Current and are now heading for Next. Then you'll shift the points down (Last = Current; Current = Next; Next = ???;). Again there are a number of ways you could make this determination (user has gotten close enough to Current, user is heading towards Next and away from Current, etc.)
You might want to include some look-ahead in case you miss a few points, especially when points are close together, but you don't want to do too much. Test your route with loops in the paths and make sure you don't jump ahead. You'll probably also need to implement some sort of holyExpletiveIHaveNoIdeaWhereTheUserIsGoing() method to recover from the (inevitable) errors.
Related
I want to create a condition to wait for a broadcast upon a button press
right now I am just doing solo.sleep(10000)
but I dont want to sleep solo for nothing
How do I formulate the condition "broadcast received" ?
Ok explanations
Robotium Solo is an instrumentation framework with nice api
It has a method called "solo.waitForCondition(Condition, int timeout)"
I want to formulate (the word formulate means say what i want to say in correct words)
the correct condition that will tell me that the broadcast was indeed received
I want to write some code (I don't know which exactly) to know that the broadcast was indeed sent
for example, if i want to know that a button is now visible i would write
solo.waitForCondition(new Condition(){
public boolean isSatisfied(){
Button b = getActivity().findViewById(R.id.myButton);
return b.getVisibility() == View.VISIBLE;
}
}
now back to my question - What (not how, but what) do I write in order to know for sure that the broadcast was sent inside the isSatisfied method
I suppose you meant that you don't want to sleep for 10 seconds, if you get the broadcast earlier. What you can do is
long beginTime = new Date().getTime();
while (new Date().getTime() - beginTime < 10000) {
solo.sleep(500);
if (conditionMet) {
// Do something
break;
}
}
This way you can do these checks on smaller intervals.
Ok, so in fact this is more or less how waitForCondition is implemented. Unfortunately I don't think you can listen for events with robotium. What you can do is monitor the view hierarchy. In your case, there should be some difference to the views that is triggered when the button is clicked, so that is what you need to check for in the Condition (and your example does that).
This is if you don't want to edit the code you are testing. If you are willing to change the code, you can add an onClickListener() and in that you can set a view's Tag to a boolean for example. Later in robotium you can check for that tag for being set. This is however not good way to do it, because you are adding more code just for the sake of the tests.
I'm starting to develop a game in libgdx, and I'm wondering what the best practice is for the following situation. There are two things that I'm trying to do at the moment: move a menu (sprite) into place, and pan the camera to the player sprite. My idea to accomplish these things is to have an 'action_stack' ArrayList in the render() function. The ArrayList would contain 'Action' instances. Each Action instance would have a step() function, which would be over-ridden. In the render() function, I would iterate through action_stack, and fire each elements' step() function. So, to accomplish moving the menu into place, I would create the class:
public class MenuAnim1 implements Action {
private int targetX;
private int targetY;
private Sprite menu;
public MenuAnim1() {
//set initial sprite and position
}
public Step() (
//move this.menu towards targetX and targetY
//draw the sprite
//if not at target position, do nothing
//if at target position, remove this object from action_stack
}
}
...and put an instance into the action_stack:
MenuAnim1 menuAnim1 = new MenuAnim1();
action_stack.add(menuAnim1);
Sorry if my Java is bad, I'm not super familiar with it. Anyways, my question is: is this even good practice? What do people normally do? Is there a better way to do what I'm describing above?
I have never used Actions, but your idea is good. If you want them to be time dependant (and thus fps independant), be sure to use the time that has passed since the last frame to the current, also known as delta or deltaTime. You can get it like this:
Gdx.graphics.getDeltaTime();
so, to make your action move the sprite, for example, to the right, this would do the trick:
speed = 10; //It will move 10 units per second.
delta = Gdx.graphics.getDeltaTime();
menu.translateX(speed*delta);
(Sprite#translateX)
On developing a painting canvas application in android, i need to track all the points and have to redraw it in another canvas. Now i am able to track all the points, but don't know how to synchronize the point drawing in case of draw and redraw ie the user should redraw the points at the same time gap as in the draw. How can i achieve this?
Not sure if this is the sort of answer you are looking for but I would record the events with a sort of timestamp, really a time difference to the next point. Something like:
class Point {
int x;
int y;
long deltaTime;
}
Its up to you how precise you want to be with the timing. Second to millisecond precision should be good enough. You could interpret deltaTime as either the time until this point should be drawn or the time until the next point should be drawn (I'm going to use the latter in my example).
A few reasons to use a deltaTime instead of a direct timestamp is that it lets you check for really long pauses and you are going to have to compute the delta time anyways in playback. Also using it as a long should give you enough room for really lengthy pauses and lets you use the Handler class which accepts a long integer for the number of milliseconds to wait before executing.
public class Redrawer implements Handler.callback {
LinkedList<Point> points; //List of point objects describing your drawing
Handler handler = new Handler(this); //Probably should place this in class initialization code
static final int MSG_DRAW_NEXT = 0;
public void begin(){
//Do any prep work here and then we can cheat and mimic a message call
//Without a delay specified it will be called ASAP but on another
//thread
handler.sendEmptyMessage(MSG_DRAW_NEXT);
}
public boolean handleMessage(Message msg){
//If you use the handler for other things you will want to
//branch off depending on msg.what
Point p = points.remove(); //returns the first element, and removes it from the list
drawPoint(p);
if (!points.isEmpty())
handler.sendEmptyMessageDelayed(MSG_DRAW_NEXT, p.deltaTime);
public void drawPoint(Point p){
//Canvas drawing code here
//something like canvas.drawPixel(p.x, p.y, SOMECOLOR);
//too lazy to look up the details right now
//also since this is called on another thread you might want to use
//view.postInvalidate
}
This code is far from complete or bullet-proof. Namely you will need to possibly pause or restart the redrawing at a later time because the user switched activities or got a phone call, etc. I also didn't implement the details of where or how you get the canvas object (I figure you have that part down by now). Also you probably want to keep track of the previous point so you can make a rectangle to send to View.postInvalidate as redrawing a small portion of the screen is much faster than redrawing it all. Lastly I didn't implement any clean-up, the handler and points list will need to be destroyed as needed.
There are probably several different approaches to this, some probably better than this. If you're worried about long pauses between touch events simply add a check for the deltaTime if its greater than say 10 seconds, then just override it to 10 seconds. Ex. handler.sendEmptyMessage(MSG_DRAW_NEXT, Math.min(p.deltaTime, 100000)); I'd suggest using a constant instead of a hard coded number however.
Hope this helps
I have two class, one is an activity that can handle Chronometer, another is handle LocationListener.I want to run them together to use stopwatch and to get changed location.
Anyone have any samples or suggestions ? Thanks
Addition:
Sorry for the confuse question. I just need to know how to make chronometer run while keeping location that changed.
Well, you could use the LocationListener to add Location to an array every time it is changed to keep track of location.
Example:
public class MyClass implements LocationListener{
private static List<Location> locationList = new ArrayList<Location>();
#Override
onLocationChanged(Location location){
locationList.add(location);
}
}
Then you could use System.getTimeMillis() (or something akin) when you want to get the start time, and the same method when you want to get the end time. Just subtract the two to get the time difference and how long it took.
I am writing an application that searches a database in "realtime".
i.e. as the user presses letters it updates a search results list.
Since the search can take a while, I need to do the search in background and allow new key presses to re-start a search. So that is a user presses 'a' (and the code starts searching for "a"), then presses 'b' - the code will NOT wait for "a" search to end, then start searching for "ab", but rather STOP the "a" search, and start a new "ab" search.
To do that I decided to do the search in an AsyncTask. Is this a wise decision ?
Now - whenever a keypress is detected, I test to see if I have an AsyncTask running. If I do - I signal it (using a boolean within the AsyncTask) it should stop. Then set a timer to re-test the AsyncTask within 10 mSec, to see if it terminated, and start the new search.
Is this a smart method ? Or is there another approach you would take ?
TIA
First yes, AsyncTask is a good way to do this. The problem I see with your approach is the timer waiting to watch something die. When you invoke the asyncTask hold onto a reference of it. Let it keep state for you so you know if it's out searching or it's has returned. When the user clicks another letter you can tell that asyncTask to cancel. Something like this:
public void onClick() {
if( searchTask != null ) {
searchTask.cancel();
}
searchTask = new SearchTask( MyActivity.this ).execute( textInput.getText() );
}
public class SearchTask extends AsyncTask<String,Integer,List<SearchResult>> {
private boolean canceled = false;
protected onPostExecute( List<SearchResult> results ) {
if( !canceled ) {
activity.handleResults( results );
}
}
public void cancel() {
canceled = true;
}
}
This is safe because onPostExecute() is on the UI thread. And cancel() is only called from the UI thread so there is no thread safety issues, and no need to synchronize. You don't have to watch a thread die. Just let the GC handle cleaning up. Once you drop the reference to the AsyncTask it will just get cleaned up. If your AsyncTask blocks that's ok because it only hangs up the background thread, and when the timeout hits it will resume by calling onPostExecute(). This also keeps your resources to a minimum without using a Timer.
Things to consider about this approach. Sending a new request everytime a new letter is typed can overload your servers because the first few letters are going to produce the largest search results. Either limit the number of results you'll return from the server (say 10-50 results max), or wait until they've entered enough characters to keep results down (say 3). The cons of making the user type more characters is the feedback doesn't kick in until 3 chars. However, the pro is it will dramatically reduce the hits on your server.