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:

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:
  • 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.

PRIORITY_BALANCED_POWER_ACCURACY

  • Vereiste rechten:
  • 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.

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

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:


  1. 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 vereist ACCESS_FINE_LOCATION .


  1. (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.


  1. Controleer nogmaals uw code!

    Weet je zeker dat je de juiste luisteraar doorgeeft? Heb je die BroadcastReceiver of IntentService aan je manifest toegevoegd? Gebruikt u PendingIntent.getService() op een BroadcastReceiver klasse of getBroadcast() op een IntentService klasse? Weet je zeker dat je je luisteraar niet ergens anders in je code ongedaan maakt direct nadat je hierom hebt gevraagd?


  1. Controleer apparaatinstellingen!

    Zorg er uiteraard voor dat locatieservices zijn ingeschakeld.

    voer hier de afbeeldingsbeschrijving in

    Hebt u "Scannen altijd beschikbaar" ingeschakeld als u netwerkservices gebruikt? Heeft u uw locatiemodus ingesteld op "Best" ("Hoge nauwkeurigheid") of "Batterijbesparing" ("Alleen netwerk")?

    voer hier de afbeeldingsbeschrijving in

    Als u GPS gebruikt, hebt u "Beste" ("Hoge nauwkeurigheid") of "Alleen apparaat" in locatiemodus ingeschakeld?

    voer hier de afbeeldingsbeschrijving in


  1. Controleer nogmaals uw code!

    Ja, dit staat hier twee keer op. Hebt u geprobeerd een LocationListener plaats van een PendingIntent , of omgekeerd, om ervoor te zorgen dat u LocationManager 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?


  1. 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();
}


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow