13 Location
As a mobile app developer, you can use the Oracle Mobile Cloud Service (MCS) Location API to access details about location devices, places and assets that have been registered in MCS.
What Can I Do With Location?
Users today expect information to be presented based on their current situation and individual needs and preferences. One of the most important contextual data points is location. The impact of location-aware mobile apps on users and businesses is growing faster every day.
-
Everyone uses navigation apps for location data, including getting directions to restaurants, airports, hospitals, and just about anything else needed in a geographic area.
-
You can implement location-based functionality in a wide range of apps, like focused queries and location-aware history.
-
Your apps can use location data to send notifications targeted to mobile devices in a geographic area or a certain mobile user or asset only in a specific geographic area.
-
Location-aware applications can also contribute a lot to business intelligence and analytics, including customer profiling and demographics, competitive analysis and supply chain tracking.
This chapter discusses how to use these Location APIs to perform common tasks. For more details on using the platform APIs, see REST APIs for Oracle Mobile Cloud Service.
Setting Up Location Devices, Places and Assets
Location devices, places and assets provide the tools you need to create location-aware mobile apps.
-
A location device is any device that provides location services, like a Bluetooth proximity beacon. The following location protocols are currently supported:
-
AltBeacon is an open source protocol for Bluetooth proximity beacons. For more information and the full specification, see altbeacon.org and https://github.com/AltBeacon/spec.
-
Eddystone is Google’s open protocol for Bluetooth proximity beacons. For details, see https://github.com/google/eddystone.
-
iBeacon is the Apple protocol for Bluetooth proximity beacons. For details, see https://developer.apple.com/ibeacon/.
-
-
A place is a physical location associated with one or more location devices.
-
An asset is a mobile physical object that’s associated with one or more location devices.
To set up a location in MCS, define the related places and/or assets and register the associated location devices in the MCS UI under Applications > Location. You can also use the Location Management API to create, update and delete location devices, places and assets from custom code. For details, see Accessing the Location Management API from Custom Code.
Defining Places
Note:
To manage places in the MCS UI, you need to be assigned theMobileEnvironment_LocationMgmt
MCS team member role in the environment.
- Click to open the side menu and select Applications > Location.
- From the Places tab, click New Place to define a place using the UI. This tab shows all the places defined. To edit an existing place, select it in the list and click Edit .
- If you are creating a new place, enter a name, and an optional label and description. If you enter a new label, it will be saved and can be used to categorize other places, location devices and assets. Click Create.
- On the Overview tab of the new Location Place Editor, enter the GPS coordinates for the place. You can also define a geofence by radius or polygon. To associate the place with another existing place, select that place from the Parent dropdown.
- Click the Attributes tab to define custom attributes for the place. Create new attributes or copy them from an existing place. You can use attributes to associate a content URI with the place, for example a coupon or flier that a mobile app downloads when the user is nearby. Attributes can also be used to filter results in queries that use the Location Platform API.
- Click the Devices tab to associate location devices with the place. You can register a new device from this page (Registering Location Devices) or select from location devices already registered. A device can be associated with a single place or asset, not both. By default, only the devices for the current place are displayed, but you can expand the list by checking the box Show all devices associated with children of this place.
- When you are done configuring the place, click Save.
If a place has descendants, click > at the end of the table row to navigate to them.
Defining Location Assets
Note:
To manage location assets in the MCS UI, you need to be assigned theMobileEnvironment_LocationMgmt
MCS team member role in the environment.
- Click to open the side menu and select Applications > Location.
- From the Assets tab, click New Asset to define a location asset using the UI. This tab shows all the assets defined. To edit an existing asset, select it in the list and click Edit Asset.
- If you are creating a new asset, enter a name, and a label and description if you choose. Labels will be saved and can be used to categorize other location assets. If the device(s) you want to associate with the asset are already registered, you can select them on this page. (A device can be associated with a single place or asset, not both.) Click Create.
- On the Overview tab of the Location Asset Editor, you can update your entries.
- Click the Attributes tab to define custom attributes for the asset. Create new attributes or copy them from an existing asset. You can use attributes to associate a content URI with the asset, for example a coupon or flier that a mobile app downloads when the user is nearby. Attributes can also be used to filter results in queries that use the Location Platform API.
- When you are done configuring the asset, click Save.
Calling the Location API from Your App
Team members with the MobileEnvironment_System
role can use the Location Management REST API to add and maintain places, devices, and assets.
Querying for Location Devices, Places and Assets
The Location API allows you to write complex queries for location devices, places and assets. You can call the REST endpoint directly or use the client SDK to construct a query.
Querying for Location Devices
-
GET {baseUri}/mobile/platform/location/devices?name={name}
to query by the device name. -
POST {baseUri}/mobile/platform/location/devices/query
to query using parameters in a JSON payload as described below.
Parameter | Description |
---|---|
name |
Filters results by a partial match of this string with the name defined for the device in the UI. Not case sensitive. |
description |
Filters results by a partial match of this string with the description defined for the device in the UI. Not case sensitive. |
search |
Filters results by a partial match of this string with the name or description defined for the device in the UI. Not case sensitive. |
attributes |
Filters results by a match of the name-value pairs in the Attributes object, using the attributes defined for the device in the UI.
|
protocol |
Filters results by device protocol type(s):
|
associatedAssetId |
The asset ID to search for. (Returns location devices associated with the specified asset.) |
listOfDevices |
An array of device IDs to search for. |
iBeacon_uuid |
The UUID of the iBeacon device(s) to search for. |
iBeacon_major |
The major version of the iBeacon device to search for. |
iBeacon_minor |
The minor version of the iBeacon device to search for. |
altBeacon_id1 |
ID1 of the altBeacon to search for. |
altBeacon_id2 |
ID2 of the altBeacon to search for. |
altBeacon_id3 |
ID3 of the altBeacon to search for. |
eddystone_namespace |
The namespace of the Eddystone device to search for. |
eddystone_instance |
The instance of the Eddystone device to search for. |
eddystone_url |
The URL of the Eddystone device to search for. |
orderBy
|
An enumeration of the field(s) to order results by. Can include any top-level attribute. Append the direction to order results by:
name:asc .
|
offset |
By default, 0 to start results at the first item. Specify an offset number to start results in a different place. |
limit |
By default, 40 items are returned. You can specify a different maximum number of results, up to 500. Generally meant to be used with offset for pagination.
|
format |
By default, the response is in long format and results include the device id, name, description, attributes, createdOn and createdBy, as well as the place ID and identifying details about the device. Specify short to return only the device id, name, description and protocol.
|
iBeacon
with the given properties. {
"protocol":"iBeacon",
"iBeacon_major": "2.0",
"iBeacon_minor": "2.2",
"iBeacon_uuid": "B9407F30-F5F8-466E-AFF9-25556B57FE6D"
}
{
"items": [
{
"id": 15,
"createdOn": "2015-11-11T21:15:34.341+0000",
"createdBy": "thomas.smith@fif.com",
"modifiedOn": "2015-11-11T21:15:34.341+0000",
"modifiedBy": "thomas.smith@fif.com",
"name": "RC_WH_01_F01_B003",
"description": "Beacon on 1st Floor in FixItFast Warehouse in Redwood City",
"place": {
"name": "FixitFast Redwood City Warehouse",
"label": "FixitFast Warehouse",
"description": "FixitFast Warehouse in Redwood City",
"address" : {
"gpsPoint" : {
"latitude": 37.5548,
"longitude": -121.1566
}
},
"attributes" : {
"EquipmentManufacturer": "Abc Corp"
},
"links": [
{
"rel": "canonical",
"href": "/internal-tools/1.0/envs/dev/location/places/9876"
},
{
"rel": "self",
"href": "/internal-tools/1.0/envs/dev/location/places/9876"
}
]
},
"beacon": {
"iBeacon": {
"major": "2.0",
"minor": "2.2",
"uuid": "B9407F30-F5F8-466E-AFF9-25556B57FE6D"
}
},
"attributes": {
"manufacturer": "Gimbal",
"status": "Active",
"manufacturerId": "10D39AE7-020E-4467-9CB2-DD36366F899D",
"visibility": "Public"
},
},
"totalResults": 1,
"offset": 0,
"limit": 20,
"count": 1,
"hasMore": false
}
altBeacon
devices with “Warehouse
” in the name or description and specifies the short
response format, ordered by name, with a limit of 5 items. {
"protocol":"altBeacon",
"orderBy":"name",
"limit":"5",
"format":"short",
"search":"Warehouse"
}
{
"items":[
{
"id":33,
"name":"RC_WH_01_B09_C004",
"description":"Beacon on 2nd Floor in FixItFast Warehouse in Redwood City",
"protocol":"altBeacon"
},
{
"id":12,
"name":"RC_WH_01_F01_B001",
"description":"Beacon on 1st Floor in FixItFast Warehouse in Redwood City",
"protocol":"altBeacon"
},
{
"id":61,
"name":"RC_WH_01_F01_B008",
"description":"Beacon on 2nd Floor in Fix*tFast Warehouse in Redwood City",
"protocol":"altBeacon"
},
{
"id":58,
"name":"RC_WH_02_F01_B011",
"description":"Beacon on 1st Floor in FixitFast Warehouse in Redwood City",
"protocol":"altBeacon"
},
{
"id":114,
"name":"RC_WH_01_K22_A999",
"description":"Beacon on 3rd Floor in FixitFast Warehouse in Redwood City",
"protocol":"altBeacon"
}
],
"totalResults":5,
"offset":0,
"limit":5,
"count":5,
"hasMore":false
}
Querying for Places
-
GET {baseUri}/mobile/platform/location/places?name={name}
to query by the place name. -
POST {baseUri}/mobile/platform/location/places/query
to query using parameters in a JSON payload as described below.
Parameter | Description |
---|---|
|
Filters results by a partial match of this string with the name defined for the place in the UI. Not case sensitive. |
|
Filters results by a partial match of this string with the description defined for the place in the UI. Not case sensitive. |
|
Filters results by a partial match of this string with the name, label or description defined for the place in the UI. Not case sensitive. |
|
Filters results by a match of the name-value pairs in the |
|
Filters results by a partial match of this string with the label specified for the place in the UI. Not case sensitive. |
|
An array of place IDs to search for. |
|
Specify a place ID to search for direct descendants. |
includeDescendantsInResult: all |
Entire Place descendant hierarchy is returned in the results. |
includeDescendantsInResult: direct |
Only direct (first level) descendants are returned in the results. |
includeDescendantsInResult: none |
No descendants are returned in the results. |
|
Specify a |
|
Specify a |
|
Set to |
|
An enumeration of the field(s) to order results by. Can include any top-level attribute. Append the direction to order results by:
name:asc .
|
|
By default, 0 to start results at the first item. Specify an offset number to start results in a different place. |
|
By default, 40 items are returned. You can specify a different maximum number of results, up to 500. Generally meant to be used with |
|
By default, the response is in |
{
"label":"block 1",
"inGeoFence": {
"gpsCircle": {
"latitude": 37.488179,
"longitude": -122.229011,
"radius": 32186
}
},
"orderBy":"name:asc",
"limit":100
}
{
"items": [
{
"id": 16,
"createdOn": "2016-03-08T22:09:19.968+0000",
"createdBy": "joe",
"modifiedOn": "2016-03-08T22:09:19.968+0000",
"modifiedBy": "joe",
"name": "l1b1",
"label": "lot 1 block 1",
"parentPlace": 15,
"description": "Lot 1 block 1 New City",
"hasChildren": false,
"address": {
"gpsCircle": {
"longitude": -120.87449998,
"latitude": 37.98560003,
"radius": 29999.99999997
}
},
"links": [
{
"rel": "canonical",
"href": "/mobile/platform/location/places/16"
},
{
"rel": "self",
"href": "/mobile/platform/location/places/16"
}
]
},
{
"id": 17,
"createdOn": "2016-03-08T22:09:20.065+0000",
"createdBy": "joe",
"modifiedOn": "2016-03-08T22:09:20.065+0000",
"modifiedBy": "joe",
"name": "l2b1",
"label": "lot2 block 1",
"parentPlace": 15,
"description": "Lot 2 block 1 New City",
"hasChildren": false,
"address": {
"gpsPolygon": {
"vertices": [
{
"longitude": -121.7845,
"latitude": 37.8453
},
{
"longitude": -120.9853,
"latitude": 37.1248
},
{
"longitude": -121.7758,
"latitude": 37.6983
}
]
}
},
"links": [
{
"rel": "canonical",
"href": "/mobile/platform/location/places/17"
},
{
"rel": "self",
"href": "/mobile/platform/location/places/17"
}
]
}
],
"totalResults": 2,
"offset": 0,
"limit": 100,
"count": 2,
"hasMore": false
}
{
"includeDescendantsInResult": "direct",
"orderBy" : "name",
"offset" : 0,
"limit" : 10,
"format" : "short"
}
{
"places": [
{
"id": 3331,
"name": "FixitFast Redwood City HQ Campus",
"label": "campus",
"description": "1st Floor in FixitFast Warehouse in Redwood City"
"children": [
{
"id": 3334,
"name": "Building #1 FixitFast Redwood City HQ Campus",
"description": "Building #1 on FixitFast Redwood City Headquarters Campus",
"label": "building",
"children": []
},
{
"id": 3335,
"name": "Building #2 FixitFast Redwood City HQ Campus",
"description": "Building #2 on FixitFast Redwood City Headquarters Campus",
"label": "building",
"children": []
},
{
"id": 3336,
"name": "Building #3 FixitFast Redwood City HQ Campus",
"description": "Building #3 on FixitFast Redwood City Headquarters Campus",
"label": "building",
"children": []
}
}
]
}
Querying for Assets
-
GET {baseUri}/mobile/platform/location/assets?name={name}
to query by the asset name. -
POST {baseUri}/mobile/platform/location/assets/query
to query using parameters in a JSON payload as described below.
Parameter | Description |
---|---|
name |
Filters results by a partial match of this string with the name defined for the asset in the UI. Not case sensitive. |
description |
Filters results by a partial match of this string with the description defined for the asset in the UI. Not case sensitive. |
search |
Filters results by a partial match of this string with the name, label or description defined for the asset in the UI. Not case sensitive. |
attributes |
Filters results by a match of the name-value pairs in the Attributes object, using the attributes defined for the asset in the UI.
|
label |
Filters results by a partial match of this string with the label specified for the asset in the UI. |
listOfAssets |
An array of asset IDs to search for. |
associatedDeviceId |
A device ID to search for. Returns the asset associated with this device ID. When you use this query parameter, don't combine it with other parameters. |
nearestTo |
Specify a gpsPoint (latitude, longitude) to return the closest asset. Can’t be combined with other parameters.
|
inGeoFence |
Specify a gpsCircle (latitude, longitude, radius) to return all assets within that geofence.
|
orderBy
|
An enumeration of the field(s) to order results by. Can include any top-level attribute. Append the direction to order results by:
name:asc .
|
offset |
By default, 0 to start results at the first item. Specify an offset number to start results in a different place. |
limit |
By default, 40 items are returned. You can specify a different maximum number of results, up to 500. Generally meant to be used with offset for pagination.
|
format |
By default, the response is in long format and results include the asset id, name, description, attributes, label, creation and modification data, as well as the associated place, and the IDs of associated devices. Specify short to return only the asset id, name, description and label.
|
{
"label":"bed",
"attributes":{
"EquipmentManufacturer":"Example Company"
},
"orderBy":"createdOn:asc",
"format":"long"
}
{
"items":[
{
"id":333,
"createdBy":"jdoe",
"createdOn":"2015-08-06T18:37:59.424Z",
"modifiedOn":"2015-08-06T18:37:59.424Z",
"modifiedBy":"jdoe",
"name":"hospital bed #233",
"label":"hospital bed",
"description":"model 1225 hospital bed",
"lastKnownLocation":{
"placeId":244
},
"devices":[
3409
],
"attributes":{
"EquipmentManufacturer": "Example Company",
"SJId": "6754843090"
}
},
{
"id":888,
"createdBy":"jdoe",
"createdOn":"2015-10-16T09:24:41.354Z",
"modifiedOn":"2015-10-16T09:24:41.354Z",
"modifiedBy":"jdoe",
"name":"hospital bed #233",
"label":"hospital bed",
"description":"model 1225 hospital bed",
"lastKnownLocation":{
"placeId":360
},
"devices":[
658
],
"attributes":{
"EquipmentManufacturer": "Example Company",
"SJId": "6754843090"
}
}
],
"totalResults":2,
"offset":0,
"limit":100,
"count":2,
"hasMore":false
}
Using the SDK to Query for Location Objects: iOS
OMCLocationQuery
class in the iOS client SDK allows you to construct queries for location devices, places and assets.
To access the Location API through the iOS SDK, use [[OMCMobileBackendManager sharedManager].defaultMobileBackend
as described in Calling Platform APIs Using the SDK for iOS.
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
NSString* searchString = @"store";
// search by name
// sort results by name, in ascending order
// results will be in "short" format
OMCLocationPlaceQuery* query = [location buildPlaceQuery];
query.name = searchString;
query.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
query.format = OMCLocationObjectQueryFormatTypeShort;
__block OMCLocationPlaceQueryResult* result;
do {
result = nil;
__block NSError* error = nil;
__block BOOL executing = YES;
[query executeWithCompletionHandler:^(OMCLocationPlaceQueryResult* result_, NSError* error_) {
result = result_;
error = error_;
executing = NO;
}];
while (executing) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeInterval:0.5 sinceDate:[NSDate date]]];
}
if (error) {
// handle error...
} else {
for (OMCLocationPlace* place in result.items) {
// process each place...
NSLog(@"place name: %@", place.name);
}
}
query = result.nextQuery;
} while ((result != nil) && result.hasMore);
Using the SDK to Query for Location Objects: Android
LocationQuery
class in the Android client SDK allows you to construct queries for location devices, places and assets.
To access the Location API through the Android SDK, use the MobileBackendManager
class as described in Calling Platform APIs Using the SDK for Android.
Location location = MobileBackendManager.getManager().getDefaultMobileBackend(mContext).getServiceProxy(Location.class);
Object lock = new Object();
String searchString = "store";
final AtomicReference<String> searchString = "store";
final AtomicReference<LocationObjectQueryResult> mResult = new AtomicReference<LocationObjectQueryResult>();
final AtomicReference<ServiceProxyException> mError = new AtomicReference<ServiceProxyException>();
// search by name
// sort results by name, in ascending order
// results will be in "short" format
LocationPlaceQuery query = location.buildPlaceQuery();
query.setName(searchString);
query.setOrderByAttributeType(LocationDeviceContainerQuery.LocationDeviceContainerQueryOrderByAttributeType
.LocationDeviceContainerQueryOrderByAttributeTypeName);
query.setFormat(LocationObjectQuery.LocationObjectQueryFormatType.LocationObjectQueryFormatTypeShort);
do{
query.execute(new LocationObjectsQueryCallback(){
@Override
void onComplete(LocationObjectQueryResult result, ServiceProxyException exception){
mError.set(exception);
mResult.set(result);
synchronized(lock){
lock.notifyAll();
}
}
});
synchronized(lock) {
lock.wait();
}
if(mError.get() != null){
//handle error
}
else{
for(LocationObject object : mResult.get().getItems()){
LocationPlace place = (LocationPlace) object;
// process each place...
}
}
query = mResult().get().getNextQuery();
} while(mResult.get() != null && mResult.get().hasMore());
Retrieving Location Objects and Properties
Use the Location API to retrieve location devices, places and assets and their associated properties.
-
Location devices:
GET {baseUri}/mobile/platform/location/devices
-
Assets:
GET {baseUri}/mobile/platform/location/assets
-
Places:
GET {baseUri}/mobile/platform/location/places
-
To retrieve an object by ID, include the ID in the path, for example:
GET {baseUri}/mobile/platform/location/devices/12345
. -
To retrieve an object by name, pass the name of an existing object to the endpoint in the
name
query parameter, for exampleGET {baseUri}/mobile/platform/location/devices?name=RC_WH_01_F01_B001
.
Using the SDK to Retrieve a Location Object: iOS
To access the Location API through the SDK, use the OMCMobileBackendManager
class as described in Calling Platform APIs Using the SDK for iOS.
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
// query for all places
// sort results by name, in ascending order
// results will be in "short" format
OMCLocationPlaceQuery* query = [location buildPlaceQuery];
query.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
query.format = OMCLocationObjectQueryFormatTypeShort;
__block OMCLocationPlaceQueryResult* result = nil;
__block NSError* error = nil;
__block BOOL executing = YES;
[query executeWithCompletionHandler:^(OMCLocationPlaceQueryResult* result_, NSError* error_) {
result = result_;
error = error_;
executing = NO;
}];
while (executing) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeInterval:0.5 sinceDate:[NSDate date]]];
}
// take the first item from the results
// it will be in "short" format...
OMCLocationPlace* shortPlace = result.items.firstObject;
// ...now, fetch the "entire" place directly
__block OMCLocationPlace* place = nil;
error = nil;
executing = YES;
[location placeWithID: shortPlace.id_ completionHandler:^(OMCLocationPlace* place_, NSError* error_) {
place = place_;
error = error_;
executing = NO;
}];
while (executing) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeInterval:0.5 sinceDate:[NSDate date]]];
}
// process place...
NSLog(@"place name: %@", place.name);
...
// take the first item from the results
// it will be in "short" format...
OMCLocationPlace* place = result.items.firstObject;
// ...now, refresh the place
error = nil;
executing = YES;
[place refreshWithCompletionHandler:^(NSError* error_) {
error = error_;
executing = NO;
}];
while (executing) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeInterval:0.5 sinceDate:[NSDate date]]];
}
// process place...
NSLog(@"place name: %@", place.name);
Using the SDK to Retrieve iBeacon Identifiers: iOS
CLLocationManager *locationManager = [[CLLocationManager alloc] init]; // iOS CoreLocation object
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
OMCLocationPlaceQuery *queryPlace = [location buildPlaceQuery];
queryPlace.name = @"Chris's Emporium";
queryPlace.limit = @1;
// Order-bys are required as name is search by wildcard, not exact match
queryPlace.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
queryPlace.orderByOrder = OMCLocationObjectQueryOrderByOrderTypeAscending;
[queryPlace executeWithCompletionHandler:^(OMCLocationObjectQueryResult<OMCLocationPlaceQuery *,OMCLocationPlace *>* queryResult, NSError * _Nullable queryError) {
OMCLocationPlace *place = queryResult.items.firstObject;
[place devicesWithCompletionHandler:^(NSArray<OMCLocationDevice *> *locationDevices, NSError * error) {
// Following code assumes 1 device for place
OMCLocationDevice *device = [locationDevices firstObject];
OMCLocationIBeacon *beacon = (OMCLocationIBeacon*)device.beacon;
NSUUID *beaconUuid = beacon.uuid;
CLBeaconMajorValue beaconMajor = (CLBeaconMajorValue)beacon.major.integerValue;
CLBeaconMinorValue beaconMinor = (CLBeaconMinorValue)beacon.minor.integerValue;
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc]initWithProximityUUID:beaconUuid major:beaconMajor minor:beaconMinor identifier:@"MyBeaconRegion"];
beaconRegion.notifyOnEntry = YES;
beaconRegion.notifyOnExit = YES;
beaconRegion.delegate = // Assign instance of CLLocationManagerDelegate to handle beacon events
[locationManager startMonitoringForRegion:beaconRegion]; // Invokes CLLocationManagerDelegate didEnterRegion/didExitRegion
[locationManager startRangingBeaconsInRegion:beaconRegion]; // Invokes CLLocationManagerDelegate inRegion
}];
}];
Using the SDK to Define a Geofence: iOS
CLLocationManager *locationManager = [[CLLocationManager alloc] init]; // iOS CoreLocation object
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
OMCLocationPlaceQuery *queryPlace = [location buildPlaceQuery];
queryPlace.name = @"Chris's Emporium";
queryPlace.limit = @1;
// Order-bys are required as name is search by wildcard, not exact match
queryPlace.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
queryPlace.orderByOrder = OMCLocationObjectQueryOrderByOrderTypeAscending;
[queryPlace executeWithCompletionHandler:^(OMCLocationObjectQueryResult<OMCLocationPlaceQuery *,OMCLocationPlace *>* queryResult, NSError * queryError) {
OMCLocationPlace *place = queryResult.items.firstObject;
OMCLocationGeoCircle *geocircle = (OMCLocationGeoCircle *)[place address];
OMCLocationGeoPoint *geopoint = [geocircle center];
CLLocationDegrees latitude = [[geopoint latitude]doubleValue];
CLLocationDegrees longitude = [[geopoint longitude]doubleValue];
CLLocationDistance radius = [[geocircle radius]doubleValue];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
CLCircularRegion *circularRegion = [[CLCircularRegion alloc]initWithCenter:coordinate radius:radius identifier:@"MyGeofenceRegion"];
circularRegion.notifyOnEntry = YES;
circularRegion.notifyOnExit = YES;
circularRegion.delegate = // Assign instance of CLLocationManagerDelegate to handle events
[locationManager startMonitoringForRegion:circularRegion]; // Invokes CLLocationManagerDelegate didEnterRegion/didExitRegion
}];
}];
Using the SDK to Retrieve Custom Attributes: iOS
Retrieving a Custom Attribute for a Place
CLLocationManager *locationManager = [[CLLocationManager alloc] init]; // iOS CoreLocation object
OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
OMCLocationPlaceQuery *queryPlace = [location buildPlaceQuery];
queryPlace.name = @"Chris's Emporium";
queryPlace.limit = @1;
// Order-bys are required as name is search by wildcard, not exact match
queryPlace.orderByAttribute = OMCLocationDeviceContainerQueryOrderByAttributeTypeName;
queryPlace.orderByOrder = OMCLocationObjectQueryOrderByOrderTypeAscending;
[queryPlace executeWithCompletionHandler:^(OMCLocationObjectQueryResult<OMCLocationPlaceQuery *,OMCLocationPlace *>* queryResult, NSError * queryError) {
OMCLocationPlace *place = queryResult.items.firstObject;
NSString *myCustomProperty = [place attributeForKey:@"MyCustomProperty"];
NSLog(@"My Custom Property = %@", myCustomProperty);
}];
Retrieving a Custom Attribute for a Location Device
OMCLocationDevice
to retrieve a custom attribute for a beacon:OMCLocation* location = [[OMCMobileBackendManager sharedManager].defaultMobileBackend location];
// Query iBeacon
OMCLocationDeviceQuery *queryDevice = [location buildDeviceQuery];
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"0AC59CA4-DFA6-442C-8C65-22247851344C"];
NSNumber *major = @4;
NSNumber *minor = @200;
queryDevice.beacon = [OMCLocationIBeacon iBeaconWithUUID:uuid major:major minor:minor];
[queryDevice executeWithCompletionHandler:^(OMCLocationObjectQueryResult<OMCLocationDeviceQuery *,OMCLocationDevice *>* queryResult, NSError * queryError) {
OMCLocationDevice *device = queryResult.items.firstObject;
// Retrieve device/beacon custom property
NSString *customProperty = (NSString *) [device attributeForKey:@"MyCustomProperty"];
}];
Using the SDK to Retrieve a Location Object: Android
To access the Location API through the Android client SDK, use the MobileBackendManager
class as described in Calling Platform APIs Using the SDK for Android.
Location location = MobileBackendManager.getManager().getDefaultMobileBackend(mContext).getServiceProxy(Location.class);
Object lock = new Object();
final AtomicReference<LocationObjectQueryResult> mResult = new AtomicReference<LocationObjectQueryResult>();
final AtomicReference<LocationPlace> mError = new AtomicReference<LocationPlace>();
// query for all places
// sort results by name, in ascending order
// results will be in "short" format
LocationPlaceQuery query = location.buildPlaceQuery();
query.setName(searchString);
query.setOrderByAttributeType(LocationDeviceContainerQuery.LocationDeviceContainerQueryOrderByAttributeType
.LocationDeviceContainerQueryOrderByAttributeTypeName);
query.setFormat(LocationObjectQuery.LocationObjectQueryFormatType.LocationObjectQueryFormatTypeShort);
query.execute(new LocationObjectsQueryCallback(){
@Override
void onComplete(LocationObjectQueryResult result, ServiceProxyException exception){
mResult.set(result);
synchronized(lock){
lock.notifyAll();
}
}
});
synchronized(lock){
lock.wait();
}
// take the first item from the results
// it will be in "short" format...
LocationPlace place = (LocationPlace) mResult.get().getItems().get(0);
// ...now, fetch the "entire" place directly
location.fetchPlace(place.getID(), new LocationObjectQueryCallback(){
@Override
void onComplete(LocationObject object, ServiceProxyException exception){
LocationPlace detailedPlace = (LocationPlace) object;
mPlace.set(detailedPlace);
synchronized(lock){
lock.notifyAll();
}
}
});
synchronized(lock){
lock.wait();
}
// process place...
Log.i(TAG, "place name is " + mPlace.get().getName());
...
// take the first item from the results
// it will be in "short" format...
LocationPlace place = (LocationPlace) mResult.get().getItems().get(0);
// ...now, refresh the place
place.refresh(new LocationObjectFetchCallback(){
@Override
void onComplete(LocationObject object, ServiceProxyException exception){
if(exception != null)
//handle error
synchronized(lock) {
lock.notifyAll();
}
}
});
synchronized(lock){
lock.wait();
}
// process place...
Log.i(TAG, "place name is " + place.getName());