Es posible que los casos de uso de su aplicación no requieran una supervisión de región activa. El servicio de Places aún se puede usar para integrar los datos de ubicación de los usuarios con otros productos de Experience Platform.
El desarrollador recopilará la ubicación del dispositivo mediante las API proporcionadas por el sistema operativo de la plataforma de destino.
Si los casos de uso de la aplicación requieren una supervisión de región activa, consulte Utilice Places Service con su propia solución de monitorización.
Para utilizar el servicio Places sin supervisión de región activa:
El desarrollador de la aplicación debe recopilar la ubicación actual del dispositivo utilizando la variable CoreLocation.framework
(iOS) o Location
API proporcionadas por los servicios de Google Play (Android).
Para obtener más información, consulte la siguiente documentación:
Una vez que obtenga la ubicación del usuario, puede pasarla al SDK para obtener una lista de los puntos de interés cercanos.
Esta es una implementación de ejemplo en Android que usa una BroadcastReceiver
:
public class LocationBroadcastReceiver extends BroadcastReceiver {
static final String ACTION_LOCATION_UPDATE = "locationUpdate";
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null || context == null) {
return;
}
final String action = intent.getAction();
if (!ACTION_LOCATION_UPDATE.equals(action)) {
return;
}
LocationResult result = LocationResult.extractResult(intent);
if (result == null) {
return;
}
Location currentLocation = result.getLastLocation();
if (currentLocation == null) {
return;
}
// ask the Places SDK for the 10 nearest Points of Interest based on the user's location
Places.getNearbyPointsOfInterest(currentLocation, 10,
new AdobeCallback<List<PlacesPOI>>() {
@Override
public void call(List<PlacesPOI> pois) {
// pois is the 10 nearest POIs based on the location
}
}, new AdobeCallback<PlacesRequestError>() {
@Override
public void call(PlacesRequestError placesRequestError) {
// Look for the placesRequestError and handle the error accordingly
}
}
);
}
}
Esta es una implementación de muestra para iOS. El código muestra la implementación de la variable locationManager:didUpdateLocations:
en el CLLocationManagerDelegate
:
- (void) locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray<CLLocation*>*)locations {
// ask the Places SDK for the 10 nearest Points of Interest based on the user's location
[ACPPlaces getNearbyPointsOfInterest:[locations lastObject] limit:10 callback:^(NSArray<ACPPlacesPoi *> * _Nullable nearbyPoi) {
// nearbyPoi is the 10 nearest POIs based on the location
} errorCallback:^(ACPPlacesRequestError result) {
// log the error if we got one
NSLog(@"error: %lu", (unsigned long)result);
}];
}
Esta es una implementación de muestra para iOS. El código muestra la implementación de la variable locationManager(_:didUpdateLocations:)
en el CLLocationManagerDelegate
:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// ask the Places SDK for the 10 nearest Points of Interest based on the user's location
ACPPlaces.getNearbyPoints(ofInterest: locations.last!, limit: 10, callback: { (nearbyPoi) in
// nearbyPoi is the 10 nearest POIs based on the location
}) { (error) in
// log the error if we have one
print("error: \(error)")
}
}
Llamando a la función getNearbyPointsOfInterest
, el SDK de Places hará que todos los datos de puntos de interés relevantes para el dispositivo estén disponibles a través de elementos de datos en Launch. Mediante una Adjuntar datos , los datos de Places se pueden añadir automáticamente a futuras solicitudes a Analytics. Esto elimina la necesidad de realizar una llamada única a Analytics en el momento en que se recopila la ubicación del dispositivo.
Consulte Agregar contexto de ubicación a solicitudes de Analytics para obtener más información sobre este tema.
La forma recomendada de capturar los datos de Places es Adjuntar datos de Places a sus solicitudes de Analytics.
Si el caso de uso requiere un evento de entrada de región para que el SDK lo active, deberá hacerlo manualmente como se describe a continuación.
La lista devuelta por el getNearbyPointsOfInterest
La API contiene objetos personalizados que indican si el usuario se encuentra actualmente dentro de un punto de interés. Si el usuario está en un punto de interés, puede hacer que el déclencheur del SDK sea un evento de entrada para esa región.
Para evitar que la aplicación active varios eventos de entrada en una visita, mantenga una lista de las regiones en las que sabe que el usuario ha entrado. Al procesar la respuesta de puntos de interés cercanos desde el SDK, se genera un déclencheur de un evento de entrada solo cuando la región no está en la lista.
En el siguiente ejemplo de código, NSUserDefaults
(iOS) y SharedPreferences
(Android) se utilizan para administrar la lista de regiones:
El siguiente ejemplo de código muestra la gestión del resultado que se proporcionó en la llamada de retorno de getNearbyPointsOfInterest
, List<PlacesPOI>
:
void handleUpdatedPOIs(final List<PlacesPOI> nearbyPois) {
// get the list of regions we know the user is already within from SharedPreferences
SharedPreferences preferences = getApplicationContext().getSharedPreferences("places", 0);
Set<String> regionsUserIsAlreadyIn = preferences.getStringSet("regionsUserIsAlreadyIn", new HashSet<String>());
// loop through new placesPOIS and post entry events for pois that aren't already in our list
// also create the new list of regions that the user is in
Set<String> updatedRegionsUserIsIn = new HashSet<String>();
for (PlacesPOI poi : nearbyPois) {
// check if the user is in this poi
if (poi.containsUser()) {
// the user is in the poi, now we need to make sure we haven't already recorded this entry event
if (!regionsUserIsAlreadyIn.contains(poi.getIdentifier())) {
Geofence poiGeofence = new Geofence.Builder()
.setRequestId(poi.getIdentifier())
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setCircularRegion(poi.getLatitude(), poi.getLongitude(), poi.getRadius())
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
Places.processGeofence(poiGeofence, Geofence.GEOFENCE_TRANSITION_ENTER);
}
// add the region to our new list of regions
updatedRegionsUserIsIn.add(poi.getIdentifier());
}
}
// update SharedPreferences with our new list of regions
SharedPreferences.Editor editor = getApplicationContext().getSharedPreferences("places", 0).edit();
editor.putStringSet("regionsUserIsAlreadyIn", updatedRegionsUserIsIn).apply();
}
El siguiente ejemplo de código muestra la gestión del resultado que se proporcionó en la llamada de retorno de getNearbyPointsOfInterest:limit:callback:errorCallback:
, un NSArray<ACPPlacesPoi *> *
:
- (void) handleUpdatedPOIs:(NSArray<ACPPlacesPoi *> *)nearbyPois {
// get the list of regions we know the user is already within from user defaults
NSArray *regionsUserIsCurrentlyWithin = [[NSUserDefaults standardUserDefaults]
arrayForKey:@"regionsUserIsAlreadyIn"];
// loop through new nearbyPoi and post entry events for pois that aren't already in our list
// also creating the new list of known regions that the user is in
NSMutableArray *updatedRegionsUserIsCurrentlyWithin = [@[] mutableCopy];
for (ACPPlacesPoi *poi in nearbyPois) {
// check if the user is in this poi
if (poi.userIsWithin) {
// the user is in the poi, now we need to make sure we haven't already recorded the entry event
if (![regionsUserIsCurrentlyWithin containsObject:poi.identifier]) {
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(poi.latitude, poi.longitude)
radius:poi.radius
identifier:poi.identifier];
[ACPPlaces processRegionEvent:region forRegionEventType:ACPRegionEventTypeEntry];
}
// add the region to our updated list
[updatedRegionsUserIsCurrentlyWithin addObject:poi.identifier];
}
}
// update user defaults with the new list
[[NSUserDefaults standardUserDefaults] setObject:updatedRegionsUserIsCurrentlyWithin forKey:@"regionsUserIsAlreadyIn"];
}
El siguiente ejemplo de código muestra la gestión del resultado que se proporcionó en la llamada de retorno de getNearbyPoints(_ ofInterest: CLLocation, limit: UInt, callback: (([ACPPlacesPoi]?) -> Void)?, errorCallback: ((ACPPlacesRequestError) -> Void)?)
, un [ACPPlacesPoi]
:
func handleUpdatedPOIs(_ nearbyPois:[ACPPlacesPoi]) {
// get the list of regions we know the user is already within from user defaults
let regionsUserIsCurrentlyWithin : [String] = UserDefaults.standard.array(forKey: "regionsUserIsAlreadyIn") as! [String]
// loop through new nearbyPoi and post entry events for pois that aren't already in our list
// also creating the new list of known regions that the user is in
var updatedRegionsUserIsCurrentlyWithin: [String] = []
for poi in nearbyPois {
// check if the user is in this poi
if poi.userIsWithin {
// the user is in the poi, now we need to make sure we haven't already recorded the entry event
if !regionsUserIsCurrentlyWithin.contains(poi.identifier!) {
let region = CLCircularRegion.init(center: CLLocationCoordinate2D.init(latitude: poi.latitude, longitude: poi.longitude), radius: CLLocationDistance(poi.radius), identifier: poi.identifier!)
ACPPlaces.processRegionEvent(region, for: .entry)
}
// add the region to our updated list
updatedRegionsUserIsCurrentlyWithin.append(poi.identifier!)
}
}
// update user defaults with the new list
UserDefaults.standard.set(updatedRegionsUserIsCurrentlyWithin, forKey: "regionsUserIsAlreadyIn")
}
Los ejemplos de código siguientes muestran cómo recuperar la ubicación actual del dispositivo, almacenar en déclencheur los eventos de entrada necesarios y asegurarse de que no se obtienen varias entradas para la misma ubicación en una visita.
Este ejemplo de código incluye el paso opcional de desencadenar eventos de entrada cuando el usuario está en un punto de interés.
Estos fragmentos son only ejemplos. Los desarrolladores deben determinar cómo desean implementar la funcionalidad y la decisión debe tener en cuenta las prácticas recomendadas recomendadas por el sistema operativo de destino.
public class LocationBroadcastReceiver extends BroadcastReceiver {
static final String ACTION_LOCATION_UPDATE = "locationUpdate";
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null || context == null) {
return;
}
final String action = intent.getAction();
if (!ACTION_LOCATION_UPDATE.equals(action)) {
return;
}
LocationResult result = LocationResult.extractResult(intent);
if (result == null) {
return;
}
Location currentLocation = result.getLastLocation();
if (currentLocation == null) {
return;
}
// ask the Places SDK for the 10 nearest Points of Interest based on the user's location
Places.getNearbyPointsOfInterest(currentLocation, 10,
new AdobeCallback<List<PlacesPOI>>() {
@Override
public void call(List<PlacesPOI> pois) {
// pois is the 10 nearest POIs based on the location
handleUpdatedPOIs(pois);
}
}, new AdobeCallback<PlacesRequestError>() {
@Override
public void call(PlacesRequestError placesRequestError) {
// Look for the placesRequestError and handle the error accordingly
}
}
);
}
void handleUpdatedPOIs(final List<PlacesPOI> nearbyPois) {
// get the list of regions we know the user is already within from SharedPreferences
SharedPreferences preferences = getApplicationContext().getSharedPreferences("places", 0);
Set<String> regionsUserIsAlreadyIn = preferences.getStringSet("regionsUserIsAlreadyIn", new HashSet<String>());
// loop through new placesPOIS and post entry events for pois that aren't already in our list
// also create the new list of regions that the user is in
Set<String> updatedRegionsUserIsIn = new HashSet<String>();
for (PlacesPOI poi : nearbyPois) {
// check if the user is in this poi
if (poi.containsUser()) {
// the user is in the poi, now we need to make sure we haven't already recorded this entry event
if (!regionsUserIsAlreadyIn.contains(poi.getIdentifier())) {
Geofence poiGeofence = new Geofence.Builder()
.setRequestId(poi.getIdentifier())
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setCircularRegion(poi.getLatitude(), poi.getLongitude(), poi.getRadius())
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
Places.processGeofence(poiGeofence, Geofence.GEOFENCE_TRANSITION_ENTER);
}
// add the region to our new list of regions
updatedRegionsUserIsIn.add(poi.getIdentifier());
}
}
// update SharedPreferences with our new list of regions
SharedPreferences.Editor editor = getApplicationContext().getSharedPreferences("places", 0).edit();
editor.putStringSet("regionsUserIsAlreadyIn", updatedRegionsUserIsIn).apply();
}
}
- (void) locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray<CLLocation*>*)locations {
// ask the Places SDK for the 10 nearest Points of Interest based on the user's location
[ACPPlaces getNearbyPointsOfInterest:[locations lastObject] limit:10 callback:^(NSArray<ACPPlacesPoi *> * _Nullable nearbyPoi) {
// nearbyPoi is the 10 nearest POIs based on the location
[self handleUpdatedPOIs:nearbyPoi];
} errorCallback:^(ACPPlacesRequestError result) {
// log the error if we got one
NSLog(@"error: %lu", (unsigned long)result);
}];
}
- (void) handleUpdatedPOIs:(NSArray<ACPPlacesPoi *> *)nearbyPois {
// get the list of regions we know the user is already within from user defaults
NSArray *regionsUserIsCurrentlyWithin = [[NSUserDefaults standardUserDefaults]
arrayForKey:@"regionsUserIsAlreadyIn"];
// loop through new nearbyPoi and post entry events for pois that aren't already in our list
// also creating the new list of known regions that the user is in
NSMutableArray *updatedRegionsUserIsCurrentlyWithin = [@[] mutableCopy];
for (ACPPlacesPoi *poi in nearbyPois) {
// check if the user is in this poi
if (poi.userIsWithin) {
// the user is in the poi, now we need to make sure we haven't already recorded the entry event
if (![regionsUserIsCurrentlyWithin containsObject:poi.identifier]) {
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(poi.latitude, poi.longitude)
radius:poi.radius
identifier:poi.identifier];
[ACPPlaces processRegionEvent:region forRegionEventType:ACPRegionEventTypeEntry];
}
// add the region to our updated list
[updatedRegionsUserIsCurrentlyWithin addObject:poi.identifier];
}
}
// update user defaults with the new list
[[NSUserDefaults standardUserDefaults] setObject:updatedRegionsUserIsCurrentlyWithin forKey:@"regionsUserIsAlreadyIn"];
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// ask the Places SDK for the 10 nearest Points of Interest based on the user's location
ACPPlaces.getNearbyPoints(ofInterest: locations.last!, limit: 10, callback: { (nearbyPoi) in
// nearbyPoi is the 10 nearest POIs based on the location
self.handleUpdatedPOIs(nearbyPoi!)
}) { (error) in
// log the error if we have one
print("error: \(error)")
}
}
func handleUpdatedPOIs(_ nearbyPois:[ACPPlacesPoi]) {
// get the list of regions we know the user is already within from user defaults
let regionsUserIsCurrentlyWithin : [String] = UserDefaults.standard.array(forKey: "regionsUserIsAlreadyIn") as! [String]
// loop through new nearbyPoi and post entry events for pois that aren't already in our list
// also creating the new list of known regions that the user is in
var updatedRegionsUserIsCurrentlyWithin: [String] = []
for poi in nearbyPois {
// check if the user is in this poi
if poi.userIsWithin {
// the user is in the poi, now we need to make sure we haven't already recorded the entry event
if !regionsUserIsCurrentlyWithin.contains(poi.identifier!) {
let region = CLCircularRegion.init(center: CLLocationCoordinate2D.init(latitude: poi.latitude, longitude: poi.longitude), radius: CLLocationDistance(poi.radius), identifier: poi.identifier!)
ACPPlaces.processRegionEvent(region, for: .entry)
}
// add the region to our updated list
updatedRegionsUserIsCurrentlyWithin.append(poi.identifier!)
}
}
// update user defaults with the new list
UserDefaults.standard.set(updatedRegionsUserIsCurrentlyWithin, forKey: "regionsUserIsAlreadyIn")
}
Además de activar eventos de entrada del servicio Places en el SDK, debido a los eventos de entrada de activación, el resto del SDK puede utilizar todos los datos que definen sus puntos de interés mediante data elements
en Experience Platform Launch. Con Experience Platform Launch rules
, puede adjuntar dinámicamente los datos del servicio de Places a los eventos entrantes que procese el SDK. Por ejemplo, puede adjuntar los metadatos de un punto de interés en el que se encuentra el usuario y enviar los datos a Analytics como datos de contexto.
Para obtener más información, consulte Uso del servicio Places con otras soluciones de Adobe.