синхронизированный цикл для получения координат GPS и, в конечном итоге, для вычисления скорости - PullRequest
0 голосов
/ 03 июня 2011

* ОБНОВЛЕНО ВНУТРИ *

По сути, я пытаюсь написать простое приложение, чтобы определить, где я нахожусь, и обновлять свою позицию каждые [фиксированный интервал времени]

Я следовал этому учебнику и сумел получить значение моей позиции.Тем не менее, на всю жизнь я не могу заставить его работать в бесконечном цикле.Я просто хочу, чтобы он продолжался до тех пор, пока я не выйду из приложения (нажав кнопку назад на некоторое время).

Причина, по которой я хочу создать такой цикл, заключается в том, что я хочу вычислить свою скорость.Я собирался сделать это так:

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. Взято из моего поста на 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 Ответ

1 голос
/ 09 июня 2011
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

}

}
...