Sending data our GPS coordinates properly - android

So basically what my problem is:
I am trying to make some sort of GPS app and in it I want to send the coordinates(longitude latitude) of where the user is to a server. It works well so far but I have reached a problem. I want to call my sendDataToserver() method periodically (every 5 seconds or so - BTW this is working correctly) method only after coordinates have been received from the GPS. But the thing is I cant figure out how to make ...(if statement or something)... the sendDataToserver() method to be called only after the coordinates have been received/changed. I am using an if statement right now:
if(lat != 0 && long !=0)
{
sendDataToserver();
}
but ... as you might have guessed 0.0 is a valid coordinate ... So can you give me an idea how to fix this problem so that sendDataToserver() could be called every 5 seconds or so and only if coordinates have been received?

First of all sending GPS data again & again to websever is not a good idea. This will dry your battery soon. To avoid this situation you should create a batch of 10-20 points togather in Json kind of format and then send those collected data togather.
Now coming to your GPS point, You need to use GpsStateListener. This listener has returns GPS_EVENT_FIRST_FIX when your device finds a GPS point. So you can write a condition that as soon as Gps State Listener returns this value you call your web-service call.
final Listener onGpsStatusChange = new GpsStatus.Listener() {
#Override
public void onGpsStatusChanged(int event) {
// TODO Auto-generated method stub
switch(event){
case GpsStatus.GPS_EVENT_STARTED:
// Started...
break ;
case GpsStatus.GPS_EVENT_FIRST_FIX:
// First Fix...
break ;
case GpsStatus.GPS_EVENT_STOPPED:
// Stopped...
break ;
}
}
};

at first: do not use long as variable Name.
what about saving the last coordinate in a temporary variable like:
if(lastLat != newLat && lastLong != newLong) // code goes here

This might solve your problem:
unsigned long GPS_WAIT=5000;
curr_time= millis();
if(curr_time>=GPS_WAIT)
{
sendDataToserver();curr_time=0;
}else
{
curr_time= millis();
}

Related

Updating a chart from an ArrayList over time?

I have an ArrayList of values, and I would like to iterate through the ArrayList. For every new value, I would like to update the chart with that value, and then wait a set amount of time before doing the same thing to the next value.
At the moment, my log says that all of the values are being iterated over. However, on my testing device, the chart does not update until the very end; at that point, all of the values are loaded at once, so there is no desired "slideshow" effect.
When I want to start playing back the values in my ArrayList, this method is called:
public void playback(){
if(ret != null) {
for (int x = 0; x < ret.size(); x++) {
addEntry(ret.get(x));
try {
Thread.sleep(100);
} catch (Exception e){
//Do nothing
}
}
} else {
Log.d(LOG_TAG, "ret was null.");
}
}
What can I do so that the values are displayed on my chart, one after another, with a certain amount of time between each value?
Edit: Here was the solution I ended up implementing with help from Shadab Ansari:
public void playback(){
if(ret != null) {
addEntry(0);
} else {
Log.d(LOG_TAG, "ret was null.");
}
}
private void addEntry(int index) {
final int in = index;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
yVals1.get(0).setVal(ret.get(in).intValue());
RadarDataSet set1 = new RadarDataSet(yVals1, "Set 1");
// And other UI stuff
// Recursive call!
if(in < ret.size() - 1){
addEntry(in + 1);
}
}
}, 100);
}
In case it was not clear, ret was a global variable that contained the arrays that I was going to be inserting. yVals1 was an ArrayList of Entries to populate the radar chart.
The end result is that, in this example code, the chart is updated with the next value in my ArrayList every 100 milliseconds. During this time I can still zoom in/out of the chart and rotate it with no problems.
If your addEntry() performs a UI operation then let me explain your problem -
Explanation -
Android is an event based system. Something happens on the device (the screen is touched, a key is pressed, etc.) and Android raises an event. An App is notified of an event and when one occurs that it needs to respond to it does so, often running the code that you have written. Your App runs its code in a loop under the control of the Android Operating Systems (OS). This code loop is referred to as the App's thread of execution. There is only one thread and it is responsible for both running the App code and updating the display.
So the UI update does not happen immediately and your making the UI thread sleep for 100 ms every time the loop runs. And when Android tries to update the UI, you make the thread sleep which means during this time period UI thread will not do anything. And this happens till your loop finishes. After your loop ends, the final event gets executed and you will see your UI updated by the call of addEntry() with the latest value passed.
Solution -
You can use postDelayed()-
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Perform your task and it will be executed after 100 ms
}
},100);

How to handle live data of Accelerometer in android?

I need to perform Dynamic Time Wrapping(DTW) algorithm with some previously stored data and Accelerometer data. But I am unable to handle the huge amount of data coming from accelerometer. I need to determine a step. In order to do that I have stored a number of data previously and trying to match with the current data.
ArrayList<Double> test=new ArrayList<Double>();
public void onSensorChanged(SensorEvent event) {
double x=event.value[0];
double y=event.value[1];
double z=event.value[2];
double a=Math.sqrt(x*x+y*y+z*z);
test.add(a);
new ProgressRunner().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,x);
private class ProgressRunner extends AsyncTask<Double, Integer, Boolean>
{
#Override
protected Boolean doInBackground(Double... params) {
new Thread(new Runnable() {
#Override
public void run() {
double r=DTWDistance(StepSamples.sample1, standTest);
if(r<700) /* "Step Detected */
}
}).start();
return null;
}
But I am getting huge data coming from the sensor. My question is how do I handle this data and match with a sample data continuously. Also I have tested with a Log.d, I'm sure the problem is related to how I handle this Live data but I can't find a way out. Any suggestion would be helpful.
I have also tried this by doing it an interval of 2 sec but an OutOfMemeoryBoundsException throws
if((System.currentTimeMillis()-sTime)/1000>2){
new ProgressRunner().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,x);
}
One of the solution to address this problem is keeping a threshold for the change in the sensor values. If the change in deltaX, deltaY, deltaZ are greater then you can start the AsyncTask else dont.
Since u are not keeping any threshold values the number of threads u create is very huge in number.
EDIT 1:
Here is a link to a small tutorial that will help you to kick start... in this link he has used a time interval and a threshold for shaking the device... i bet this is a perfect solution for your requirement
Tutorial Link
Do you need to process every single value or are you fine processing every x (e.g. 0.1) seconds? I call a method that checks "now - lastProcessedTime". If that value is > 100ms, I will handle the data and update lastProcessedTime = now. If not, I will throw away the sensor value.

Track an user with location based App

I'm working on a Location based App. Here my requirement is I want to track a user location from my device like uber or Ly ft App.
Example: If a pizza guy(User B) wants to deliver pizza to me(User A) then he can share his user id, so using that id, I can enter in my device and see his exact precise location. But I want to track him until I required so how to achieve this in code. Help me with the architecture if you have come across such scenario.
I can also achieve the above scenario, but my doubt is how can I show in map without refreshing each time when the user moves say for example two minutes once I want to check the Latitude and Longitude and update it in my map for the same user
Create a Thread, that asks a Handler to get the position a few times. You need to use a Handler, because the getMyLocation method can only be called from GUI Thread:
private class MyLocationThread extends Thread{
#Override
public void run() {
int loops = 0;
// we give the location search a minute
while(loops < 60){
// we have to try it over a handler, because getMyLocation() has to be called from GUI Thread -_-
_getMyLocationHandler.sendEmptyMessage(0);
if(isInterrupted()){
return;
}
// take a short nap before next try
try {Thread.sleep(1000);} catch(Exception e){}
loops++;
}
}
}
Here's what the Handler does:
private Handler _getMyLocationHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(getMap().isMyLocationEnabled() && getMap().getMyLocation() != null){
_locationWatcher.interrupt();
drawCurrentImagePositions();
}
}
};

How to find if a function hasn't been called?

I am working on an Android application and I just want to know when a function hasn't been called. For example, lets say you have the function
void foo()
{
...//do something here;
}
What I want to do is time if the function hasn't been called for lets say, 10 seconds, and then record the time after that 10 seconds. After that, if the function is invoked and it is called, I want to record the time when it function begins again. I was thinking of using the Timer function but I wasn't exactly sure on how to test whether or not a function has been invoked.
I am working on an application in which you see whether or not a person starts or stops walking. For example, if someone has stopped walking for 10 seconds, I want to record that time. When they resume walking, I also want to record that time. Hope this makes better sense. Any help would be appreciated! Thanks!
One possible solution is to add a boolean flag to your code; maybe call it fooWasCalled. Initialize this variable to false and set it to true inside foo(). Then you can simply check the flag when you need to know whether or not the function was called.
This is a very common idiom to check whether some action has occurred.
p.s. Since you are using a Timer, you probably need to synchronize access to this boolean flag or use some other thread-safe mechanism.
This is probably what you want (not completer code, just idea)
protected boolean mIsCountDownOn;
private class CountDownTimer mCountDownTimer = new CountDownTimer(10000, 10000)
{
#Override
public void onTick(long millisUntilFinished)
{
}
#Override
public void onFinish()
{
mIsCountDownOn = false;
}
};
In foo
foo
{
if (mIsCountDownOn)
{
// less than 10 seconds since the last time foo is called
mCountDownTimer.cancel();
}
else
{
// more than 10 seconds since last call
mIsCountDownOn = true; // will start the timer at the end of foo body
// Code to save mTime to wherever you want to save it.
}
// Whatever else foo supposes to do
mTime = // get the time now
mCountDownTimer.start();
}

How do i prevent my program from queing button presses

Hi everyone This is my first post so please be gentle. Even though my android final is complete and all i still find it hard to not continue to adjust my program and add to it just for the fun of it. what it is is a simple program that when you touch the screen the character on the screen laughs one of two ways with matching vibration. It works nicely but when my teacher (who was in a foul mood at the time) went to test it he pretty much button mashed the thing which made it que up every button press and we had to sit through like 15 laughter fits before we could do anything more with the phone. What i want to do is just have one touch event count until the first event is complete. what it is is a simple on touch event with a couple nested if statements.
public boolean onTouch(final View v, MotionEvent m)
{
v.setBackgroundResource(R.drawable.laughing);//changes the image to the laughing monkey
if (m.getAction() == MotionEvent.ACTION_DOWN)
{
if (timesTouched != I) //checks to see if the touch amount is not equal to the random number
{
if(laughter != 0)
{
sp.play(laughter, 1, 1, 1, 0, 1);//plays the loaded sound when the screen is pressed
//vib.vibrate(900);
}
Time = 900;
timesTouched++;
intDelay = 1;
if(vibon == 1)
{
vib.vibrate(Time);
}
}
else if (timesTouched == I)//checks to see if the touch amount is the same as the random number
{
if(laughter != 0)
{
sp.play(laughFit, 1, 1, 1, 0, 1);//plays the loaded sound when the screen is pressed
}
Time = 6000;
timesTouched = 0;
intDelay = 1;
if(vibon == 1)
{
vib.vibrate(laugh, -1);
}
}
}
else if((m.getAction() == MotionEvent.ACTION_UP) && (intDelay == 1))
{
try {
Thread.sleep(Time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
v.setBackgroundResource(R.drawable.normal) ;//returns the image to the normal looking monkey
intDelay = 0;
}
return true;
}
}
the sleep timer is there to prevent the background image from going back to the default before the laughter is over. I did attempt to get my teacher to help but he is just a speedy replacement and had never even touched an android device before starting to teach at the beginning of this year. please any help you can provide is greatly appreciated because so far i have had to pretty much teach myself this stuff with the help of Google searches.
Thanks a Bunch!
If this were me I would probably move the sound playing to a separate thread then use messages to notify that thread when to start and stop the sounds. In this way the button can send the message immediately and not be blocked by any subsequent actions. The side-effect should be that every button press stops the previous laughter and starts a new one (or just queues up another sound byte over the previous one effectively combining sounds). You could contrarily disable the button until the sound is finished but I do not believe that would be a good user experience - they would expect to be able to mash and mash to their hearts content!
Check out http://developer.android.com/resources/articles/painless-threading.html for more guidance on how to approach such a thing.

Categories

Resources