Поиск…


Вступление

API Android Location используются в самых разных приложениях для различных целей, таких как поиск местоположения пользователя, уведомление о том, когда пользователь покинул общую область (Geofencing), и помочь интерпретировать активность пользователя (ходьба, работа, вождение и т. Д.).

Однако API-интерфейсы Android не являются единственным средством приобретения местоположения пользователя. Ниже приводятся примеры использования Android LocationManager и других распространенных библиотек местоположений.

замечания

Для создания приложений с поддержкой местоположения на Android существует два пути:

LocationManager

Pros

  • Более гранулированный контроль
  • Доступно на всех устройствах
  • Часть платформы Android

Cons

  • Слив батареи - проблема, если ее не управляют должным образом
  • Требуется логика для переключения поставщиков местоположения, если устройство не может найти местоположение (например, плохой GPS внутри здания)

Характеристики

  • Приемник NMEA
  • Приемник состояния GPS
  • Слушайте изменения статуса поставщика (например, GPS отключается пользователем)
  • Список поставщиков для выбора источника местоположения

Провайдеры

GPS

  • Необходимые разрешения:
  • Точность: 10 м - 100 м
  • Требования к питанию: HIGH
  • Доступность: во всем мире (с ясным видом на небо)
  • ПРИМЕЧАНИЯ :
    • Обновления местоположения обычно поступают один раз в секунду, но в ситуациях, когда GPS не используется в течение некоторого времени, и A-GPS недоступен, для получения местоположения требуется несколько минут.
    • В тех случаях, когда затруднено четкое представление о небе, точки GPS не будут группироваться очень хорошо (точки места «прыгать»), и точность может вводить в заблуждение в определенных областях из-за эффекта « Городской каньон ».

сеть

  • Необходимые разрешения:
  • Точность: 100 м - 1000 м +
  • Требования к питанию: LOW - MEDIUM
  • Доступность: В пределах диапазона ячеек башни или сигнала Wi-Fi
  • ЗАМЕТКИ:
    • Обновления местоположения происходят реже, чем GPS
    • Обновления местоположения обычно не кластеризуются (точки места «прыгать»), и точность может варьироваться в зависимости от количества различных факторов (количество сигналов Wi-Fi, уровень сигнала, тип ячейки башни и т. Д.),

пассивный

  • Необходимые разрешения:
  • Точность: 10 м - 1000 м +
  • Требования к питанию: НЕТ
  • Доступность: только когда другое приложение получает местоположение от GPS или сети
  • ЗАМЕТКИ:
    • Не полагайтесь на это, чтобы постоянно обновлять его. Это пассивно слушает другие приложения, которые делают запросы на местоположение, и передает их обратно.
    • Не возвращает FagedLocationProviderApi сгенерированные точки, только базовые точки местоположения, используемые для их создания.

FusedLocationProviderApi

Pros

  • Предлагает меньше разряда аккумулятора «из коробки»
  • Обрабатывает плохой GPS-приемник
  • Получает обновления более регулярно

Cons

  • Менее детальный контроль над GPS
  • Может быть недоступен на всех устройствах или в некоторых странах
  • Требуется зависимость сторонней библиотеки

Характеристики

  • Хорошо управляемое использование поставщиков местоположения для оптимальной экономии тесто
  • Обычно генерирует более точные точки, а затем Network Location Provider
  • Более частые обновления библиотеки, позволяющие улучшить
  • Нет необходимости указывать, какой тип поставщика использовать

Приоритетные уровни местоположения

PRIORITY_HIGH_ACCURACY

  • Необходимые разрешения:
  • Точность: 10 м - 100 м
  • Требования к питанию: HIGH
  • Доступность: везде, где доступны службы Google Play.
  • ЗАМЕТКИ:
    • Если ACCESS_FINE_LOCATION не используется, это не будет использовать GPS для генерации обновлений местоположения, но все равно найдет довольно точную точку в правильных условиях.
    • Если ACCESS_FINE_LOCATION используется, он может или не может использовать GPS для создания точек местоположения, в зависимости от того, насколько точно он может отслеживать устройство в соответствии с условиями окружающей среды.
    • Хотя это может сообщать о более точном обновлении местоположения, чем другие настройки, оно все еще подвержено эффекту « Городской каньон ».

PRIORITY_BALANCED_POWER_ACCURACY

  • Необходимые разрешения:
  • Точность: 100 м - 1000 м +
  • Требования к питанию: СРЕДНЯЯ
  • Доступность: везде, где доступны службы Google Play.
  • ЗАМЕТКИ:
    • Такие же заметки, как PRIORITY_HIGH_ACCURACY
    • Хотя это маловероятно, этот параметр может по-прежнему использовать GPS для создания местоположения.

PRIORITY_LOW_POWER

  • Необходимые разрешения:
  • Точность: 100 м - 1000 м +
  • Требования к питанию: LOW
  • Доступность: везде, где доступны службы Google Play.
  • ЗАМЕТКИ:
    • Вероятно, он не использует GPS, но пока не проверен.
    • Обновления обычно не очень точны
    • Обычно используется для обнаружения значительных изменений в местоположении

PRIORITY_NO_POWER

  • Необходимые разрешения:
  • Точность: 10 м - 1000 м +
  • Требования к питанию: НЕТ
  • Доступность: везде, где доступны службы Google Play.
  • ЗАМЕТКИ:
    • Функции почти идентичны с LocationManager PASSIVE_PROVIDER
    • PASSIVE_PROVIDER отчеты об обновлениях Служб Google Play, когда PASSIVE_PROVIDER сообщает о возвращенных базовых обновлениях местоположения

Поиск проблемы

OnLocationChanged () никогда не вызывается

Поскольку это, похоже, является общей проблемой при получении Android Locations, я изложу быстрый контрольный список общих исправлений:


  1. Проверьте свой манифест!

    Одна из наиболее распространенных проблем заключается в том, что правильные разрешения никогда не предоставлялись. Если вы используете GPS (с сетью или без нее), используйте <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> use <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> , иначе используйте <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> , Для FuseLocationApi от Google требуется ACCESS_FINE_LOCATION .


  1. (Для Android 6+) Проверьте разрешения во время выполнения !

    Проверьте и запросите разрешения! Если вам никогда не дадут разрешения, вы столкнетесь с аварийными ситуациями или, что еще хуже (если вы поймаете все исключения), вы ничего не увидите! Не имеет значения, предоставит ли пользователь разрешение в начале приложения, всегда проверяйте, есть ли у вас разрешения для всех вызовов. Пользователь может легко перейти к своим настройкам и отозвать их.


  1. Дважды проверьте свой код!

    Вы уверены, что проходите в правом слушателе? IntentService ли вы, что BroadcastReceiver или IntentService к вашему манифесту? Используете ли вы PendingIntent.getService() в классе BroadcastReceiver или getBroadcast() в классе IntentService ? Вы уверены, что не регистрируете своего слушателя где-то еще в своем коде сразу после запроса?


  1. Проверьте настройки устройства!

    Очевидно, убедитесь, что вы включили службы определения местоположения.

    введите описание изображения здесь

    Если вы используете сетевые службы, включили ли вы «Сканирование всегда доступно»? У вас установлен режим «Лучшее» («Высокая точность») или «Аккумуляторная батарея» (только для сети)?

    введите описание изображения здесь

    Если вы используете GPS, включили ли вы режим «Лучшее» («Высокая точность») или «Только устройство» в режиме местоположения?

    введите описание изображения здесь


  1. Дважды проверьте свой код!

    Да, это здесь дважды. Вы пытались использовать LocationListener вместо PendingIntent или наоборот, чтобы убедиться, что вы действительно реализовали LocationManager правильно? Вы уверены, что запрос местоположения не удаляется в какой-либо части жизненного цикла Activity или Service, который вы не ожидали?


  1. Проверьте свое окружение!

    Вы тестируете GPS на первом этаже здания в центре Сан-Франциско? Проверяете ли вы сетевые местоположения в середине нигде? Вы работаете в секретном подземном бункере, лишенном всех радиосигналов, удивляясь, почему ваше устройство не получает место? Всегда проверяйте свое окружение, пытаясь устранить проблемы с местоположением!


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

API с плавающим местоположением

Пример использования активности w / LocationRequest

/*
 * This example is useful if you only want to receive updates in this 
 * activity only, and have no use for location anywhere else.
 */
public class LocationActivity extends AppCompatActivity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
                .setInterval(2000) //At least once every 2 seconds
                .setFastestInterval(1000); //At most once a second
    }

    @Override
    protected void onStart(){
        super.onStart();
        mGoogleApiClient.connect();
    }
    
    @Override
    protected void onResume(){
        super.onResume();
        //Permission check for Android 6.0+
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            }
        }
    }
    
    @Override
    protected void onPause(){
        super.onPause();
        //Permission check for Android 6.0+
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            }
        }
    }
    
    @Override
    protected void onStop(){
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    }

    @Override
    public void onLocationChanged(Location location) {
        //Handle your location update code here
    }
}

Пример использования службы с ожиданием и трансляцией

ExampleActivity

Рекомендуемое чтение: LocalBroadcastManager

/*
 * This example is useful if you have many different classes that should be 
 * receiving location updates, but want more granular control over which ones
 * listen to the updates.
 * 
 * For example, this activity will stop getting updates when it is not visible, but a database
 * class with a registered local receiver will continue to receive updates, until "stopUpdates()" is called here.
 *
 */
public class ExampleActivity extends AppCompatActivity {

    private InternalLocationReceiver mInternalLocationReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        
        //Create internal receiver object in this method only.
        mInternalLocationReceiver = new InternalLocationReceiver(this);
    }

    @Override
    protected void onResume(){
        super.onResume();
        
        //Register to receive updates in activity only when activity is visible
        LocalBroadcastManager.getInstance(this).registerReceiver(mInternalLocationReceiver, new IntentFilter("googleLocation"));
    }

    @Override
    protected void onPause(){
        super.onPause();
        
        //Unregister to stop receiving updates in activity when it is not visible.
        //NOTE: You will still receive updates even if this activity is killed.
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mInternalLocationReceiver);
    }

    //Helper method to get updates
    private void requestUpdates(){
        startService(new Intent(this, LocationService.class).putExtra("request", true));
    }

    //Helper method to stop updates
    private void stopUpdates(){
        startService(new Intent(this, LocationService.class).putExtra("remove", true));
    }

    /*
     * Internal receiver used to get location updates for this activity.
     * 
     * This receiver and any receiver registered with LocalBroadcastManager does
     * not need to be registered in the Manifest.
     *
     */
    private static class InternalLocationReceiver extends BroadcastReceiver{

        private ExampleActivity mActivity;

        InternalLocationReceiver(ExampleActivity activity){
            mActivity = activity;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            final ExampleActivity activity = mActivity;
            if(activity != null) {
                LocationResult result = intent.getParcelableExtra("result");
                //Handle location update here
            }
        }
    }
}

Служба определения местоположения

ПРИМЕЧАНИЕ. Не забудьте зарегистрировать эту службу в манифесте!

public class LocationService extends Service implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    public void onCreate(){
        super.onCreate();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
                .setInterval(2000) //At least once every 2 seconds
                .setFastestInterval(1000); //At most once a second
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        super.onStartCommand(intent, flags, startId);
        //Permission check for Android 6.0+
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if (intent.getBooleanExtra("request", false)) {
                if (mGoogleApiClient.isConnected()) {
                    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
                } else {
                    mGoogleApiClient.connect();
                }
            }
            else if(intent.getBooleanExtra("remove", false)){
                stopSelf();
            }
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        if(mGoogleApiClient.isConnected()){
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, getPendingIntent());
            mGoogleApiClient.disconnect();
        }
    }
    
    private PendingIntent getPendingIntent(){
        
        //Example for IntentService
        //return PendingIntent.getService(this, 0, new Intent(this, **YOUR_INTENT_SERVICE_CLASS_HERE**), PendingIntent.FLAG_UPDATE_CURRENT);
        
        //Example for BroadcastReceiver
        return PendingIntent.getBroadcast(this, 0, new Intent(this, LocationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        //Permission check for Android 6.0+
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

LocationReceiver

ПРИМЕЧАНИЕ. Не забудьте зарегистрировать этот приемник в манифесте!

public class LocationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if(LocationResult.hasResult(intent)){
            LocationResult locationResult = LocationResult.extractResult(intent);
            LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("googleLocation").putExtra("result", locationResult));
        }
    }
}

Запрос обновлений местоположения с помощью LocationManager

Как всегда, вы должны убедиться, что у вас есть необходимые разрешения.

public class MainActivity extends AppCompatActivity implements LocationListener{

    private LocationManager mLocationManager = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    }


    @Override
    protected void onResume() {
        super.onResume();

        try {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
        catch(SecurityException e){
            // The app doesn't have the correct permissions
        }
    }


    @Override
    protected void onPause() {
        try{
            mLocationManager.removeUpdates(this);
        }
        catch (SecurityException e){
            // The app doesn't have the correct permissions
        }

        super.onPause();
    }




    @Override
    public void onLocationChanged(Location location) {
        // We received a location update!
        Log.i("onLocationChanged", location.toString());
    }

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

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

Запрос обновлений местоположения в отдельном потоке с помощью LocationManager

Как всегда, вы должны убедиться, что у вас есть необходимые разрешения.

public class MainActivity extends AppCompatActivity implements LocationListener{

    private LocationManager mLocationManager = null;
    HandlerThread mLocationHandlerThread = null;
    Looper mLocationHandlerLooper = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocationHandlerThread = new HandlerThread("locationHandlerThread");
    }


    @Override
    protected void onResume() {
        super.onResume();

        mLocationHandlerThread.start();
        mLocationHandlerLooper = mLocationHandlerThread.getLooper();

        try {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this, mLocationHandlerLooper);
        }
        catch(SecurityException e){
            // The app doesn't have the correct permissions
        }
    }


    @Override
    protected void onPause() {
        try{
            mLocationManager.removeUpdates(this);
        }
        catch (SecurityException e){
            // The app doesn't have the correct permissions
        }

        mLocationHandlerLooper = null;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
            mLocationHandlerThread.quitSafely();
        else
            mLocationHandlerThread.quit();

        mLocationHandlerThread = null;


        super.onPause();
    }




    @Override
    public void onLocationChanged(Location location) {
        // We received a location update on a separate thread!
        Log.i("onLocationChanged", location.toString());

        // You can verify which thread you're on by something like this:
        // Log.d("Which thread?", Thread.currentThread() == Looper.getMainLooper().getThread() ? "UI Thread" : "New thread");
    }

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

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

Зарегистрировать геозонность

Я создал GeoFenceObserversationService одноэлементный класс.

GeoFenceObserversationService.java :

public class GeoFenceObserversationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {

    protected static final String TAG = "GeoFenceObserversationService";
    protected GoogleApiClient mGoogleApiClient;
    protected ArrayList<Geofence> mGeofenceList;
    private boolean mGeofencesAdded;
    private SharedPreferences mSharedPreferences;
    private static GeoFenceObserversationService mInstant;
    public static GeoFenceObserversationService getInstant(){
        return mInstant;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstant = this;
        mGeofenceList = new ArrayList<Geofence>();
        mSharedPreferences = getSharedPreferences(AppConstants.SHARED_PREFERENCES_NAME, MODE_PRIVATE);
        mGeofencesAdded = mSharedPreferences.getBoolean(AppConstants.GEOFENCES_ADDED_KEY, false);

        buildGoogleApiClient();
    }


    @Override
    public void onDestroy() {
        mGoogleApiClient.disconnect();
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    protected void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle connectionHint) {
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
    }

    @Override
    public void onConnectionSuspended(int cause) {

    }

    private GeofencingRequest getGeofencingRequest() {

        GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
        builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
        builder.addGeofences(mGeofenceList);
        return builder.build();
    }


    public void addGeofences() {
            if (!mGoogleApiClient.isConnected()) {
                Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
                return;
            }

        populateGeofenceList();
        if(!mGeofenceList.isEmpty()){
            try {
                LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent()).setResultCallback(this);
            } catch (SecurityException securityException) {
                securityException.printStackTrace();
            }
        }

        }

    public void removeGeofences() {
        if (!mGoogleApiClient.isConnected()) {
            Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient,getGeofencePendingIntent()).setResultCallback(this);
        } catch (SecurityException securityException) {
            securityException.printStackTrace();
        }
    }


    public void onResult(Status status) {

        if (status.isSuccess()) {
            mGeofencesAdded = !mGeofencesAdded;
            SharedPreferences.Editor editor = mSharedPreferences.edit();
            editor.putBoolean(AppConstants.GEOFENCES_ADDED_KEY, mGeofencesAdded);
            editor.apply();
        } else {
            String errorMessage = AppConstants.getErrorString(this,status.getStatusCode());
            Log.i("Geofence", errorMessage);
        }
    }

    private PendingIntent getGeofencePendingIntent() {
        Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
        return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private void populateGeofenceList() {
        mGeofenceList.clear();
        List<GeoFencingResponce> geoFenceList = getGeofencesList;
        if(geoFenceList!=null&&!geoFenceList.isEmpty()){
            for (GeoFencingResponce obj : geoFenceList){
                mGeofenceList.add(obj.getGeofence());
                Log.i(TAG,"Registered Geofences : " + obj.Id+"-"+obj.Name+"-"+obj.Lattitude+"-"+obj.Longitude);
            }
        }
    }
}

AppConstant :

   public static final String SHARED_PREFERENCES_NAME = PACKAGE_NAME + ".SHARED_PREFERENCES_NAME";
    public static final String GEOFENCES_ADDED_KEY = PACKAGE_NAME + ".GEOFENCES_ADDED_KEY";
    public static final String DETECTED_GEOFENCES = "detected_geofences";
    public static final String DETECTED_BEACONS = "detected_beacons";

    public static String getErrorString(Context context, int errorCode) {
        Resources mResources = context.getResources();
        switch (errorCode) {
            case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
                return mResources.getString(R.string.geofence_not_available);
            case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
                return mResources.getString(R.string.geofence_too_many_geofences);
            case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
                return mResources.getString(R.string.geofence_too_many_pending_intents);
            default:
                return mResources.getString(R.string.unknown_geofence_error);
        }
    }

Где я начал службу? Из класса приложения

  • startService(new Intent(getApplicationContext(),GeoFenceObserversationService.class));

Как я зарегистрировал Geofences?

  • GeoFenceObserversationService.getInstant().addGeofences();

Получить адрес из местоположения с помощью геокодирования

После того, как вы получили объект Location из FusedAPI , вы можете легко получить Address информацию от этого объекта.

private Address getCountryInfo(Location location) {
    Address address = null;
    Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
    String errorMessage;
    List<Address> addresses = null;
    try {
        addresses = geocoder.getFromLocation(
                location.getLatitude(),
                location.getLongitude(),
                // In this sample, get just a single address.
                1);
    } catch (IOException ioException) {
        // Catch network or other I/O problems.
        errorMessage = "IOException>>" + ioException.getMessage();
    } catch (IllegalArgumentException illegalArgumentException) {
        // Catch invalid latitude or longitude values.
        errorMessage = "IllegalArgumentException>>" + illegalArgumentException.getMessage();
    }
    if (addresses != null && !addresses.isEmpty()) {
        address = addresses.get(0);
    }
    return country;
}

Получение обновлений местоположения в BroadcastReceiver

Сначала создайте класс BroadcastReceiver для обработки входящих обновлений местоположения:

public class LocationReceiver extends BroadcastReceiver implements Constants {

    @Override
     public void onReceive(Context context, Intent intent) {

        if (LocationResult.hasResult(intent)) {
            LocationResult locationResult = LocationResult.extractResult(intent);
            Location location = locationResult.getLastLocation();
            if (location != null) {
                // Do something with your location
            } else {
                Log.d(LocationReceiver.class.getSimpleName(), "*** location object is null ***");
            }
        }
    }
}

Затем, когда вы подключаетесь к GoogleApiClient в обратном вызове onConnected:

@Override
public void onConnected(Bundle connectionHint) {
    Intent backgroundIntent = new Intent(this, LocationReceiver.class);
    mBackgroundPendingIntent = backgroundPendingIntent.getBroadcast(getApplicationContext(), LOCATION_REUEST_CODE, backgroundIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    mFusedLocationProviderApi.requestLocationUpdates(mLocationClient, mLocationRequest, backgroundPendingIntent);
}

Не забудьте удалить намерение обновления местоположения в соответствующем обратном вызове жизненного цикла:

@Override
public void onDestroy() {
    if (servicesAvailable && mLocationClient != null) {
        if (mLocationClient.isConnected()) {
            fusedLocationProviderApi.removeLocationUpdates(mLocationClient, backgroundPendingIntent);
            // Destroy the current location client
            mLocationClient = null;
        } else {
            mLocationClient.unregisterConnectionCallbacks(this);
            mLocationClient = null;
        }
    }
    super.onDestroy();
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow