使用GPS计算累计距离(不能调用运行方法)

时间:2014-01-21 08:36:20

标签: android eclipse gps

我还在研究我在这里提出问题的项目。它是计算一个人在一段时间后旅行或跑步的累积距离。

我不知道我是应该开始一个新问题,还是继续我先问过的第一个问题,因为从那时起我的进步很多,而且我的代码有很多不同的错误。我试图在eclipse中使用调试器,但它不起作用,我不明白。

距离累积部分让我烦恼,我使用Runnable run方法。但我的应用程序在崩溃时没有到达Run方法。 当我按开始移动时,它显示“第二个值成功”和“线程开始”,这只是为了告诉我它到达那一点。但它没有显示“运行正在运行”,因此它永远不会达到运行方法。

当我测试代码时,我使用模拟器输入位置数据。它是实时的吗?我一直认为在笔记本电脑中开发代码时不可能实时使用。如果有,有人可以告诉我吗?从研究中,我见过的所有人都使用模拟器。我是一个新用户,所以不明白如何使用调试器,我试过但它没有显示任何东西。

当我按下距离时,返回0,当我再次按下时,应用程序说unfortunately app has stopped。也许是因为它没有达到Run?当我的帖子是t1=new Thread(new MainActivity());时,当我按开始移动时它崩溃了。现在它是t1 = new Thread()但是距离是0并且崩溃了。两种情况都没有达到Run方法。

所有距离都变为0,所以我认为这是因为我的lat2值在Run方法中首次计算时为null,然后变为lat 1值。所以我在开始移动时首先为它赋值。 /> 另外,当我第一次按下开始时,如何停止计时器并使dist 0?即使我按下停止,时间也不会停止。基本上,我的问题是,当停止时启动线程时,如何使Run方法运行,停止计时器和线程。

有一段时间,距离没有崩溃,但没有累积(不是显示的代码)我测试停止计时器,但时间仍然继续。 Thread.Stop似乎很危险,因为很多地方都暗示。我只是让dis = 0?我使用bool来阻止累积距离或重新开始。所以我需要停止线程吗?

编辑:这是更新的代码。

公共类MainActivity扩展Activity实现Runnable {

 private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in Meters
    private static final long MINIMUM_TIME_BETWEEN_UPDATES = 30000;

    protected LocationManager locationManager;
    static double n=0;
    Long s1,r1;
    double lat1,lon1,lat3,lon3,lat2,lon2;
    double dis=0.0;
    MyCount counter;
    Thread t1;
    EditText e1;
    boolean bool=true;
    int count=0;

Button btnCurrentPosition,btnStartMove,btnPause,btnResume,btnStop,btnGetDistance;
/** Called when the activity is first created. */

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);     
    btnCurrentPosition=(Button)findViewById(R.id.CurrentPosition);//current position
    btnStartMove=(Button)findViewById(R.id.StartMove);//start moving.. calculates distance on clicking this
    btnPause=(Button)findViewById(R.id.Pause);//pause
    btnResume=(Button)findViewById(R.id.Resume);//resume
    btnStop=(Button)findViewById(R.id.Stopping);
    btnGetDistance=(Button)findViewById(R.id.GetDistance);//get distance
    e1=(EditText)findViewById(R.id.Text1);
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER, 
            MINIMUM_TIME_BETWEEN_UPDATES, 
            MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
            new MyLocationListener()
    );
    btnCurrentPosition.setOnClickListener(new OnClickListener() 
    {
        @Override
        public void onClick(View v) {
            showCurrentLocation();
        }
    });  
    btnStartMove.setOnClickListener(new OnClickListener() 
    {
        @Override
        public void onClick(View v) {
            start(v);
        }
    });
    btnPause.setOnClickListener(new OnClickListener() 
    {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            start(v); 
        }
    });
    btnResume.setOnClickListener(new OnClickListener() 
    {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            start(v); 
        }
    });
    btnStop.setOnClickListener(new OnClickListener() 
    {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            start(v); 
        }
    });
    btnGetDistance.setOnClickListener(new OnClickListener() 
    {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            start(v);
        }
    });

}

protected void showCurrentLocation() 
{
    Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

    if (location != null) {
        String message = String.format(
                "Current Location \n Longitude: %1$s \n Latitude: %2$s",
                location.getLongitude(), location.getLatitude()
        );
        lat1=location.getLatitude();
        lon1=location.getLongitude();
        Toast.makeText(MainActivity.this, message,
                Toast.LENGTH_LONG).show();
        Toast.makeText(MainActivity.this,"distance in metres:"+String.valueOf(dis),Toast.LENGTH_LONG).show();
        Toast.makeText(MainActivity.this, "Value of Count:" + String.valueOf(count),
                Toast.LENGTH_LONG).show();
    }
    else{
        Toast.makeText(MainActivity.this, "null location",
                Toast.LENGTH_LONG).show();
    }


}

public void start (View v){

    switch(v.getId()){

    case R.id.StartMove:
        Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        lat2=location.getLatitude();
        lon2=location.getLongitude();
        bool=true;
        t1=new Thread(this);
        t1.start();
        //  Thread t = new Thread(new MainActivity()); t.start()
        //new MainActivity()
        counter= new MyCount(30000,1000);
     counter.start();
     break;
    case R.id.Pause:
        counter.cancel();
        bool=false;
        break;
    case R.id.Resume:
        counter= new MyCount(s1,1000);
     counter.start();
     bool=true;
     break;
    case R.id.GetDistance:

        Toast.makeText(MainActivity.this, "reach get distance",
                Toast.LENGTH_LONG).show();
        //run();
        double time=n*30+r1;

        Toast.makeText(MainActivity.this,"distance in metres:"+String.valueOf(dis)+"Velocity in m/sec :"+String.valueOf(dis/time)+"Time :"+String.valueOf(time),Toast.LENGTH_LONG).show();

    case R.id.Stopping:
        counter.cancel();
        counter = null;
        bool = false;

        //r1 = (long) 0;

    }
}

private class MyLocationListener implements LocationListener {

    public void onLocationChanged(Location location) {
        String message = String.format(
                "New Location \n Longitude: %1$s \n Latitude: %2$s",
                location.getLongitude(), location.getLatitude()
        );
        Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
    }

    public void onStatusChanged(String s, int i, Bundle b) {
        Toast.makeText(MainActivity.this, "Provider status changed",
                Toast.LENGTH_LONG).show();
    }

    public void onProviderDisabled(String s) {
        Toast.makeText(MainActivity.this,
                "Provider disabled by the user. GPS turned off",
                Toast.LENGTH_LONG).show();
    }

    public void onProviderEnabled(String s) {
        Toast.makeText(MainActivity.this,
                "Provider enabled by the user. GPS turned on",
                Toast.LENGTH_LONG).show();
    }

}

public class MyCount extends CountDownTimer{
    public MyCount(long millisInFuture, long countDownInterval) {
    super(millisInFuture, countDownInterval);
    }
    @Override
    public void onFinish() {
        counter= new MyCount(30000,1000);
     counter.start();
     n=n+1;
    }
    @Override
    public void onTick(long millisUntilFinished) {
        s1=millisUntilFinished;
        r1=(30000-s1)/1000;
        e1.setText(String.valueOf(r1));


    }
}

@Override
public void run() 
{
    count=6;
    Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    while(bool==true)
    {
        lat1=location.getLatitude();
        lon1=location.getLongitude();

        if(lat1!=lat2 || lon1!=lon2)
        {
            dis+=getDistance(lat2,lon2,lat1,lon1);
            lat2=lat1;
            lon2=lon1;
            count=7;
        }

    }

}

public double getDistance(double lat1, double lon1, double lat2, double lon2) {
    double latA = Math.toRadians(lat1);
    double lonA = Math.toRadians(lon1);
    double latB = Math.toRadians(lat2);
    double lonB = Math.toRadians(lon2);
    double cosAng = (Math.cos(latA) * Math.cos(latB) * Math.cos(lonB-lonA)) +
                    (Math.sin(latA) * Math.sin(latB));
    double ang = Math.acos(cosAng);
    double dist = ang *6371;
    return dist;
}

编辑:上面更新的代码是我使用另一种方法来确定它是否已到达Run()。我试图在getCurrentPosition中显示距离和计数,而不是它的目的,只是为了测试代码。距离出现,只是值保持不变。计数值为7,因此它证明它达到了我的Run方法。然后单击GetDistance,即使更新位置,距离值结果也保持不变,但是当我再次单击它时,它会崩溃。我不知道我的距离按钮的问题。我点击第一次,它显示,进一步的价值是准确的或不准确的。第二次,它甚至没有显示“达到距离”。屏幕挂了1秒然后就崩溃了。我甚至用相同的代码创建另一个项目并运行。结果是当我第一次运行它时,它在显示应用程序之前崩溃了。 我是Android用户和新用户,所以如果我做错了,请告诉我。谢谢。我不确定我的问题是否过于笼统。

这是首次运行时崩溃的项目的LogCat。

01-21 22:13:05.950: D/dalvikvm(911): Not late-enabling CheckJNI (already on)
01-21 22:13:09.240: D/AndroidRuntime(911): Shutting down VM
01-21 22:13:09.250: W/dalvikvm(911): threadid=1: thread exiting with uncaught exception (group=0xb3a2cb90)
01-21 22:13:09.320: E/AndroidRuntime(911): FATAL EXCEPTION: main
01-21 22:13:09.320: E/AndroidRuntime(911): Process: com.example.gpsdistance, PID: 911
01-21 22:13:09.320: E/AndroidRuntime(911): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.gpsdistance/com.example.gpsdistance.MainActivity}: java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2176)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2226)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.app.ActivityThread.access$700(ActivityThread.java:135)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.os.Handler.dispatchMessage(Handler.java:102)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.os.Looper.loop(Looper.java:137)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.app.ActivityThread.main(ActivityThread.java:4998)
01-21 22:13:09.320: E/AndroidRuntime(911):  at java.lang.reflect.Method.invokeNative(Native Method)
01-21 22:13:09.320: E/AndroidRuntime(911):  at java.lang.reflect.Method.invoke(Method.java:515)
01-21 22:13:09.320: E/AndroidRuntime(911):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
01-21 22:13:09.320: E/AndroidRuntime(911):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
01-21 22:13:09.320: E/AndroidRuntime(911):  at dalvik.system.NativeStart.main(Native Method)
01-21 22:13:09.320: E/AndroidRuntime(911): Caused by: java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.os.Parcel.readException(Parcel.java:1461)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.os.Parcel.readException(Parcel.java:1415)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:540)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.location.LocationManager.requestLocationUpdates(LocationManager.java:860)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.location.LocationManager.requestLocationUpdates(LocationManager.java:454)
01-21 22:13:09.320: E/AndroidRuntime(911):  at com.example.gpsdistance.MainActivity.onCreate(MainActivity.java:53)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.app.Activity.performCreate(Activity.java:5243)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-21 22:13:09.320: E/AndroidRuntime(911):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140)
01-21 22:13:09.320: E/AndroidRuntime(911):  ... 11 more

1 个答案:

答案 0 :(得分:0)

添加权限

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

任何问题让我通知或完成+1