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.
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
, GeofenceApi
, GeofencingEvent
, och GeofenceStatusCodes
. I denna handledning använder vi dessa klasser för att skapa och arbeta med geofences.
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_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.
PendingResultaddGeofences (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.
PendingResultremoveGeofences (GoogleApiClient-klient, Lista geofenceRequestIds)
PendingResultremoveGeofences (GoogleApiClient-klient, PendingIntent pendingIntent)
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.
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.
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.
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.
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.OnMapReadyCallback
, GoogleMap.OnMapClickListener
, och GoogleMap.OnMarkerClickListener
i Aktivitet
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;
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.OnConnectionFailedListener
i Aktivitet
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 ()");
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);
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);
Ä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");
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 ListtriggeringGeofences = 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 ListtriggeringGeofences = 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.";
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.
I 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]
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.