定时循环检索gps坐标并最终计算速度

时间:2011-06-03 10:02:21

标签: android performance geolocation gps position

*在底部更新*

基本上,我正在尝试编写一个简单的应用程序来确定我的位置并在每个[固定时间间隔]更新我的位置

我按照this教程设法获得了一个值我的位置。然而,对于我的生活,我无法让它在无限循环中工作。我只是希望它继续下去,直到我退出应用程序(暂时按下后退按钮)。

我想要这样的循环的原因是因为我想计算我的速度。我打算这样做:

loop{

   get Location and store it
   wait One Second
   get Location and store it
   wait One Second
   get Location and store it
   wait One Second
   get Location and store it
   wait One Second
   get Location and store it
   wait One Second

   calculate distance traveled and divide by 5 to get average speed
   print latest location and speed

}

现在,这只是我想要做的非常基本的版本。理想我希望有一个线程处理计时器,另一个获取位置(通过锁定另一个线程获取位置直到“timer%1000毫秒== 0”,确保通过一秒间隔精确地获取该位置或类似的东西),然后有另一个线程来计算当前的速度。

我是Android编程的新手,所以我不确定我是否朝着正确的方向去做,或者即使这是解决这个问题的正确方法,我也不一定在寻找代码,但如果你们可以帮助我朝着正确的方向前进,建议如何以更准确/更有效的方式获取数据,甚至建议如何改变我的代码逻辑,这将是伟大的!... BUUUUT如果你想帮我解决一些代码,我会非常感激! :d

另外,我想知道这是否是一种更好的计算速度的方法,如果我说的话,我会得到更准确的读数:

get location
add to arrayList

...fill list with 5 items and enter loop of...

calculate speed with items from list  <---
                                         |
remove oldest item from list             |
add current location to list             |
                                         |
loop -------------------------------------
这样我可以每秒钟获得一个新的速度值,但仍然具有计算过去5秒平均速度的准确性......或者有什么我不在这里考虑的事情? (请记住,我可以将间隔时间缩短到1/5秒,并且每秒读取5个读数,理论上能够每秒更新速度5次......或者这会产生不利影响)

任何反馈都会非常感激!

//更新1.从THE ANDDEV FORUMS

上的帖子中删除

好的,现在我有一些更新。

代码已经发生了重大变化。我把它分成了单独的类文件。

程序现在运行并获取它的当前位置,但是我会等待,移动,移动等待多久,它不会更新。现在我知道这可能只是我做错了但是我的理解是这一行中提供的值(以红色突出显示)决定更新频率,amirite ??

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,1000,locationListener);

主要

GPSMain.java

代码:

package Hartford.gps;

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class GPSMain extends Activity {

   //text views to display latitude and longitude
   TextView latituteField;
   TextView longitudeField;
   TextView currentSpeedField;

   protected double lat;
   protected double lon;

   //object to store previous location data
   protected Location oldLocation = null;

   //object to define 2 minutes of time
   static final int TWO_MINUTES = 1000 * 60 * 2;

   //object to store value for current speed
   protected int currentSpeed = 0;

   //boolean value used to compare new location with previous location
   protected boolean betterLocation;

   //list of locations to be used when calculating currentSpeed
   private List<Location> locations = new ArrayList<Location>();   

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

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

      run();

   }

   private void run(){
      //Acquire a reference to the system Location Manager
      LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

      // Define a listener that responds to location updates
      LocationListener locationListener = new LocationListener() {

         public void onLocationChanged(Location newLocation) {

            //temporarily store newLocation
            oldLocation = newLocation;

            //add the newLocation to the list
            locations = Calculations.updateLocations(locations, newLocation);
            currentSpeed = Calculations.calculateSpeed(locations, currentSpeed);

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

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

            latituteField.setText(String.valueOf(lat));
            longitudeField.setText(String.valueOf(lon));
            currentSpeedField.setText(String.valueOf(currentSpeed));

         }

         //not entirely sure what these do yet
         public void onStatusChanged(String provider, int status, Bundle extras) {}
         public void onProviderEnabled(String provider) {}
         public void onProviderDisabled(String provider) {}

      };

      // Register the listener with the Location Manager to receive location updates every second or kilometer
      locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1000, locationListener);
   }

}

计算类

Calculations.java

代码:

package Hartford.gps;

import java.util.List;

import android.location.Location;

public class Calculations {

   //update the locations list
   static List <Location> updateLocations(List <Location> locations, Location newLocation){

      List<Location> updatedLocations = locations;

      //create buffer
      Location buff = null;

      //if there are already 5 elements in the array
      if (updatedLocations.size()==5) {

         //remove the oldest location from the list and shift the remaining 4 down
         int i;
         //loop that executes 5 times
         for(i = 0; i > 4; i++){

            //store the value of the "i"th value in the array
            buff = updatedLocations.get(i+1);

            //replace the "i"th value with the "i-1"th
            //(effectively push the last element off and move the rest up)
            updatedLocations.set(i, buff);
         }

         //add the newest location to the beginning of the list
         updatedLocations.set(i, newLocation);

      //if there are less than 5 elements already in the array
      }else{

         //just add the newest location to the end
         updatedLocations.add(newLocation);

      }
      return updatedLocations;

   }



   //method to calculate speed

   //NB: I KNOW THAT THIS METHOD DOES NOT CURRENTLY CALCULATE THE CORRECT SPEED!
   //    I JUST HAVE IT DOING ADDITION SO THAT WHEN I'M DEBUGING THAT I CAN TELL IF IT IS
   //    WORKING OR NOT

   static int calculateSpeed(List<Location> locations, int speed){

      List <Location> speedList = locations;

      int totalSpeed = speed;

      while(speedList.contains(true)){

         totalSpeed++;

      }

      return totalSpeed;
   }


}

1 个答案:

答案 0 :(得分:1)

package Hartford.gps;

import java.math.BigDecimal;

import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class GPSMain extends Activity implements LocationListener {

LocationManager locationManager;
LocationListener locationListener;

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

//objects to store positional information
protected double lat;
protected double lon;

//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;

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

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

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

    run();
}

@Override
public void onResume() {
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, this);
    super.onResume();
}

@Override
public void onPause() {
    locationManager.removeUpdates(this);
    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);

    // Define a listener that responds to location updates
    locationListener = new LocationListener() {

        public void onLocationChanged(Location newLocation) {

            counter++;

            //current speed fo the gps device
            currentSpeed = round(newLocation.getSpeed(),3,BigDecimal.ROUND_HALF_UP);
            kmphSpeed = round((currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP);

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

            //calculates average speed
            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())),3,BigDecimal.ROUND_HALF_UP);
            lon = round(((double) (newLocation.getLongitude())),3,BigDecimal.ROUND_HALF_UP);

            latituteField = (TextView) findViewById(R.id.lat);
            longitudeField = (TextView) findViewById(R.id.lon);             
            currentSpeedField = (TextView) findViewById(R.id.speed);
            kmphSpeedField = (TextView) findViewById(R.id.kmph);
            avgSpeedField = (TextView) findViewById(R.id.avgspeed);
            avgKmphField = (TextView) findViewById(R.id.avgkmph);

            latituteField.setText("Current Latitude:        "+String.valueOf(lat));
            longitudeField.setText("Current Longitude:      "+String.valueOf(lon));
            currentSpeedField.setText("Current Speed (m/s):     "+String.valueOf(currentSpeed));
            kmphSpeedField.setText("Cuttent Speed (kmph):       "+String.valueOf(kmphSpeed));
            avgSpeedField.setText("Average Speed (m/s):     "+String.valueOf(avgSpeed));
            avgKmphField.setText("Average Speed (kmph):     "+String.valueOf(avgKmph));

        }

        //not entirely sure what these do yet
        public void onStatusChanged(String provider, int status, Bundle extras) {}
        public void onProviderEnabled(String provider) {}
        public void onProviderDisabled(String provider) {}

    };

    // Register the listener with the Location Manager to receive location updates
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, locationListener);
}

//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();
}


@Override
public void onLocationChanged(Location location) {
    // TODO Auto-generated method stub

}

@Override
public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub

}

@Override
public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub

}

}