Speed of devices in Android
<p>I am calculating the speed using the Distance / Time however when onlocation changed it goes up to infinity and decrease gradually. </p>

<pre><code>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&lt;LatLon&gt; myList = new ArrayList&lt;LatLon&gt;(); 

//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() &gt; 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() &amp;&amp; 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() &gt; 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&lt;Camera.Size&gt; 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();

}
</code></pre>

<p>} </p>
