Hur man arbetar med Geofences på Android

Platsmedvetna resurser gör att din ansökan kan interagera med den fysiska världen och de är idealiska för att öka användarengagemanget. Även om många mobilappar använder dem, är ämnet för denna handledning en funktion som ofta förbises, geofencing.

En geofence är en virtuell omkrets inställd på ett riktigt geografiskt område. Kombinera en användarposition med en geofence omkrets, det är möjligt att veta om användaren är inne eller utanför geofence eller ens om han lämnar eller går in i området.

Föreställ dig en universitetsapp som kan berätta vilka kollegor och professorer som för närvarande är på campus. Eller en app för ett köpcentrum som belönar vanliga kunder. Det finns många andra intressanta möjligheter som du kan utforska.

I denna handledning lär du dig hur du använder geofences på Android genom att skapa en applikation som visar användaren en anmälan när de anger eller lämnar en geofence. Det hjälper om du har tidigare kunskaper om Google Play Services, Google Maps Android API eller IntentService. Om du inte gör det kan du fortfarande följa med, men du kanske vill göra lite forskning om dessa ämnen efter att ha läst den här handledningen.

1. Geofences på Android

På Android finns flera sätt att arbeta med geofences. Du kan till och med skapa ditt eget genomförande för att fungera med geofences, men det är lättare att använda Googles GeofencingApi.

Dessa API är en del av Googles Plats API: er. Det inkluderar geofence, GeofencingRequest, GeofenceApiGeofencingEvent, och GeofenceStatusCodes. I denna handledning använder vi dessa klasser för att skapa och arbeta med geofences.

Geofence-gränssnittet

geofence är ett gränssnitt som representerar ett geografiskt område som ska övervakas. Det skapas genom att använda Geofence.Builder. Under skapandet ställer du in den övervakade regionen, geofenceens utgångsdatum, lyhördhet, en identifierare och vilken typ av övergångar den ska leta efter.

För att hålla strömförbrukningen till ett minimum rekommenderas att använda en geofence med en radie på minst 100 meter för de flesta situationer. Om geofences finns på landsbygden, bör du öka radieen till 500 meter eller högre för att säkerställa att geofvenserna är effektiva.

Geofence geofence = ny Geofence.Builder () .setRequestId (GEOFENCE_REQ_ID) // Geofence ID .setCircularRegion (LATITUDE, LONGITUDE, RADIUS) // definierande stängsel region .setExpirationDuration (DURANTION) // utgångsdatum // Övergångstyper att det ska leta efter .setTransitionTypes (Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) .build ();

Geofence Transitions

  • GEOFENCE_TRANSITION_DWELL indikerar att användaren angav området och tillbringade tid där. Det är användbart att undvika flera varningar när användaren anger och lämnar området för snabbt. Du kan konfigurera bostadstiden med hjälp av setLoiteringDelay parameter.
  • GEOFENCE_TRANSITION_ENTER Indikerar när användaren går in i det övervakade området.
  • GEOFENCE_TRANSITION_EXIT  indikerar när användaren lämnar regionen.

GeofenceRequest

De GeofencingRequest klassen mottar de geofences som ska övervakas. Du kan skapa en instans genom att använda en Byggare, passerar a geofence eller a Lista, och vilken typ av meddelande som ska utlösas när geofence (er) skapas.

GeofencingRequest request = ny GeofencingRequest.Builder () // Meddelande att utlösa när Geofence skapas .setInitialTrigger (GeofencingRequest.INITIAL_TRIGGER_ENTER) .addGeofence (geofence) // lägg till en Geofence .build ();

GeofencingApi

De GeofencingApi klassen är startpunkten för alla interaktioner med Googles geofencing API. Det är en del av Plats API och det beror på a GoogleApiClient att jobba. Du kommer att använda GeofencingApi att lägga till och ta bort geofences.

För att lägga till en geofence, ringer du på addGeofence () metod. Den övervakar det angivna området med inställningarna som skickas till GeofencingRequest och skjuter a PendingIntent när en geofence-övergång, som går in i eller lämnar området, äger rum.

PendingResult addGeofences (GoogleApiClient-klient, GeofencingRequest geofencingRequest, PendingIntent pendingIntent)

För att ta bort geofensen ringer du removeGeofences (). Du kan antingen ta bort geofence med hjälp av dess förfrågningsidentifiering eller väntande avsikt.

PendingResult removeGeofences (GoogleApiClient-klient, Lista geofenceRequestIds)
 PendingResult removeGeofences (GoogleApiClient-klient, PendingIntent pendingIntent)

2. Skapa en Geofencing App

I den här handledningen skapar vi en enkel applikation som övervakar användarplatsen och skickar ett meddelande när användaren går in eller lämnar ett geofenced-område. Appen består av endast en Aktivitet och en IntentService. Vi tar också en snabb titt på Google karta, GoogleApiClient, och FusedLocationProviderApi, och vi undersöker några grunder för geofence API.

Steg 1: Projektinställningar

GeofencingApi ingår i Google Play Services. För att komma åt det måste du korrekt konfigurera din utvecklingsmiljö och skapa en instans av GoogleApiClient. Skapa ett nytt projekt med ett tomt Aktivitet, redigera projektets build.gradle filen som visas nedan och synkronisera ditt projekt.

Steg 2: Tillstånd

Vi måste ange rätt behörigheter för att skapa och använda geofences. Lägg till följande tillstånd för projektets manifest:

Från och med Android 6.0 ber appen om tillstånd vid körning och inte under installationen. Vi tar itu med detta senare i handledningen.

Steg 3: Skapa layout

Projektet består av en layout, the MainActity layout. Den innehåller enhetens nuvarande latitud och longitud, och a Google karta fragment som visar geofences och användarens position.

Eftersom activity_main.xml är ganska enkelt, jag vill bara koncentrera mig på MapFragment element. Du kan titta på den färdiga layouten i källfilerna i denna handledning.

 

Steg 4: API-nyckel för Google Maps

Eftersom vi använder en MapFragment, Vi måste konfigurera och initiera en Google karta exempel. Först måste du skaffa en API-nyckel. När du har en API-nyckel lägger du till den i projektets manifest.

Låt oss börja med Google karta exempel. Genomföra GoogleMap.OnMapReadyCallbackGoogleMap.OnMapClickListener, och GoogleMap.OnMarkerClickListenerAktivitet klass och initiera kartan.

public class MainActivity utökar AppCompatActivity implementerar OnMapReadyCallback, GoogleMap.OnMapClickListener, GoogleMap.OnMarkerClickListener privat statisk slutsträng TAG = MainActivity.class.getSimpleName (); privat TextView textLat, textLong; privat MapFragment mapFragment; privat GoogleMap-karta @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); textLat = (TextView) findViewById (R.id.lat); textLong = (TextView) findViewById (R.id.lon); // initiera GoogleMaps initGMaps ();  // Initiera GoogleMaps private void initGMaps () mapFragment = (MapFragment) getFragmentManager (). FindFragmentById (R.id.map); mapFragment.getMapAsync (detta);  // Återuppringning som heter när Map är klar @ Överför offentligt tomrum onMapReady (GoogleMap googleMap) Log.d (TAG, "onMapReady ()"); map = googleMap; map.setOnMapClickListener (detta); map.setOnMarkerClickListener (detta);  // Återuppringning som heter när kartan berörs @ Överför allmän tomrum påMapClick (LatLng latLng) Log.d (TAG, "onMapClick (" + latLng + ")");  // Återuppringning kallad när Markör är rörd @ Överför allmän boolean onMarkerClick (Marker-markör) Log.d (TAG, "onMarkerClickListener:" + marker.getPosition ()); returnera false; 

Steg 5: GoogleApiClient

Att använda GeofencingApi gränssnitt, vi behöver en GoogleApiClient inkörsport. Låt oss genomföra en GoogleApiClient.ConnectionCallbacks och a GoogleApiClient.OnConnectionFailedListenerAktivitet enligt nedanstående.

public class MainActivity utökar AppCompatActivity implementerar GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, OnMapReadyCallback, GoogleMap.OnMapClickListener, GoogleMap.OnMarkerClickListener // ... privat GoogleApiClient googleApiClient; @Override protected void onCreate (Bundle savedInstanceState) // ... // skapa GoogleApiClient createGoogleApi ();  // Skapa GoogleApiClient-instans privat tomt skapaGoogleApi () Log.d (TAG, "createGoogleApi ()"); om (googleApiClient == null) googleApiClient = nya GoogleApiClient.Builder (detta) .addConnectionCallbacks (this) .addOnConnectionFailedListener (this) .addApi (LocationServices.API) .build ();  @Override protected void onStart () super.onStart (); // Ring GoogleApiClient-anslutning när du startar aktiviteten googleApiClient.connect ();  @Override protected void onStop () super.onStop (); // Avbryt GoogleApiClient när du stoppar aktiviteten googleApiClient.disconnect ();  // GoogleApiClient.ConnectionCallbacks connected @Override public void onConnected (@Nullable Bundle Bundle) Log.i (TAG, "onConnected ()");  // GoogleApiClient.ConnectionCallbacks suspenderad @Override public void onConnectionSuspended (int i) Log.w (TAG, "onConnectionSuspended ()");  // GoogleApiClient.OnConnectionFailedListener misslyckas @Override public void onConnectionFailed (@NonNull ConnectionResult connectionResult) Log.w (TAG, "onConnectionFailed ()");  

Steg 6: FusedLocationProviderApi

Vi behöver också komma åt användarens nuvarande plats. De FusedLocationProviderApi gränssnitt ger oss den här informationen och möjliggör en stor kontrollnivå av platsförfrågan. Detta är mycket viktigt, med tanke på att platsförfrågningar har en direkt effekt över enhetens batteriförbrukning.

Nu, låt oss genomföra en LocationListener. Kontrollera om användaren gav programmet rätt behörighet genom att skapa Plats begära och visa deras aktuella plats på skärmen.

public class MainActivity utökar AppCompatActivity implementerar // ... LocationListener privat plats lastLocation; // ... // GoogleApiClient.ConnectionCallbacks connected @Override public void onConnected (@Nullable Bundle Bundle) Log.i (TAG, "onConnected ()"); getLastKnownLocation ();  // Få senaste kända platsen privat void getLastKnownLocation () Log.d (TAG, "getLastKnownLocation ()"); om (checkPermission ()) lastLocation = LocationServices.FusedLocationApi.getLastLocation (googleApiClient); om lastLocation! = null) Log.i (TAG, "LasKnown location." + "Lång:" + lastLocation.getLongitude () + "| Lat:" + lastLocation.getLatitude ()); writeLastLocation (); startLocationUpdates ();  else Log.w (TAG, "Ingen plats hämtad än"); startLocationUpdates ();  else askPermission ();  Privat LocationRequest LocationRequest; // Definierad i mili sekunder. // Detta nummer är extremt lågt och bör endast användas för debug privat slutlig int UPDATE_INTERVAL = 1000; privat slutlig int FASTEST_INTERVAL = 900; // Starta plats Uppdateringar privat tomt startLocationUpdates () Log.i (TAG, "startLocationUpdates ()"); locationRequest = LocationRequest.create () .setPriority (LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval (UPDATE_INTERVAL) .setFastestInterval (FASTEST_INTERVAL); om (checkPermission ()) LocationServices.FusedLocationApi.requestLocationUpdates (googleApiClient, locationRequest, this);  @Override public void onLocationChanged (Platsplats) Log.d (TAG, "onLocationChanged [" + location + "]"); lastLocation = location; writeActualLocation (plats);  // Skriv placeringskoordinater på användargränssnittet privat void writeActualLocation (Platsplats) textLat.setText ("Lat:" + location.getLatitude ()); textLong.setText ("Long:" + location.getLongitude ());  privat tomt writeLastLocation () writeActualLocation (lastLocation);  // Sök efter behörighet att komma åt Lokal privat booleansk checkPermission () Log.d (TAG, "checkPermission ()"); // Begär om tillåtelse om det inte beviljades än återvända (ContextCompat.checkSelfPermission (detta, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);  // Fråga om tillstånd privat tomt frågaPermission () Log.d (TAG, "askPermission ()"); ActivityCompat.requestPermissions (den här nya strängen [] Manifest.permission.ACCESS_FINE_LOCATION, REQ_PERMISSION);  // Verifiera användarens svar på det begärda tillståndet @ Överför offentligt ogiltigt onRequestPermissionsResult (int requestCode, @NonNull String [] behörigheter, @NonNull int [] grantResults) Log.d (TAG, "onRequestPermissionsResult ()"); super.onRequestPermissionsResult (requestCode, permissions, grantResults); switch (requestCode) fall REQ_PERMISSION: if (grantResults.length> 0 && grantResults [0] == PackageManager.PERMISSION_GRANTED) // Tillstånd beviljat getLastKnownLocation ();  else // Tillstånd nekade rättigheterDenied ();  ha sönder;  // App kan inte fungera utan behörigheterna privata tomt tillståndDenied () Log.w (TAG, "permissionsDenied ()"); 

Det är viktigt att ta itu med det Location skapade ovan är inte optimerad för en produktionsmiljö. De UPPDATERINGSINTERVALL är för kort och skulle förbruka för mycket batteriström. En mer realistisk konfiguration för produktion kan vara:

privat slutlig int UPDATE_INTERVAL = 3 * 60 * 1000; // 3 minuter privat slutlig int FASTEST_INTERVAL = 30 * 1000; // 30 sekunder privata tomt startLocationUpdates () Log.i (TAG, "startLocationUpdates ()"); locationRequest = LocationRequest.create () .setPriority (LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval (UPDATE_INTERVAL) .setFastestInterval (FASTEST_INTERVAL); om (checkPermission ()) LocationServices.FusedLocationApi.requestLocationUpdates (googleApiClient, locationRequest, this); 

Steg 7: GoogleMap Markers

Vår Aktivitet behöver två olika markörer. en locationMarker använder latitud och longitud som ges av FusedLocationProviderApi för att informera enhetens aktuella plats. en geoFenceMarker är målet för skapandet av geofence eftersom det använder den sista handen som visas på kartan för att hämta sin position.

@Override public void onMapClick (LatLng latLng) Log.d (TAG, "onMapClick (" + latLng + ")"); markerForGeofence (latLng);  privat tomt writeActualLocation (plats plats) // ... markörLocation (new LatLng (location.getLatitude (), location.getLongitude ()));  Privat Markör LocationMarker; // Skapa en platsmarkör privat tommarkeringsplats (LatLng latLng) Log.i (TAG, "markerLocation (" + latLng + ")"); String title = latLng.latitude + "," + latLng.longitude; MarkerOptions markerOptions = new MarkerOptions () .position (latLng) .title (title); om (map! = null) // Ta bort den främre markören om (locationMarker! = null) locationMarker.remove (); locationMarker = map.addMarker (markerOptions); float zoom = 14f; CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom (latLng, zoom); map.animateCamera (cameraUpdate);  privatmarkör geoFenceMarker; // Skapa en markör för geofence skapandet privat tomt markörFörGeofence (LatLng latLng) Log.i (TAG, "markerForGeofence (" + latLng + ")"); String title = latLng.latitude + "," + latLng.longitude; // Definiera markeringsalternativ MarkerOptions markörOptions = nya MarkerOptions () .position (latLng) .icon (BitmapDescriptorFactory.defaultMarker (BitmapDescriptorFactory.HUE_ORANGE)) .title (title); om (map! = null) // Ta bort senaste geoFenceMarker om (geoFenceMarker! = null) geoFenceMarker.remove (); geoFenceMarker = map.addMarker (markerOptions); 

Steg 8: Skapa en Geofence

Äntligen är det dags att skapa en geofence. Vi använder geoFenceMarker som mittpunkten för geofensen.

privat statisk slutlig lång GEO_DURATION = 60 * 60 * 1000; privat statisk slutsträng GEOFENCE_REQ_ID = "My Geofence"; privat statisk slutflotta GEOFENCE_RADIUS = 500.0f; // i meter // Skapa en Geofence privat Geofence createGeofence (LatLng latLng, floatradie) Log.d (TAG, "createGeofence"); returnera ny Geofence.Builder () .setRequestId (GEOFENCE_REQ_ID) .setCircularRegion (latlng.latitude, latlng.longitude, radius) .setExpirationDuration (GEO_DURATION) .setTransitionTypes (Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) .build (); 

Därefter skapar vi GeofencingRequest objekt.

// Skapa en Geofence Begär privat GeofencingRequest createGeofenceRequest (Geofence geofence) Log.d (TAG, "createGeofenceRequest"); returnera nya GeofencingRequest.Builder () .setInitialTrigger (GeofencingRequest.INITIAL_TRIGGER_ENTER) .addGeofence (geofence) .build (); 

Vi använder en PendingIntent motsätta sig att ringa a IntentService som kommer att hantera GeofenceEvent. Vi skapar GeofenceTrasitionService.class senare.

privat PendingIntent geoFencePendingIntent; privat slutligt int GEOFENCE_REQ_CODE = 0; privat PendingIntent createGeofencePendingIntent () Log.d (TAG, "createGeofencePendingIntent"); om (geoFencePendingIntent! = null) returnera geoFencePendingIntent; Avsikten med avsikt = ny Intent (detta, GeofenceTrasitionService.class); returnera PendingIntent.getService (detta, GEOFENCE_REQ_CODE, avsikten, PendingIntent.FLAG_UPDATE_CURRENT);  // Lägg till den skapade GeofenceRequest till enhetens övervakningslista privat void addGeofence (GeofencingRequest request) Log.d (TAG, "addGeofence"); om (checkPermission ()) LocationServices.GeofencingApi.addGeofences (googleApiClient, request, createGeofencePendingIntent ()) .setResultCallback (detta); 

Vi ritar också geofensen på kartan som en visuell referens.

@Override public void onResult (@NonNull Status status) Log.i (TAG, "onResult:" + status); om (status.isSuccess ()) drawGeofence ();  annat // informera om misslyckas // Dra Geofence-cirkeln på GoogleMap Private Circle geoFenceLimits; privat tomt drawGeofence () Log.d (TAG, "drawGeofence ()"); om (geoFenceLimits! = null) geoFenceLimits.remove (); CircleOptions circleOptions = new CircleOptions () .center (geoFenceMarker.getPosition ()) .strokeColor (Color.argb (50, 70,70,70)) .fillColor (Color.argb (100, 150, 150, 150)) .radio (GEOFENCE_RADIUS); geoFenceLimits = map.addCircle (circleOptions); 

De startGeofence () Metoden är ansvarig för att starta geofencingprocessen i Huvudaktivitet klass.

 @Override public boolean onOptionsItemSelected (MenuItem item) switch (item.getItemId ()) fall R.id.geofence: startGeofence (); återvänd sant;  returnera super.onOptionsItemSelected (item);  // Starta Geofence skapande processen privat void startGeofence () Log.i (TAG, "startGeofence ()"); om (geoFenceMarker! = null) Geofence geofence = createGeofence (geoFenceMarker.getPosition (), GEOFENCE_RADIUS); GeofencingRequest geofenceRequest = createGeofenceRequest (geofence); addGeofence (geofenceRequest);  else Log.e (TAG, "Geofence marker är null"); 

Steg 9: Geofence Transition Service

Vi kan nu äntligen skapa GeofenceTrasitionService.class nämnde tidigare. Denna klass sträcker sig IntentService och ansvarar för hanteringen av GeofencingEvent. Först får vi den här händelsen från den mottagna avsikten.

GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent (avsikt);

Vi kontrollerar då om den typ av geofencingövergång som ägde rum är av intresse för oss. Om så är fallet hämtar vi en lista över de utlösta geoferna och skapar en anmälan med lämpliga åtgärder.

// Hämta GeofenceTrasition int geoFenceTransition = geofencingEvent.getGeofenceTransition (); // Kontrollera om övergångstypen om (geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) // Få geofence som utlösts List triggeringGeofences = geofencingEvent.getTriggeringGeofences (); // Skapa ett detaljmeddelande med Geofences mottagna String geofenceTransitionDetails = getGeofenceTrasitionDetails (geoFenceTransition, triggeringGeofences); // Skicka meddelandeinformation som en sträng sendNotifikation (geofenceTransitionDetails); 

Jag har också implementerat några hjälpar metoder för att göra genomförandet av klassen lättare att förstå.

offentlig klass GeofenceTrasitionService utökar IntentService privat statisk slutsträng TAG = GeofenceTrasitionService.class.getSimpleName (); offentlig statisk slutlig int GEOFENCE_NOTIFICATION_ID = 0; offentlig GeofenceTrasitionService () super (TAG);  @Override protected void onHandleIntent (Intent intention) // Hämta Geofencing-avsikt GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent (avsikt); // Hantera fel om (geofencingEvent.hasError ()) String errorMsg = getErrorString (geofencingEvent.getErrorCode ()); Log.e (TAG, errorMsg); lämna tillbaka;  // Hämta GeofenceTrasition int geoFenceTransition = geofencingEvent.getGeofenceTransition (); // Kontrollera om övergångstypen om (geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) // Få geofence som utlösts List triggeringGeofences = geofencingEvent.getTriggeringGeofences (); // Skapa ett detaljmeddelande med Geofences mottagna String geofenceTransitionDetails = getGeofenceTrasitionDetails (geoFenceTransition, triggeringGeofences); // Skicka meddelandeinformation som en sträng sendNotifikation (geofenceTransitionDetails);  // Skapa ett detaljmeddelande med Geofences mottagna privata String getGeofenceTrasitionDetails (int geoFenceTransition, List triggeringGeofences) // få ID för varje geofence utlöst ArrayList triggeringGeofencesList = ny ArrayList <> (); för (Geofence geofence: triggeringGeofences) triggeringGeofencesList.add (geofence.getRequestId ());  Stringstatus = null; om (geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER) status = "Entering"; annars om (geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) status = "Exiting"; returnera status + TextUtils.join (",", triggeringGeofencesList);  // Skicka ett meddelande privat tomt sendNotification (String msg) Log.i (TAG, "sendNotification:" + msg); // Intent att starta den huvudsakliga aktivitetsintentionen notificationIntent = MainActivity.makeNotificationIntent (getApplicationContext (), msg); TaskStackBuilder stackBuilder = TaskStackBuilder.create (detta); stackBuilder.addParentStack (MainActivity.class); stackBuilder.addNextIntent (notificationIntent); PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent (0, PendingIntent.FLAG_UPDATE_CURRENT); // Skapa och skicka Notification NotificationManager notificatioMng = (NotificationManager) getSystemService (Context.NOTIFICATION_SERVICE); notifiering.notify (GEOFENCE_NOTIFICATION_ID, createNotification (msg, notificationPendingIntent));  // Skapa ett meddelande privat Meddelande createNotification (String msg, PendingIntent notificationPendingIntent) NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder (this); notificationBuilder .setSmallIcon (R.drawable.ic_action_location) .setColor (Color.RED) .setContentTitle (msg) .setContentText ("Geofence Notification!") .setContentIntent (notificationPendingIntent) .setDefaults (Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND ) .setAutoCancel (true); returnera notificationBuilder.build ();  // Hantera fel privat statisk String getErrorString (int errorCode) switch (errorCode) fall GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE: returnera "GeoFence inte tillgänglig"; fall GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES: returnera "För många GeoFences"; fall GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS: returnera "För många väntar intentioner"; standard: returnera "Okänt fel."; 

3. Testning

Testa på en virtuell enhet

Det är mycket enklare att testa geofencing på en virtuell enhet. Det finns flera sätt att göra detta. I Android Studio öppnar du en virtuell enhet och klickar på fler alternativknappar längst ner till höger.

Plats fliken till vänster, ange koordinaterna för platsen.

Jag föredrar att använda telnet kommandon för att styra den virtuella enheten. För att kunna använda det måste du ansluta till enheten från kommandoraden med följande kommando:

telnet localhost [DEVICE_PORT]

Enhetsporten visas i fönstret virtuellt enhet. Enhetsporten är vanligen lika med 5554.

Det är möjligt att du måste godkänna den här anslutningen med din auth_token, men kommandoraden visar dig var den ligger. Navigera till den platsen och kopiera token och typ, auth [YOUR_AUTH_TOKEN].

Du kan nu ange platsen för enheten genom att köra följande kommando:

geo fix [LATITUDE] [LONGITUDE]

Slutsats

Geofencing kan vara ett utmärkt komplement till din app eftersom det kan öka användarnas engagemang avsevärt. Det finns massor av möjligheter att utforska och du kan till och med skapa en sofistikerad erfarenhet med hjälp av inomhusfyrar, såsom Estimote. Med inomhusväggar vet du exakt var användaren har passerat, till exempel ett köpcentrum.

Att lägga Geofencing till ett projekt är enkelt, men vi måste hålla strömförbrukningen i åtanke hela tiden. Det betyder att vi måste noggrant välja storlek på geofence och uppdateringshastighet eftersom både direkt påverkar strömförbrukningen i din applikation.

Testning är därför väldigt viktigt för att få en realistisk bild av energiförbrukningen i din ansökan. Också överväga att ge användarna möjlighet att inaktivera geofencing helt och hållet om de inte vill ha eller behöver den här funktionen.