활성 지역 모니터링 없이 장소 서비스 사용 use-places-without-active-monitoring
응용 프로그램에 대한 사용 사례는 활성 지역 모니터링이 필요하지 않을 수 있습니다. Places Service를 사용하여 사용자의 위치 데이터를 다른 Experience Platform 제품과 통합할 수 있습니다.
전제 조건
개발자는 대상 플랫폼의 운영 체제에서 제공하는 API를 사용하여 장치의 위치를 수집합니다.
활성 지역 모니터링 없이 위치 서비스를 사용하려면
1. 사용자의 위치 수집
앱 개발자는 다음을 사용하여 장치의 현재 위치를 수집해야 합니다. CoreLocation.framework
(iOS) 또는 Location
Google Play 서비스(Android)에서 제공하는 API입니다.
자세한 내용은 다음 설명서를 참조하십시오.
- CoreLocation (Apple)
- Google Play 서비스의 위치 API (Google)
2. SDK에서 가까운 관심 영역 가져오기
사용자의 위치를 가져온 후 SDK에 전달하여 근처 POI 목록을 다시 가져올 수 있습니다.
Android
다음은 를 사용하는 Android의 샘플 구현입니다 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
}
}
);
}
}
Objective-C
다음은 iOS에 대한 샘플 구현입니다. 이 코드는 의 구현을 보여 줍니다. locationManager:didUpdateLocations:
의 메서드 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);
}];
}
Swift
다음은 iOS에 대한 샘플 구현입니다. 이 코드는 의 구현을 보여 줍니다. locationManager(_:didUpdateLocations:)
의 메서드 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)")
}
}
3. Analytics 요청에 위치 데이터 첨부
를 호출하여 getNearbyPointsOfInterest
API를 사용하면 위치 SDK는 Launch의 데이터 요소를 통해 사용할 수 있도록 모든 POI 데이터를 디바이스에 적절한 것으로 만듭니다. 를 사용하여 데이터 첨부 규칙, 위치 데이터는 Analytics에 대한 향후 요청에 자동으로 추가될 수 있습니다. 이렇게 하면 디바이스 위치가 수집될 때 Analytics에 대한 일회성 호출이 필요 없습니다.
다음을 참조하십시오 Analytics 요청에 위치 컨텍스트 추가 을(를) 참조하십시오.
선택 사항 - 사용자가 POI에 있을 때 항목 이벤트를 트리거합니다.
이(가) 반환한 목록 getNearbyPointsOfInterest
API에 포함된 항목 사용자 지정 개체 사용자가 현재 POI 내에 있는지 보여 줍니다. 사용자가 POI에 있는 경우 SDK에서 해당 지역에 대한 시작 이벤트를 트리거하도록 할 수 있습니다.
NSUserDefaults
(iOS) 및 SharedPreferences
(Android)는 지역 목록을 관리하는 데 사용됩니다.Android
다음 코드 샘플은 콜백에서 제공된 결과의 처리를 보여 줍니다. getNearbyPointsOfInterest
, a 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();
}
Objective-C
다음 코드 샘플은 콜백에서 제공된 결과의 처리를 보여 줍니다. getNearbyPointsOfInterest:limit:callback:errorCallback:
, 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"];
}
Swift
다음 코드 샘플은 콜백에서 제공된 결과의 처리를 보여 줍니다. getNearbyPoints(_ ofInterest: CLLocation, limit: UInt, callback: (([ACPPlacesPoi]?) -> Void)?, errorCallback: ((ACPPlacesRequestError) -> Void)?)
, [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")
}
전체 샘플 구현
아래 코드 샘플은 장치의 현재 위치를 검색하고, 필요한 항목 이벤트를 트리거하고, 한 번의 방문으로 동일한 위치에 대해 여러 항목을 가져오지 않도록 하는 방법을 보여 줍니다.
이 코드 샘플에는 사용자가 POI에 있을 때 항목 이벤트 트리거.
Android
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();
}
}
Objective-C
- (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"];
}
Swift
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")
}
SDK에서 위치 서비스 시작 이벤트를 트리거하는 것 외에도, 트리거하는 시작 이벤트로 인해 POI를 정의하는 모든 데이터를 SDK의 나머지 부분에서 다음을 통해 사용할 수 있습니다. data elements
Experience Platform Launch. Experience Platform Launch rules
, SDK에서 처리하는 수신 이벤트에 위치 서비스 데이터를 동적으로 첨부할 수 있습니다. 예를 들어 사용자가 있는 POI의 메타데이터를 첨부하고 데이터를 Analytics에 컨텍스트 데이터로 보낼 수 있습니다.
자세한 내용은 다른 Adobe 솔루션에서 Places Service 사용.