Android
Место нахождения
Поиск…
Вступление
API Android Location используются в самых разных приложениях для различных целей, таких как поиск местоположения пользователя, уведомление о том, когда пользователь покинул общую область (Geofencing), и помочь интерпретировать активность пользователя (ходьба, работа, вождение и т. Д.).
Однако API-интерфейсы Android не являются единственным средством приобретения местоположения пользователя. Ниже приводятся примеры использования Android LocationManager и других распространенных библиотек местоположений.
замечания
Для создания приложений с поддержкой местоположения на Android существует два пути:
- Исходный исходный код
LocationManagerAndroid - Google
FusedLocationProviderApi, входящий в состав Google Play Services
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
- Необходимые разрешения:
-
ACCESS_FINE_LOCATIONдля более точного местоположения илиACCESS_COARSE_LOCATIONдля менее точного местоположения
-
- Точность: 10 м - 100 м
- Требования к питанию: HIGH
- Доступность: везде, где доступны службы Google Play.
- ЗАМЕТКИ:
- Если
ACCESS_FINE_LOCATIONне используется, это не будет использовать GPS для генерации обновлений местоположения, но все равно найдет довольно точную точку в правильных условиях. - Если
ACCESS_FINE_LOCATIONиспользуется, он может или не может использовать GPS для создания точек местоположения, в зависимости от того, насколько точно он может отслеживать устройство в соответствии с условиями окружающей среды. - Хотя это может сообщать о более точном обновлении местоположения, чем другие настройки, оно все еще подвержено эффекту « Городской каньон ».
- Если
PRIORITY_BALANCED_POWER_ACCURACY
- Необходимые разрешения:
-
ACCESS_FINE_LOCATIONдля более точного местоположения илиACCESS_COARSE_LOCATIONдля менее точного местоположения
-
- Точность: 100 м - 1000 м +
- Требования к питанию: СРЕДНЯЯ
- Доступность: везде, где доступны службы Google Play.
- ЗАМЕТКИ:
- Такие же заметки, как
PRIORITY_HIGH_ACCURACY - Хотя это маловероятно, этот параметр может по-прежнему использовать GPS для создания местоположения.
- Такие же заметки, как
PRIORITY_LOW_POWER
- Необходимые разрешения:
- Точность: 100 м - 1000 м +
- Требования к питанию: LOW
- Доступность: везде, где доступны службы Google Play.
- ЗАМЕТКИ:
- Вероятно, он не использует GPS, но пока не проверен.
- Обновления обычно не очень точны
- Обычно используется для обнаружения значительных изменений в местоположении
PRIORITY_NO_POWER
- Необходимые разрешения:
- Точность: 10 м - 1000 м +
- Требования к питанию: НЕТ
- Доступность: везде, где доступны службы Google Play.
- ЗАМЕТКИ:
- Функции почти идентичны с
LocationManagerPASSIVE_PROVIDER -
PASSIVE_PROVIDERотчеты об обновлениях Служб Google Play, когдаPASSIVE_PROVIDERсообщает о возвращенных базовых обновлениях местоположения
- Функции почти идентичны с
Поиск проблемы
OnLocationChanged () никогда не вызывается
Поскольку это, похоже, является общей проблемой при получении Android Locations, я изложу быстрый контрольный список общих исправлений:
Проверьте свой манифест!
Одна из наиболее распространенных проблем заключается в том, что правильные разрешения никогда не предоставлялись. Если вы используете 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.
(Для Android 6+) Проверьте разрешения во время выполнения !
Проверьте и запросите разрешения! Если вам никогда не дадут разрешения, вы столкнетесь с аварийными ситуациями или, что еще хуже (если вы поймаете все исключения), вы ничего не увидите! Не имеет значения, предоставит ли пользователь разрешение в начале приложения, всегда проверяйте, есть ли у вас разрешения для всех вызовов. Пользователь может легко перейти к своим настройкам и отозвать их.
Дважды проверьте свой код!
Вы уверены, что проходите в правом слушателе?
IntentServiceли вы, чтоBroadcastReceiverилиIntentServiceк вашему манифесту? Используете ли выPendingIntent.getService()в классеBroadcastReceiverилиgetBroadcast()в классеIntentService? Вы уверены, что не регистрируете своего слушателя где-то еще в своем коде сразу после запроса?
Проверьте настройки устройства!
Очевидно, убедитесь, что вы включили службы определения местоположения.
Если вы используете сетевые службы, включили ли вы «Сканирование всегда доступно»? У вас установлен режим «Лучшее» («Высокая точность») или «Аккумуляторная батарея» (только для сети)?
Если вы используете GPS, включили ли вы режим «Лучшее» («Высокая точность») или «Только устройство» в режиме местоположения?
Дважды проверьте свой код!
Да, это здесь дважды. Вы пытались использовать
LocationListenerвместоPendingIntentили наоборот, чтобы убедиться, что вы действительно реализовалиLocationManagerправильно? Вы уверены, что запрос местоположения не удаляется в какой-либо части жизненного цикла Activity или Service, который вы не ожидали?
Проверьте свое окружение!
Вы тестируете 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();
}


