Sample tracking and geofence application for Android - Amazon Location Service

Sample tracking and geofence application for Android

This topic covers the Android tutorial designed to demonstrate the key features of using the Amazon Location geofences and trackers in a mobile application. The applications demonstrate how a tracker and geonfence interact using a combination of Lambda, AWS IoT and Amazon Location features.

Create Amazon Location resources for your app

To begin you will need to create the required Amazon Location resources. These resources will be essential for the functionality of the application and executing the provided code snippets.

Note

If you haven't created an AWS account, follow the instructions in the AWS account managment user guide.

To begin you will need to create a Amazon Cognito Identity Pool Id, use the following procedure:

  1. Open the Amazon Cognito console and select Identity pools from the left side menu, then select Create Identity pool.

  2. Make sure Guest Access is checked, and press Next to contiue.

  3. Next create a new IAM role or Use an existing IAM role.

  4. Enter an Identity pool name, and make sure Identity Pool has access to Amazon Location (geo)resources for the map and tracker you will be creating nin the next procedure.

Next you need to create and style a map in the AWS Amazon Location console, use the following procedure:

  1. Navigate to the Maps section of the Amazon Location console and select Create Map.

  2. Give the new map a Name and Description. Record the name you assign, as it is used later in the tutorial.

  3. When choosing a map style, consider the map data provider. Refer to section 82 of the AWS service terms for more details.

  4. Accept the Amazon Location Terms and Conditions, then select Create Map, to finish the map creation process.

Next you need to create a tracker in the Amazon Location console, use the following procedure:

  1. Open the Maps section in the Amazon Location console.

  2. Choose Create tracker.

  3. Fill in the required fields. Make note of the tracker's Name as it will be refrenced throughout this tutoiral.

  4. Under the Position filtering field, choose the option that best fits how you intend to use your tracker resource. If you do not set Position filtering, the default setting is TimeBased. For more information, see Trackers, and PositionFiltering in the Amazon Location API Reference.

  5. Choose Create tracker to finish creating the tracker.

Create a Geofence Collection

Now will you create a geofence collection. You can use either the console, API or CLI. The following procedures walk you through each option.

  • Create a geofence collection using the Amazon Location console:

    1. Open the Geofence Collections section of the Amazon Location console.

    2. Choose Create geofence collection.

    3. Provide a name and description for the collection.

    4. Under the EventBridge rule with Amazon CloudWatch as a target, you can create an optional EventBridge rule to get started reacting to geofence events. This enables Amazon Location to publish events to Amazon CloudWatch Logs.

    5. Press the Create geofence collection to finish creating the collection.

  • Create a geofence collection using the Amazon Location API:

    Use the CreateGeofenceCollection operation from the Amazon Location Geofences APIs. The following example uses an API request to create a geofence collection called GEOCOLLECTION_NAME.

    POST /geofencing/v0/collections Content-type: application/json { "CollectionName": "GEOCOLLECTION_NAME", "Description": "Geofence collection 1 for shopping center", "Tags": { "Tag1" : "Value1" } }
  • Create a geofence collection using AWS CLI commands:

    Use the create-geofence-collection command. The following example uses an AWS CLI to create a geofence collection called GEOCOLLECTION_NAME. For more information on using the AWS CLI, see the AWS Command Line Interface Documentation.

    aws location \ create-geofence-collection \ --collection-name "ExampleGeofenceCollection" \ --description "Shopping center geofence collection" \ --tags Tag1=Value1

To link a tracker to a geofence collection you can use either the console, API, or CLI. The following procedures walk you through each option.

Link a tracker resource to a geofence collection using the Amazon Location Service console:

  1. Open the Amazon Location console.

  2. In the left navigation pane, choose Trackers.

  3. Under Device Trackers, select the name link of the target tracker.

  4. Under Linked Geofence Collections, choose Link Geofence Collection.

  5. In the Linked Geofence Collection window, select a geofence collection from the dropdown menu.

  6. Choose Link.

  7. After you link the tracker resource, it will be assigned an Active status.

Link a tracker resource to a geofence collection using the Amazon Location APIs:

Use the AsssociateTrackerConsumer operation from the Amazon Location Trackers APIs. The following example uses an API request that associates an ExampleTracker with a geofence collection using its Amazon Resource Name (ARN).

POST /tracking/v0/trackers/ExampleTracker/consumers Content-type: application/json {    "ConsumerArn": "arn:aws:geo:us-west-2:123456789012:geofence-collection/GOECOLLECTION_NAME" }

Link a tracker resource to a geofence collection using AWS CLI commands:

Use the associate-tracker-consumer command. The following example uses an AWS CLI to create a geofence collection called GOECOLLECTION_NAME.

aws location \ associate-tracker-consumer \ --consumer-arn "arn:aws:geo:us-west-2:123456789012:geofence-collection/GOECOLLECTION_NAME" \ --tracker-name "ExampleTracker"

Using AWS Lambda with MQTT

In order to create a connection between AWS IoT and Amazon Location, you need a Lambda function to process messages forwarded by EventBridge CloudWatch events. This function will extract any positional data, format it for Amazon Location, and submit it through the Amazon Location Tracker API.

The following procedure shows you how to create this function through the Lambda console:

  1. Open the console.

  2. From the left navigation, choose Functions.

  3. Then choose Create Function, and make sure that the Author from scratch option is selected.

  4. provide a Function name, and for the Runtime option, choose Node.js 16.x.

  5. Choose Create function.

  6. Open the Code tab to access the editor.

  7. Overwrite the placeholder code in the index.js file with the following:

    const AWS = require('aws-sdk') const iot = new AWS.Iot(); exports.handler =  function(event) {   console.log("event===>>>", JSON.stringify(event));   var param = {     endpointType: "iot:Data-ATS"   };   iot.describeEndpoint(param, function(err, data) {     if (err) {       console.log("error===>>>", err, err.stack); // an error occurred     } else {       var endp = data['endpointAddress'];       const iotdata = new AWS.IotData({endpoint: endp});           const trackerEvent = event["detail"]["EventType"];       const src = event["source"];       const time = event["time"];       const gfId = event["detail"]["GeofenceId"];       const resources = event["resources"][0];         const splitResources = resources.split(".");         const geofenceCollection = splitResources[splitResources.length - 1];       const coordinates = event["detail"]["Position"];                                     const deviceId = event["detail"]["DeviceId"];       console.log("deviceId===>>>", deviceId);       const msg =  {           "trackerEventType" : trackerEvent,           "source" : src,           "eventTime" : time,           "geofenceId" : gfId,           "coordinates": coordinates,           "geofenceCollection": geofenceCollection         };       const params = {         topic: `${deviceId}/tracker`,         payload: JSON.stringify(msg),         qos: 0       };       iotdata.publish(params, function(err, data) {           if (err) {             console.log("error===>>>", err, err.stack); // an error occurred           } else {             console.log("Ladmbda triggered===>>>", trackerEvent);  // successful response           }       });     }   }); }
  8. Press the Deploy to save the updated function.

  9. Next open the Configuration tab.

  10. In the Triggers section, press the Add Trigger button.

  11. Select EventBridge (CloudWatch Events) in Source field.

  12. Select the Existing Rules option.

  13. Enter the rule name, for example AmazonLocationMonitor-GEOFENCECOLLECTION_NAME.

  14. Press the Add button.

  15. This will also attach Resource-based policy statements in the permissions tab

Now you will set up the MQTT Test Client using AWS IoT, use the following procedure:

  1. Open the https://console.aws.amazon.com/iot/.

  2. In the left navigation pane, select the MQTT test client.

  3. You'll see a section titled MQTT test client where you can configure your MQTT connection.

  4. After configuring the necessary settings, click on the Connect button to establish a connection to the MQTT broker using the provided parameters.

  5. Record endpoint, as it is used later in the tutoiral.

    Once connected to the test client, you can subscribe to MQTT topics or publish messages to topics using the respective input fields provided in the MQTT test client interface. Next you will create an AWS IoT policy.

  6. On the left side menu, under Manage expand Security option and click on Policies.

  7. Click on Create Policy button.

  8. Enter a policy name.

  9. On Policy Document select JSON tab.

  10. Copy paste the policy shown below, but make sure to update all elements with your REGION and ACCOUNT_ID:

    { "Version": "2012-10-17", "Statement": [ { "Action": [ "iot:Connect", "iot:Publish", "iot:Subscribe", "iot:Receive" ], "Resource": [ "arn:aws:iot:REGION:ACCOUNT_ID:client/${cognito-identity.amazonaws.com:sub}", "arn:aws:iot:REGION:ACCOUNT_ID:topic/${cognito-identity.amazonaws.com:sub}", "arn:aws:iot:REGION:ACCOUNT_ID:topicfilter/${cognito-identity.amazonaws.com:sub}/*", "arn:aws:iot:REGION:ACCOUNT_ID:topic/${cognito-identity.amazonaws.com:sub}/tracker" ], "Effect": "Allow" } ] }
  11. Select the Create button to finish.

After completing the previous procedure, you will now update the permissions for the guest role as follows:

  1. Navigate to Amazon Cognito and open your identity pool. Then, proceed to user access and select the guest role.

  2. Click on permission policies to enable editing.

    { 'Version': '2012-10-17', 'Statement': [ { 'Action': [ 'geo:GetMap*', 'geo:BatchUpdateDevicePosition', 'geo:BatchEvaluateGeofences', 'iot:Subscribe', 'iot:Publish', 'iot:Connect', 'iot:Receive', 'iot:AttachPrincipalPolicy', 'iot:AttachPolicy', 'iot:DetachPrincipalPolicy', 'iot:DetachPolicy' ], 'Resource': [ 'arn:aws:geo:us-east-1:{USER_ID}:map/{MAP_NAME}', 'arn:aws:geo:us-east-1:{USER_ID}:tracker/{TRACKER_NAME}', 'arn:aws:geo:us-east-1:{USER_ID}:geofence-collection/{GEOFENCE_COLLECTION_NAME}', 'arn:aws:iot:us-east-1:{USER_ID}:client/${cognito-identity.amazonaws.com:sub}', 'arn:aws:iot:us-east-1:{USER_ID}:topic/${cognito-identity.amazonaws.com:sub}', 'arn:aws:iot:us-east-1:{USER_ID}:topicfilter/${cognito-identity.amazonaws.com:sub}/*', 'arn:aws:iot:us-east-1:{USER_ID}:topic/${cognito-identity.amazonaws.com:sub}/tracker' ], 'Effect': 'Allow' }, { 'Condition': { 'StringEquals': { 'cognito-identity.amazonaws.com:sub': '${cognito-identity.amazonaws.com:sub}' } }, 'Action': [ 'iot:AttachPolicy', 'iot:DetachPolicy', 'iot:AttachPrincipalPolicy', 'iot:DetachPrincipalPolicy' ], 'Resource': [ '*' ], 'Effect': 'Allow' } ] }
  3. With the above policy changes, all necessary AWS resources are now configured appropriately for the application.

Set up the sample app code

  1. Clone this repository: https://github.com/aws-geospatial/amazon-location-samples-android/tree/main/tracking-with-geofence-notifications to your local machine.

  2. Open the AmazonSampleSDKApp project in Android Studio.

  3. Build and run the app on your Android device or emulator.

Using the sample app

To use the sample follow these procedures:

  • Create a custom.properties:

    To configure your custom.properties file, follow these steps:

    1. Open your preferred text editor or IDE.

    2. Create a new file.

    3. Save the file with the name custom.properties.

    4. Update the custom.properties with the following code sample, and replace the MQTT_END_POINT, POLICY_NAME, GEOFENCE_COLLECTION_NAME, and TOPIC_TRACKER with your resoucre names:

      MQTT_END_POINT=YOUR_END_POINT.us-east-1.amazonaws.com POLICY_NAME=YOUR_POLICY GEOFENCE_COLLECTION_NAME=YOUR_GEOFENCE TOPIC_TRACKER=YOUR_TRACKER
    5. Clean and Rebuild the project. After this, you can run the project.

  • Sign In:

    To sign in to the application, follow the below steps:

    1. Press the Sign In button.

    2. Provide an Identity Pool Id, Tracker name, and a Map name.

    3. Press Sign In again to finish.

  • Manage Filters:

    Open the configuration screen, and perform the following:

    1. Toggle filters on or off using the switch UI.

    2. Update Time and Distance filters when needed.

  • Tracking Operations:

    Open the tracking screen and perform the following:

    • You can start and stop tracking in foreground, background, or in battery-saver mode by pressing the respective buttons.