使用GPS获取的总行程距离不会更新我的位置

时间:2013-08-16 07:49:45

标签: android google-maps gps

您好我正在学习Android中的GPS开发。现在我通过vogellas blog here了解了基础知识。现在我已经获得了纬度和经度并将其显示在我的设备上,但我不知道为什么它不会更新我的位置,即使我已经设置了一个可运行的线程来每3秒获取一次位置。同样的原因,我无法检查我是否得到了正确的公式来获得我旅行的总距离。

这是我第一次使用这个,所以也许有人可以给我一个提示或想法如何。

我在github中创建了一个存储库,也许有人可以帮我解决这个问题。请参阅文件here:)

编辑: 好的主要问题是onChangeLocation()似乎不适合我。我尝试的是创建一个runnable来每隔3秒显示一次该位置,但它不会返回我预期的结果。

我错过了什么吗?

到目前为止,这是我的代码,以便于查看:

Main.java

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.provider.Settings;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/*created by Kahel 08/16/2013
* to read more about the location manager go here: http://www.vogella.com/articles/AndroidLocationAPI/article.html
*
* */

public class Main extends Activity implements LocationListener {

    private TextView latitude, longitude, distance;
    private Button getLocation;
    private LocationManager locationManager;
    private String provider;

    double distance_travelled;
    double latitude_prev;
    double longitude_prev;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        latitude = (TextView)findViewById(R.id.txt_latitude);
        longitude = (TextView)findViewById(R.id.txt_longitude);
        distance = (TextView) findViewById(R.id.txt_distance);
        getLocation = (Button)findViewById(R.id.btn_getLocation);

        checkGps();

        getCurrentLocation();

        getLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                locatorRunner();
            }
        });

    }

    private void locatorRunner(){
        Thread thread = new Thread()
        {
            @Override
            public void run() {
                try {
                    while(true) {
                        sleep(3000);

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                 /*needs UI Thread*/
                                getCurrentLocation();
                            }
                        });
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        thread.start();
    }

    private void getCurrentLocation(){
        // Get the location manager
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        // Define the criteria how to select the locatioin provider -> use
        // default
        Criteria criteria = new Criteria();
        provider = locationManager.getBestProvider(criteria, false);
        Location location = locationManager.getLastKnownLocation(provider);

        Toast.makeText(Main.this,String.valueOf(location),Toast.LENGTH_SHORT).show();


        //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000L,500.0f, (LocationListener) location);


        // Initialize the location fields
        if (location != null) {
            System.out.println("Provider " + provider + " has been selected.");
            onLocationChanged(location);
        } else {
            latitude.setText("Location not available");
            longitude.setText("Location not available");
            distance.setText("0");
        }
    }

    private void checkGps(){
        LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
        boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);

        Toast.makeText(Main.this,String.valueOf(enabled),Toast.LENGTH_SHORT).show();

        // Check if enabled and if not send user to the GSP settings
        // Better solution would be to display a dialog and suggesting to
        // go to the settings
        if (!enabled) {
            showGpsSettingDialog();
        }
    }

    private void showGpsSettingDialog(){
        /*Create a dialog to tell user to enable his GPS settings to pinpoint his or her location*/
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(Main.this);
        alertDialog.setTitle("Settings para sa lokasyon"); /*should be on a string values*/

        alertDialog
                .setMessage("Kasalukuyang hindi aktibo ang iyong GPS para makuha ang iyong lokasyon. Nais mo bang i-set ito ngayon?")
                .setCancelable(false)
                .setPositiveButton("Oo", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivity(intent);
                    }
                })
                .setNegativeButton("Hindi", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.cancel();
                    }
                });

        AlertDialog gpsSettingsDialog = alertDialog.create();
        gpsSettingsDialog.show();

    }

    /* Request updates at startup */
    @Override
    protected void onResume() {
        super.onResume();
        locationManager.requestLocationUpdates(provider, 400, 1, this);
    }

    /* Remove the locationlistener updates when Activity is paused */
    @Override
    protected void onPause() {
        super.onPause();
        locationManager.removeUpdates(this);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onLocationChanged(Location location) {
        getLocation(location);
    }

    private void getLocation(Location location){

        int R = 6371;

        double lat = location.getLatitude();
        double lon = location.getLongitude();

        latitude_prev = lat;
        longitude_prev = lon;

        Double dlat = latitude_prev - lat;
        Double dlon = longitude_prev - lon;

        double a = Math.sin(dlat / 2) * Math.sin(dlat / 2) + Math.cos(latitude_prev) *
                Math.cos(lat) * Math.sin(dlon / 2) * Math.sin(dlon / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        distance_travelled =  R * c;

        latitude.setText(String.valueOf(lat));
        longitude.setText(String.valueOf(lon));
        distance.setText(String.valueOf(distance_travelled));
    }

    /*private double toRad(double d) {
        return d * Math.PI / 180;
    }*/

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {
        Toast.makeText(this, "Enabled new provider " + provider,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProviderDisabled(String s) {
        Toast.makeText(this, "Disabled provider " + provider,Toast.LENGTH_SHORT).show();
    }
}

main.xml中

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >

    <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dip"
            android:orientation="horizontal" >

        <TextView
                android:id="@+id/TextView01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dip"
                android:layout_marginRight="5dip"
                android:text="Latitude: "
                android:textSize="20dip" >
        </TextView>

        <TextView
                android:id="@+id/txt_latitude"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="unknown"
                android:textSize="20dip" >
        </TextView>
    </LinearLayout>

    <LinearLayout
            android:id="@+id/linearLayout2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

        <TextView
                android:id="@+id/TextView03"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dip"
                android:layout_marginRight="5dip"
                android:text="Longitute: "
                android:textSize="20dip" >
        </TextView>

        <TextView
                android:id="@+id/txt_longitude"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="unknown"
                android:textSize="20dip" >
        </TextView>

    </LinearLayout>

    <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="Distance Travelled:"
                android:id="@+id/textView"
                android:layout_gravity="left|center_vertical"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="5dp"/>

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="unknown"
                android:id="@+id/txt_distance"/>
    </LinearLayout>

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Get Location"
            android:id="@+id/btn_getLocation"
            android:layout_gravity="center"/>

</LinearLayout>

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.geolocation"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION " />
    <uses-permission android:name="android.permission.INTERNET" />

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="10" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.geolocation.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

注意:

我添加了按钮开始跟踪,因为我不确定onLocationChanged是否正常工作。哈哈哈!

3 个答案:

答案 0 :(得分:1)

距离的基本方法:

public class test extends Activity implements LocationListener{
   private LocationManager lm;
   private Location last;
   private long distance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        lm = (LocationManager) getSystemService(LOCATION_SERVICE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,1,this);

    }

    @Override
    protected void onPause() {
        super.onPause();
        lm.removeUpdates(this);
    }

    @Override
    public void onLocationChanged(Location location) {
        if(last != null){
            distance += location.distanceTo(last);
        }

        last = new Location(location);
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {
    }

    @Override
    public void onProviderEnabled(String s) {
    }

    @Override
    public void onProviderDisabled(String s) {
    }
}

答案 1 :(得分:0)

您必须实施LocationListener才能获得如下所示的当前GPS位置: 设置用户权限firlst      

现在获得这样的GPS位置:

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

LocationListener locationListener = new MyLocationListener();  
locationManager.requestLocationUpdates(  
LocationManager.GPS_PROVIDER, 0, 0, locationListener);

/*----------Listener class to get coordinates ------------- */
private class MyLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location loc) {
        //Get your location here
    }

    @Override
    public void onProviderDisabled(String provider) {}

    @Override
    public void onProviderEnabled(String provider) {}

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

答案 2 :(得分:0)

您可以每隔3秒拨打getCurrentLocation(),但这不会触发getLocation(location);

仅当位置更新时才会调用

getLocation(位置);

@Override
public void onLocationChanged(Location location) {
    getLocation(location);
}