Measure distance walked with GeoPoint and displaying distance to user

廉价感情. 提交于 2019-12-13 01:28:49

问题


In my app I am trying to make it possible to calculate the distance a person walks. To do this I have created a LocationHelper class that should get me the current GeoPoint every 30 seconds or 10 meters. I already have a method that returns the distance in meters between two GeoPoints that I know works, because I have used it in a previous project. I also have an Activity called WalkActivity where I call the method getDistance() in LocationHelper and display it in a TextView that is updated every 30 seconds with help of a timer. See code below.

When I run my app nothing is displayed. It says "You have walked 0.0 meters" no matter how far I walk. I get no error messages. What do you think I am doing wrong? I have searched and looked at numerous examples but found none that can tell me what is wrong here.

I hope this is not a stupid question, any help is welcome :)

package Controller;

import com.google.android.maps.GeoPoint;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

/**
 * Location Helper Class that handles creation of the Location Manager and Location Listener.
 * 
 */
public class LocationHelper{

    private double distance = 0;
    GeoPoint geoPointA;
    GeoPoint geoPointB;

    //location manager and listener
    private LocationManager locationManager;
    private MyLocationListener locationListener;

    /**
     * Constructor for LocationHelper
     * 
     * @param context - The context of the calling activity.
     */
    public LocationHelper(Context context){

        //setup the location manager
        locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);

        //create the location listener
        locationListener = new MyLocationListener();

        //setup a callback for when the GPS gets a lock and we receive data
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 10, locationListener);

    }

    /**
     * Receiving notifications from the Location Manager when they are sent.
     *
     */
    public class MyLocationListener implements LocationListener {


        /**
         * called when the location service reports a change in location
         */
        public void onLocationChanged(Location location) {

            if (geoPointB == null){
                geoPointB = new GeoPoint((int) location.getLatitude(), (int) location.getLongitude());
            }

            //Getting the current GeoPoint.
            geoPointA = new GeoPoint((int) location.getLatitude(), (int) location.getLongitude());

            //Calculating the distance in meters
            distance = distance + nu.placebo.whatsup.util.Geodetics.distance(geoPointA, geoPointB);

            //Making current GeoPoint the previous GeoPoint
            geoPointB = geoPointA;

        }

        //called when the provider is disabled
        public void onProviderDisabled(String provider) {}
        //called when the provider is enabled
        public void onProviderEnabled(String provider) {}
        //called when the provider changes state
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    }

    /**
     * Stop updates from the Location Service.
     */
    public void killLocationServices(){
        locationManager.removeUpdates(locationListener);
    }

    /**
     * Get Distance 
     *
     * @return - The current distance walked.
     */
    public double getDistance(){
        return distance;
    }

    /**
     * Check if a location has been found yet.
     * @return - True if a location has been acquired. False otherwise.
     */
    public Boolean gpsEnabled(){
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }   
}

package edu.chl.dat255.sofiase.readyforapet;

import java.util.Timer;
import java.util.TimerTask;
import Controller.LocationHelper;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class WalkActivity extends Activity{

    private TextView displayDistance;
    private int delay = 0;
    private int period = 30000;
    private Timer timer;
    Handler handler = new Handler();

    private LocationHelper location;

    /**
     * On Create method
     * 
     * @param savedInstanceState - bundle
     */
    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView(R.layout.walkactivity);
        location = new LocationHelper(this);

        //Checking if the GPS is enabled, else let the user start GPS if wanted.
        if (location.gpsEnabled()){
            Toast.makeText(this, "GPS is Enabled on your devide", Toast.LENGTH_SHORT).show();
        }
        else{
            showGPSDisabledAlert();
        }

        Button startWalking = (Button) findViewById(R.id.startwalking);
        startWalking.setOnClickListener(new OnClickListener() {

            /**
             * Method onClick for the start walking button
             * 
             * @param v - View
             */
            public void onClick (View v){

                try{
                    timer = new Timer();
                    timer.schedule(myTimerTask, delay, period);
                } 
                catch (Exception e){
                    e.printStackTrace();
                }
            }
        }

                );

        Button stopWalking = (Button) findViewById(R.id.stopwalking);
        stopWalking.setOnClickListener(new OnClickListener() {

            /**
             * Method onClick for the stop walking button
             * 
             * @param v - View
             */
            public void onClick (View v){
                timer.cancel();
                location.killLocationServices();
                startActivity(new Intent(WalkActivity.this, PetActivity.class));
            }
        }
                );

    }


    TimerTask myTimerTask = new TimerTask() {

        @Override
        public void run() {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    displayDistance = (TextView) findViewById(R.id.distance);
                    displayDistance.setText("You have walked " + location.getDistance() + " meters so far.");
                }
            });

        }

    };

    /**
     * If GPS is turned off, lets the user either choose to enable GPS or cancel.
     * 
     */
    private void showGPSDisabledAlert(){
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
        alertDialogBuilder.setMessage("GPS is disabled on your device. Would you like to enable it?")
        .setCancelable(false)
        .setPositiveButton("Go to Settings Page To Enable GPS",
                new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog, int id){
                Intent callGPSSettingIntent = new Intent(
                        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(callGPSSettingIntent);
            }
        });
        alertDialogBuilder.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog, int id){
                dialog.cancel();
            }
        });
        AlertDialog alert = alertDialogBuilder.create();
        alert.show();
    }

}

回答1:


One problem in your code is when you create a GeoPoint from a Location in onLocationChanged(Location location). Both getLatitude() and getLongitude() from the class Location return degrees, but the constructor for GeoPoint takes microdegrees. This might be screwing up your distance calculation because your GeoPoint coordinates could be, let's just say, 42 degrees, which turns out to be .0000042 degrees in the GeoPoint.

Also, you might try printing the current location somehow, through the debug monitor or through a Toast message. This will greatly help in the debugging process, as you can see your Lat/Long changing and debug from there.

Note: I would recommend updating to Maps v2, they changed a lot of classes and added LatLng which makes things easier to understand :)



来源:https://stackoverflow.com/questions/16650929/measure-distance-walked-with-geopoint-and-displaying-distance-to-user

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!