понедельник, 26 сентября 2011 г.

Прием GPS координат.

Постановка задачи: Отправлять координаты на сервер, а также сопутствующую информацию (скорость, направление, время получения координат, точность) в фоновом потоке.




Небольшая заметка по терминологии:
GPS (Система Глобального Позиционирования. Может обновлять данные раз в 1-5 секунд, точность 2-3 метра) - позволяет при помощи спутников определить свои координаты. (потом эти координаты можно использовать, чтобы увидеть свое месторасположение на карте)
холодный старт, теплый старт - это процессы поиска спутников.
горячий старт - определение своих координат
GPRS - интернет, через оператора мобильной связи
LBS - получение своих координат не при помощи спутников, а на основании данных о нахождении ближайших вышек, передающих сигнал на мобильный телефон. (точность не очень, когда я тестировал были отклонения метров  на 500)
A-GPS - система ускорения холодного и теплого старта GPS приемника.
Как работает GPS:
GPS-приемник на телефоне получает информацию о местонахождении спутников, потом вычисляется расстояние от телефона до каждого спутника, на основе этих данных определяются координаты. Вся эта информация передается по GPRS, по крайней мере если у меня на телефоне его выключить и включить интернет по блютузу GPS приемник не работает. Поскольку в зданиях GPS приемник не видит спутников, то GPS там не работает.


Перед тем как реализовывать свой код GPS на Android-е желательно скачать готовое приложение, использующие GPS и убедится, что все работает. Например у меня на телефоне 
Samsung galaxy 5800 GPS изначально не работал, пришлось лазить на форумах в поисках решения этой проблемы.


Привожу код классов реализующих GPS у меня:

import java.math.BigDecimal;
import java.math.RoundingMode;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import com.evos.gps.IGPSCommunicator;
import com.google.inject.Singleton;

@Singleton
public class GPSCommunicator implements IGPSCommunicator {

  private final int RAUND_MOD = 4;
  private LocationManager _locationManager;
  private double _latitude = 0;
  private double _longitude = 0;
  private float _accuracy = 0;
  private long _time = 0;
  private float _speed = 0;
  private double _altitude = 0;
  private float _bearing = 0;

  private class GPSListener implements LocationListener {

    public void onLocationChanged(final Location loc) {
      if (loc != null) setLatitudeAndLongitude( loc.getLatitude(), loc.getLongitude(), loc.getAccuracy(), loc.getTime(), loc.getSpeed(), loc.getAltitude(), loc.getBearing() );
    }

    public void onProviderDisabled(String provider) { }

    public void onProviderEnabled(String provider) { }

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

  public synchronized double getLatitude() {
    return new BigDecimal(_latitude).setScale(RAUND_MOD, RoundingMode.HALF_EVEN).doubleValue();
  }

  public synchronized double getLongitude() {
    return new BigDecimal(_longitude).setScale(RAUND_MOD, RoundingMode.HALF_EVEN).doubleValue();
  }

  public synchronized float getAccuracy() {
    return _accuracy;
  }

  public synchronized long getTime() {
    return _time;
  }

  public synchronized float getSpeed() {
    return _speed;
  }

  public synchronized double getAltitude() {
    return _altitude;
  }

  public synchronized float getBearing() {
    return _bearing;
  }

  private synchronized void setLatitudeAndLongitude(double latitude, double longitude, float accuracy, long time, float speed, double altitude, float bearing) {
    _longitude = longitude;
    _latitude = latitude;
    _accuracy = accuracy;
    _time = time;
    _speed = speed;
    _altitude = altitude;
    _bearing = bearing;
  }

  public void setContext(Context context) {
    initializationGPS(context);
  }

  private void initializationGPS(Context context) {
    _locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    _locationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER,
        0,
        0,
        new GPSListener());

  }

}



public interface IGPSCommunicator {

  public double getLatitude();
  public double getLongitude();
  public float getAccuracy();
  public long getTime();
  public float getSpeed();
  public double getAltitude();
  public float getBearing();
  public void setContext(Context context);

}



Дальше я создавал экземпляр класса GPSCommunicator в методе onGreate, класса унаследованного от Service. Вместо Service можно использовать daemon поток,
какой из этих подходов лучше использовать и в какой ситуации мне пока не ясно.








3 комментария:

  1. Максим,спасибо за статью, помогла! еще про работу с GPS на Android http://www.enterra.ru/blog/gps-android/

    ОтветитьУдалить
  2. Что то я не пойму, а где в этом коде отправка данных на сервер?

    ОтветитьУдалить