Android. Работаем с GPS

Большинство устройств под управлением Android может определять свое положение с той или иной точностью. Это достигается использованием глобальной системы позиционирования (GPS), триангуляцией по базовым станциям сотовых сетей или при помощи открытых (публичных) точек доступа. Чтобы использовать эти возможности нам нужен пакет android.location.

В этом пакете находится несколько классов, наиболее важные:

  • LocationManager — предоставляет доступ к системным сервисам позиционирования, т.е. к GPS и компании. Так же с его помощью можно выбрать сервис, наиболее полно отвечающий заданным критериям (потребляемая мощность, точность позиционирования и др.)
  • LocationProvider — абстрактный класс, от которого образованы все поставщики (провайдеры) информации о географическом положении. Провайдер периодически поставляет информацию об изменении географических координат устройства.
  • LocationListener — используется для получения уведомлений от LocationProvider'а при смене координат.

Здесь же можно упомянуть классы Location (географическое положение устройства в определенный момент времени) и Criteria (критерии выбора провайдера).

В дальнейшем будем рассматривать получение координат от провайдера GPS_PROVIDER.

Чтобы приложение могло получать данные о географическом положении устройства в файле AndroidManifets.xml должны присутствовать строки

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">
<uses-feature android:name="android.hardware.location.gps">

Не буду здесь в деталях описывать процесс создания приложения, а просто приведу код, реализующий «слушанье» GPS

package com.example.anddemo;

import android.app.Activity;
import android.os.Bundle;

import android.content.Context;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;

import android.util.Log;

import android.view.View;
import android.widget.EditText;

public class AppActivity extends Activity {
    private EditText etLatitude;
    private EditText etLongitude;

    private LocationManager mLocationManager;
    private LocationListener mLocationListener;

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

        // текстовые поля для отображения координат
        etLatitude = (EditText) findViewById(R.id.txtLat);
        etLongitude = (EditText) findViewById(R.id.txtLon);

        // получаем экземпляр LocationManager'а
        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        // пытаемся получить предыдущие координаты
        Location currentLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        // и, если они есть, показываем
        if (currentLocation != null) {
            float lat = (float) (currentLocation.getLatitude());
            float lon = (float) (currentLocation.getLongitude());
            etLatitude.setText(Float.toString(lat));
            etLongitude.setText(Float.toString(lon));
        } else {
            etLatitude.setText("No location info");
            etLongitude.setText("No location info");
        }

        // создаем listener, чтобы "слушать" изменения
        mLocationListener = new LocationListener() {
            public void onStatusChanged(String provider, int status,
                                        Bundle extras) {
                switch (status) {
                    case LocationProvider.OUT_OF_SERVICE:
                        Log.v("GPS demo",
                              "Status changed: " + provider + " provider"
                              + " out of service");
                        break;
                    case LocationProvider.TEMPORARILY_UNAVAILABLE:
                        Log.v("GPS demo",
                              "Status changed: " + provider + " provider"
                              + " temporarily unavailable");
                        break;
                    case LocationProvider.AVAILABLE:
                        Log.v("GPS demo",
                              "Status changed: " + provider + " provider"
                              + " available");
                        break;
                }
            }

            public void onProviderEnabled(String provider) {
                Log.v("GPS demo", "Enabled new provider: " + provider);
            }

            public void onProviderDisabled(String provider) {
                Log.v("GPS demo", "Disabled provider: " + provider);
            }

            public void onLocationChanged(Location location) {
                Log.v("GPS demo", "Location changed");
                float lat = (float) (location.getLatitude());
                float lon = (float) (location.getLongitude());
                etLatitude.setText(Float.toString(lat));
                etLongitude.setText(Float.toString(lon));
            }
        };
    }

    /* при старте приложения cвязываем listener с manager'ом и запрашиваем
     * обновления с максимальной частотой (в реальном приложении частоту
     * запросов стоит снизить)
     */
    protected void onResume() {
        super.onResume();
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                                                0, 0, mLocationListener);
    }

    // перестаем отслеживать изменения при приостановке приложения
    protected void onPause() {
        super.onPause();
        mLocationManager.removeUpdates(mLocationListener);
    }
}
``

Тестировать можно как на реальном устройстве, так и при помощи
эмулятора. Перед запуском приложения необходимо убедиться, что модуль
GPS активен. При использовании эмулятора координаты можно передавать
из DDMS

или при помощи telnet:

подключаемся к устройству (5554 это номер эмулятора)

telnet localhost 5554

отправляем координаты (долгота широта)

geo fix 48 51