Android
Plaats
Zoeken…
Invoering
Android-locatie-API's worden gebruikt in een breed scala aan apps voor verschillende doeleinden, zoals het vinden van gebruikerslocatie, melden wanneer een gebruiker een algemeen gebied heeft verlaten (Geofencing) en helpen bij het interpreteren van gebruikersactiviteit (wandelen, hardlopen, rijden, enz.).
Android Location API's zijn echter niet het enige middel om de gebruikerslocatie te verkrijgen. Het volgende geeft voorbeelden van het gebruik van Android's LocationManager
en andere veelgebruikte locatiebibliotheken.
Opmerkingen
Voor het bouwen van locatiebewuste apps in Android zijn er twee paden:
- Android's native open source
LocationManager
-
FusedLocationProviderApi
van Google, dat deel uitmaakt van Google Play Services
Locatie manager
Pros
- Meer korrelige controle
- Beschikbaar op alle apparaten
- Onderdeel van het Android-framework
Cons
- Batterijverbruik is een probleem, als het niet goed wordt beheerd
- Vereist logica om van locatie-aanbieder te wisselen, als het apparaat een locatie niet kan vinden (bijv. Slechte GPS in een gebouw)
Kenmerken
- NMEA-luisteraar
- GPS-statusluisteraar
- Luister naar statuswijzigingen van provider (bijv. GPS is uitgeschakeld door gebruiker)
- Lijst met providers waaruit u de locatiebron kunt kiezen
providers
GPS
- Vereiste rechten:
- Nauwkeurigheid: 10m - 100m
- Stroomvereisten: HOOG
- Beschikbaarheid: Wereldwijd (met vrij zicht op de lucht)
- OPMERKINGEN :
- Locatie-updates komen meestal elke seconde binnen, maar in situaties waarin GPS enige tijd niet is gebruikt en A-GPS niet beschikbaar is, kan het enkele minuten duren voordat een locatie wordt ontvangen.
- In gevallen waar een helder zicht op de lucht wordt belemmerd, zullen GPS-punten niet erg goed clusteren (locatiepunten "springen") en kan nauwkeurigheid in bepaalde gebieden misleidend zijn vanwege het " Urban Canyon " -effect.
Netwerk
- Vereiste rechten:
- Nauwkeurigheid: 100m - 1000m +
- Stroomvoorziening: LAAG - GEMIDDELD
- Beschikbaarheid: binnen bereik van celtoren of wifi-signaal
- OPMERKINGEN:
- Locatie-updates vinden minder vaak plaats dan GPS
- Locatie-updates clusteren meestal niet goed (locatiepunten "springen") en de nauwkeurigheid kan variëren afhankelijk van het aantal verschillende factoren (aantal wifi-signalen, signaalsterkte, type celtoren, enz.)
Passief
- Vereiste rechten:
- Nauwkeurigheid: 10m - 1000m +
- Stroomvereisten: GEEN
- Beschikbaarheid: alleen wanneer een andere app een locatie ontvangt van GPS of netwerk
- OPMERKINGEN:
- Vertrouw hier niet op om u continue updates te geven. Dit luistert passief naar andere apps die locatieverzoeken doen en geeft die locaties terug.
- Retourneert geen door FusedLocationProviderApi gegenereerde punten, alleen de onderliggende locatiepunten die worden gebruikt om ze te genereren.
FusedLocationProviderApi
Pros
- Biedt minder lege batterijen "out of the box"
- Behandelt slechte GPS goed
- Krijgt regelmatig updates
Cons
- Minder korrelige controle over GPS
- Mogelijk niet beschikbaar op alle apparaten of in bepaalde landen
- Vereist afhankelijkheid van externe bibliotheken
Kenmerken
- Goed beheerd gebruik van locatieproviders voor optimale beslagbesparingen
- Genereert doorgaans nauwkeurigere punten dan netwerklocatieprovider
- Meer frequente updates van de bibliotheek, waardoor meer verbetering mogelijk is
- U hoeft niet op te geven welk type provider u moet gebruiken
LocationRevest Priority Levels
PRIORITY_HIGH_ACCURACY
- Vereiste rechten:
-
ACCESS_FINE_LOCATION
voor een nauwkeurigere locatie ofACCESS_COARSE_LOCATION
voor een minder nauwkeurige locatie
-
- Nauwkeurigheid: 10m - 100m
- Stroomvereisten: HOOG
- Beschikbaarheid: overal waar Google Play Services beschikbaar is.
- OPMERKINGEN:
- Als
ACCESS_FINE_LOCATION
niet wordt gebruikt, zal dit geen GPS gebruiken voor het genereren van locatie-updates, maar vindt het toch een redelijk nauwkeurig punt in de juiste omstandigheden. - Als
ACCESS_FINE_LOCATION
wordt gebruikt, kan het al dan niet GPS gebruiken om locatiepunten te genereren, afhankelijk van hoe nauwkeurig het momenteel het apparaat kan volgen, gegeven de omgevingsomstandigheden. - Hoewel dit mogelijk meer accurate locatie-updates meldt dan de andere instellingen, is het nog steeds gevoelig voor het " Urban Canyon " -effect.
- Als
PRIORITY_BALANCED_POWER_ACCURACY
- Vereiste rechten:
-
ACCESS_FINE_LOCATION
voor een nauwkeurigere locatie ofACCESS_COARSE_LOCATION
voor een minder nauwkeurige locatie
-
- Nauwkeurigheid: 100m - 1000m +
- Stroomvoorziening: MEDIUM
- Beschikbaarheid: overal waar Google Play Services beschikbaar is.
- OPMERKINGEN:
- Zelfde notities als
PRIORITY_HIGH_ACCURACY
- Hoewel het onwaarschijnlijk is, kan deze instelling GPS nog steeds gebruiken om een locatie te genereren.
- Zelfde notities als
PRIORITY_LOW_POWER
- Vereiste rechten:
- Nauwkeurigheid: 100m - 1000m +
- Stroomvereisten: LAAG
- Beschikbaarheid: overal waar Google Play Services beschikbaar is.
- OPMERKINGEN:
- Waarschijnlijk maakt geen gebruik van GPS, maar tot nu toe niet getest.
- Updates zijn meestal niet erg nauwkeurig
- Over het algemeen gebruikt om significante locatiewijzigingen op te sporen
PRIORITY_NO_POWER
- Vereiste rechten:
- Nauwkeurigheid: 10m - 1000m +
- Stroomvereisten: GEEN
- Beschikbaarheid: overal waar Google Play Services beschikbaar is.
- OPMERKINGEN:
- Functies bijna identiek aan
LocationManager
PASSIVE_PROVIDER
- Meldt updates van Google Play-services terug bij ontvangst, waar
PASSIVE_PROVIDER
rapporteert over gebruikte gebruikte locatie-updates
- Functies bijna identiek aan
Probleemoplossen
OnLocationChanged () Nooit aangeroepen
Aangezien dit een veel voorkomend probleem lijkt te zijn bij het verkrijgen van Android-locaties, zal ik een korte checklist met veelvoorkomende oplossingen opstellen:
Controleer je manifest!
Een van de meest voorkomende problemen is dat nooit de juiste machtigingen zijn gegeven. Als u GPS (met of zonder netwerk) gebruikt, gebruikt u
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
use<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
, anders gebruikt u<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
use<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
. FusedLocationApi van Google vereistACCESS_FINE_LOCATION
.
(Voor Android 6+) Controleer runtime-machtigingen !
Controleer en vraag toestemming! Als je nooit machtigingen krijgt, zul je crashes krijgen, of erger (als je alle uitzonderingen opvangt), heb je geen enkele indicatie! Het maakt niet uit of de gebruiker u toestemming geeft aan het begin van de app, controleer altijd of u machtigingen hebt voor alle oproepen. De gebruiker kan eenvoudig naar zijn instellingen gaan en ze intrekken.
Controleer nogmaals uw code!
Weet je zeker dat je de juiste luisteraar doorgeeft? Heb je die
BroadcastReceiver
ofIntentService
aan je manifest toegevoegd? Gebruikt uPendingIntent.getService()
op eenBroadcastReceiver
klasse ofgetBroadcast()
op eenIntentService
klasse? Weet je zeker dat je je luisteraar niet ergens anders in je code ongedaan maakt direct nadat je hierom hebt gevraagd?
Controleer apparaatinstellingen!
Zorg er uiteraard voor dat locatieservices zijn ingeschakeld.
Hebt u "Scannen altijd beschikbaar" ingeschakeld als u netwerkservices gebruikt? Heeft u uw locatiemodus ingesteld op "Best" ("Hoge nauwkeurigheid") of "Batterijbesparing" ("Alleen netwerk")?
Als u GPS gebruikt, hebt u "Beste" ("Hoge nauwkeurigheid") of "Alleen apparaat" in locatiemodus ingeschakeld?
Controleer nogmaals uw code!
Ja, dit staat hier twee keer op. Hebt u geprobeerd een
LocationListener
plaats van eenPendingIntent
, of omgekeerd, om ervoor te zorgen dat uLocationManager
daadwerkelijk correct implementeerde? Weet u zeker dat het locatieverzoek niet wordt verwijderd in een deel van de levenscyclus van activiteit of service waarvan u niet had verwacht dat het zou gebeuren?
Controleer je omgeving!
Test u GPS op de eerste verdieping van een gebouw in het midden van San Francisco? Test u netwerklocaties in de middle of nowhere? Werk je in een geheime ondergrondse bunker zonder alle radiosignalen en vraag je je af waarom je apparaat geen locatie krijgt? Controleer altijd uw omgeving wanneer u probeert locatieproblemen op te lossen!
Er kunnen nog veel andere, minder voor de hand liggende redenen zijn waarom de locatie niet werkt, maar doorloop deze snelle checklist voordat je die esoterische oplossingen zoekt.
Gefuseerde locatie-API
Voorbeeld met activiteit 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
}
}
Voorbeeld met Service w / PendingIntent en BroadcastReceiver
ExampleActivity
Aanbevolen literatuur: 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
}
}
}
}
Locatie service
OPMERKING: vergeet deze service niet te registreren in het Manifest!
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
OPMERKING: vergeet deze ontvanger niet te registreren in de Manifest!
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));
}
}
}
Locatie-updates aanvragen met behulp van LocationManager
Zoals altijd moet u ervoor zorgen dat u over de vereiste machtigingen beschikt.
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) {
}
}
Locatie-updates aanvragen op een afzonderlijke thread met behulp van LocationManager
Zoals altijd moet u ervoor zorgen dat u over de vereiste machtigingen beschikt.
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) {
}
}
Geofence registreren
Ik heb de singleton- klasse GeoFenceObserversationService
gemaakt.
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);
}
}
Waar ben ik begonnen met service? Van toepassingsklasse
-
startService(new Intent(getApplicationContext(),GeoFenceObserversationService.class));
Hoe ik Geofences heb geregistreerd?
-
GeoFenceObserversationService.getInstant().addGeofences();
Krijg adres van locatie met behulp van Geocoder
Nadat u het kreeg Location
object uit FusedAPI
, kunt u gemakkelijk te verwerven Address
informatie van dat object.
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;
}
Locatie-updates ophalen in een BroadcastReceiver
Maak eerst een klasse BroadcastReceiver om de binnenkomende locatie-updates af te handelen:
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 ***");
}
}
}
}
Wanneer u vervolgens verbinding maakt met GoogleApiClient in de onConnected callback:
@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);
}
Vergeet niet om de intentie voor locatie-update te verwijderen in de juiste call voor de levenscyclus:
@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();
}