2

I am calculating the speed using the Distance / Time however when onlocation changed it goes up to infinity and decrease gradually.

package water.Spill;


import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.util.FloatMath;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import water.Spill.LatLon;
import android.hardware.Camera;


public class GPS2 extends Activity implements SurfaceHolder.Callback {

LocationManager locationManager;
LocationListener locationListener;


//text views to display latitude and longitude
TextView latituteField;
TextView longitudeField;
TextView currentSpeedField;
TextView kmphSpeedField;
TextView avgSpeedField;
TextView avgKmphField;
TextView gpsOnOff;


//objects to store positional information
protected double lat;
protected double lon;
ArrayList<LatLon> myList = new ArrayList<LatLon>(); 

//objects to store values for current and average speed
protected double currentSpeed;
protected double kmphSpeed;
protected double avgSpeed;
protected double avgKmph;
protected double totalSpeed;
protected double totalKmph;

//Camera
private SurfaceView mSurfaceView ;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private boolean mPreviewRunning;



boolean gps_enabled = false;
boolean network_enabled = false;

//counter that is incremented every time a new position is received, used to calculate average speed
int counter = 0;
double totalDistance=0;

//timer
TextView text3;
TextView secondLabel;
TextView minutesLabel;
TextView hourLabel;
long starttime = 0;
long spdstarttime = 0;

Handler h2 = new Handler();
Runnable run = new Runnable() {


    public void run() {
        long spdmillis = System.currentTimeMillis() - spdstarttime;
        long millis = System.currentTimeMillis() - starttime;
        int spdseconds = (int) (spdmillis / 1000);
        int spdhours = spdseconds/60/60;
        int seconds = (int) (millis / 1000);
        int minutes = seconds / 60;
        int hours = minutes/60;
        seconds  = seconds % 60;
        minutes = minutes % 60;


        currentSpeedField = (TextView) findViewById(R.id.speed);
        secondLabel = (TextView) findViewById(R.id.seconds);
        minutesLabel = (TextView) findViewById(R.id.minutes);
        hourLabel = (TextView) findViewById(R.id.hour);

        secondLabel.setText(String.valueOf(seconds) + "s");
        minutesLabel.setText(String.valueOf(minutes)+ "m");
        hourLabel.setText(String.valueOf(hours)+ "h");
        if(myList.size() > 1){

            LatLon ll1 = myList.get(myList.size()-2);
            LatLon ll2 = myList.get(myList.size()-1);
            double distance = 0;
            distance = distFrom(ll1.getLat(), ll1.getLon(), ll2.getLat(), ll2.getLon());
            if(ll1.getLat()== ll2.getLat() && ll1.getLon() == ll2.getLon()){
                currentSpeed = 0;
            }
            else{
                distance = round(distance,3,BigDecimal.ROUND_HALF_UP);
                currentSpeed = (distance*1000)/spdseconds;


                double test12 = spdseconds;
                System.out.println("distance " + (distance*1000));
                System.out.println("time " + test12); 


                //currentSpeed = round(currentSpeed,3,BigDecimal.ROUND_HALF_UP);
            }
            currentSpeedField.setText(String.valueOf(currentSpeed) + "km/h");
        }
        h2.postDelayed(this, 500);
    }
};

Timer timer = new Timer();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.gps2);

    mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
    mSurfaceHolder = mSurfaceView.getHolder();
    mSurfaceHolder.addCallback(this);
    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


    text3 = (TextView)findViewById(R.id.text3);

    Button b = (Button)findViewById(R.id.button);
    b.setText("stop");

    timer = new Timer();

    b.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            Button b = (Button)v;
            b.setText("stop");
            if(b.getText().equals("stop")){
                timer.cancel();
                timer.purge();
                h2.removeCallbacks(run);
                stop();
                Button bStop = (Button)findViewById(R.id.button4);
                bStop.setEnabled(true);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                b.setEnabled(false);

            }

        }   

    });
    run();

    Button b2 = (Button)findViewById(R.id.button4);

    b2.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            getLocation();
            h2.postDelayed(run, 0);
            starttime = System.currentTimeMillis();
            Button bStart = (Button)findViewById(R.id.button4);
            bStart.setEnabled(false);
             Button b = (Button)findViewById(R.id.button);
            b.setEnabled(true);
        }
    });
}

private void getLocation() {

    {   

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        locationListener = new MyLocationListener();

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0,locationListener);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,3000,0,locationListener);    
    }


}


public void stop(){
    locationManager.removeUpdates(locationListener);

}
@Override
public void onResume() {

    super.onResume();
}

@Override
public void onPause() {
    locationManager.removeUpdates(locationListener);
    super.onPause();
}

private void run(){

    final Criteria criteria = new Criteria();


    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setSpeedRequired(true);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    //Acquire a reference to the system Location Manager

    locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

    try{network_enabled=locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){} 
    try{gps_enabled=locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}        

    // Define a listener that responds to location updates
    locationListener = new MyLocationListener();
    String Results="Unavailable";
    Button bStart = (Button)findViewById(R.id.button4);
    bStart.setEnabled(false);
    TextView gpsOnOff = (TextView) findViewById(R.id.gpsOnOff);
    if(network_enabled)
        {
        Results="Available";
        Button bStartGot = (Button)findViewById(R.id.button4);
        bStartGot.setEnabled(true);
        }
    else if(gps_enabled)  
        {
        Results="Available";
        Button bStartGot = (Button)findViewById(R.id.button4);
        bStartGot.setEnabled(true);
        gpsOnOff.setText(Results);
        }
}

//Method to round the doubles to a max of 3 decimal places
public static double round(double unrounded, int precision, int roundingMode)
{
    BigDecimal bd = new BigDecimal(unrounded);
    BigDecimal rounded = bd.setScale(precision, roundingMode);
    return rounded.doubleValue();
}




    public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
    double earthRadius = 6371;
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2  -lng1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
               Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
               Math.sin(dLng/2) * Math.sin(dLng/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double dist = earthRadius * c;

    return dist;
}



public class MyLocationListener implements LocationListener 
{ 

    public void onLocationChanged(Location newLocation) 
    { 
        //current speed fo the gps device
        spdstarttime = System.currentTimeMillis();
        //kmphSpeed = round((currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP);

        //all speeds added together
        totalSpeed = totalSpeed + currentSpeed;
        totalKmph = totalKmph + kmphSpeed;

        //calculates average speedss
        //avgSpeed = round(totalSpeed/counter,3,BigDecimal.ROUND_HALF_UP);
        //avgKmph = round(totalKmph/counter,3,BigDecimal.ROUND_HALF_UP);

        //gets position
        lat = round(((double) (newLocation.getLatitude())),9,BigDecimal.ROUND_HALF_UP);
        lon = round(((double) (newLocation.getLongitude())),9,BigDecimal.ROUND_HALF_UP);

        latituteField = (TextView) findViewById(R.id.lat);
        longitudeField = (TextView) findViewById(R.id.lon);     

        TextView distanceField = (TextView) findViewById(R.id.distance);


        LatLon ll = new LatLon(lat, lon);
        myList.add(ll);

            if(myList.size() > 1){
            LatLon ll2 = myList.get(myList.size()-2);
            double dist = distFrom( ll2.getLat(), ll2.getLon(), ll.getLat(), ll.getLon());


            dist = round(dist,3,BigDecimal.ROUND_HALF_UP);
            totalDistance += dist;
            totalDistance = round(totalDistance,3,BigDecimal.ROUND_HALF_UP);
            distanceField.setText("Distance:            " + String.valueOf(totalDistance)+ "km");

            Context context = getApplicationContext();


            CharSequence text = "Location Changed , Distance Accumulated";
            int duration = Toast.LENGTH_SHORT;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
            }
            latituteField.setText(String.valueOf(lat));
            longitudeField.setText(String.valueOf(lon));


    } 

    public void onProviderDisabled(String provider) 
    { 


    } 

    public void onProviderEnabled(String provider) 
    { 
    } 

    public void onStatusChanged(String provider, int status, Bundle extras) {


            if(status==LocationProvider.OUT_OF_SERVICE)
            {
                gpsOnOff.setText("OFF");
            }
            else
            {
                if(status==LocationProvider.TEMPORARILY_UNAVAILABLE)
                {
                    gpsOnOff.setText("OFF");
                }
                else
                {
                    if(status==LocationProvider.AVAILABLE)
                    {
                        gpsOnOff.setText("ON");
                    }
                }
            }
        }




} 


Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] imageData, Camera c) {

        /*if (imageData != null) {

        Intent mIntent = new Intent();

            StoreByteImage(mContext, imageData, 50,
                    "ImageName");
            mCamera.startPreview();

            setResult(FOTO_MODE, mIntent);
            finish();

        }*/
    }
};


public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // TODO Auto-generated method stub
    if (mPreviewRunning) {

        mCamera.stopPreview();

        }

        Camera.Parameters p = mCamera.getParameters();



        List<Camera.Size> list = p.getSupportedPreviewSizes ();
        Camera.Size size = list.get(0);

        p.setPreviewSize(size.width, size.height);
        mCamera.setParameters(p);
        //p.setPreviewSize(w, h);
        //p.setPreviewSize(300, 200);


        try {

        mCamera.setPreviewDisplay(holder);

        } catch (IOException e) {

        e.printStackTrace();

        }

        mCamera.startPreview();

        mPreviewRunning = true;

}

public void surfaceCreated(SurfaceHolder arg0) {
    // TODO Auto-generated method stub
    mCamera = Camera.open();
}


public void surfaceDestroyed(SurfaceHolder arg0) {
    // TODO Auto-generated method stub
    mCamera.stopPreview(); 
    mPreviewRunning = false;
    mCamera.release();

}

}

Tinyfool
  • 1,460
  • 2
  • 18
  • 40
  • What is your actual qustion? As it's worded at the moment it is very ambiguous. Please reword it as an actual question and provide any code examples that can help describe your specific needs. – Justin Shield Jul 20 '11 at 02:44
  • How are you calculating Distance? How are you calculating Time? – Ted Hopp Jul 20 '11 at 02:45
  • To what purpose, the speed and time between the location updates wont be linear if they are far apart, you also have accuracy to worry about etc. Also why not just use the locations getSpeed() method if you want current speed? – Idistic Jul 20 '11 at 03:31

1 Answers1

1

Sometimes the time between two locations is less than one second. Hence dist/time => infinity. (Are you using a float variable for speed calculations?)

Anyway you don't need to do that to calculate speed.

Use:

Location.getSpeed(); 

Problem solved.

Note: You have to be moving to see a non-zero speed. Also accuracy of this value depends on the GPS chipset used in your phone. Some devices use other sensors to calculate this speed.

Reno
  • 33,594
  • 11
  • 89
  • 102
  • You do know that the timestamp for location in android is stored in milliseconds right? – Nicklas A. Jul 20 '11 at 04:31
  • Yep in UTC, [Even if there is a small time diff between two locations](http://www.java2s.com/Open-Source/Android/android-core/platform-frameworks-base/com/android/server/LocationManagerService.java.htm) using OP's method will give a [spike in speed](http://www.google.co.uk/#sclient=psy&hl=en&source=hp&q=(1+meters+%2F+10+milliseconds)+to+km%2Fh&aq=f&aqi=&aql=&oq=&pbx=1&bav=on.2,or.r_gc.r_pw.&fp=78207bf8c2b7603b&biw=963&bih=671). – Reno Jul 20 '11 at 04:53
  • i thought "Location.getSpeed();" u need to set the speed yourself first? ( i tried before it gives me speed 0) – WcgEddie Lim Jul 20 '11 at 06:23
  • 1
    No, the framework sets the speed. You should not modify the values received in the onLocationChanged() callback. Try checking the speed values in a moving vehicle. They should be > 0 – Reno Jul 20 '11 at 06:30
  • can anyone give me some example on how to use the location.getSpeed(); ? i am beginner i really need help – WcgEddie Lim Jul 20 '11 at 06:38
  • http://stackoverflow.com/questions/4811920/why-getspeed-always-return-0-on-android – WcgEddie Lim Jul 20 '11 at 06:42
  • As per my note. This is a problem only in some devices. If you are in a moving vehicle you will get non-zero values of speed. – Reno Jul 20 '11 at 06:50
  • i know another way to do it which is to pull down the nmea strings from the satellite and decode it i think the nmea includes speed bearing and etc . But i have no idea how to do it. anyone knows? – WcgEddie Lim Jul 20 '11 at 07:05
  • why would data from a satellite in the Earth's orbit include your speed and bearing? – Axarydax Nov 11 '11 at 06:26