Personalisation SDK, by MapmyIndia, is India's first O2O engagement tool that can 3X your customer engagement, retention and conversion.
Get Real-Time Location Tracking for your apps with MapmyIndia InTouch SDK. Track a user's live location with our simplified InTouch SDK integration (for Android), highly customizable to your specific needs.
The InTouch SDK comes with a variety of events that enable better control and power over your tracking needs. Get readymade events to create Geo-Fences, Event Alerts, and Trails of telematics/ phone devices. Also get location benefits built for various applications including logistics, delivery tracking, employee tracking, and live location sharing.
To get started, explore the InTouch Demo App.
Already have an application? Give it a boost with the powerful features of InTouch. Learn how to Integrate the InTouch SDK.
We use your Client ID to identify your account details and assign all your user's devices under a single account.
To get your Outh2 Rest API Client ID and Client Secret please login to MapmyIndia API Dashboard
Please contact apisupport@mapmyindia.com to get InTouch SDK access to your Client ID
After getting the access, you can start with the InTouchDemo app, or Integrate the InTouch SDK in your app.
This guide allows you to add live location tracking to an Android app. Android Studio is the recommended development environment for building an app with the MapmyIndia InTouch SDK for Android.
Click here to download the InTouchDemo App Project. Open this project in Android Studio
Android Studio starts Gradle and builds your project. This may take a few seconds. For more information about creating a project in Android Studio, see the Android Studio documentation.
The next few sections contain the code samples that you need to add to your activity's java file as well as its xml layout file for creating an app with MapmyIndia InTouch SDK for live tracking.
Add following lines to your applications build.gradle:
// Import the SDK within your repositories block allprojects { repositories { google() jcenter() maven { url 'https://maven.mapmyindia.com/repository/mapmyindia/' } } } //Add to build.gradle android{ ----- compileOptions { sourceCompatibility 1.8 targetCompatibility 1.8 } ----- } dependencies { implementation 'com.mapmyindia.sdk:intouch-sdk:0.3.0' ... }
Required Minimum sdk version minSdkVersion 16
Initialize the SDK with your Client ID and Client Secret.
// Add the following to your AndroidManifest.xml file. <uses-permission android:name="android.permission.INTERNET" />
// IAuthListener - returns authorization results in the forms of callbacks. InTouch.initialize(<device name>, <your client id>, <your client secret>, new IAuthListener() { @Override public void onSuccess() { //write your code here } @Override public void onError(String reason, String identifier, String description) { // reason gives the error type. // errorIdentifier gives information about error code. // errorDescription gives a message for a particular error. } });
Track your app user's phone live location by using the below method.
InTouch.startTracking();
Check your device live location in the Intouch Web dashboard. Login to Intouch Dashboard using your MapmyIndia Username and password.
All devices tracked on InTouch are uniquely identified using UUID. You can get this identifier programmatically in your app by calling getDeviceID() after initialization. Another approach is to tag the device with a name that will make it easy to distinguish them on InTouch Dashboard.
Intouch sdkInstance = Intouch.initialize(deviceName, clientId, clientSecret, iAuthListener);
Intouch.updateDeviceName(<device name>);
Check whether location tracking is started or not. This method returns boolean value.
Intouch.isRunning();
You can stop tracking the user location using below method.
Intouch.stopTracking();
MapmyIndiaIntouch tracking runs as a separate foreground service, so when tracking is started, users will see a persistent notification. By default, it displays your app icon with text {app name} is running but you can customize it anytime after initialization by calling:
Intouch.getInstance().addNotificationIconsAndTitle( R.drawable.ic_small, R.drawable.ic_large, notificationTitleText, notificationBodyText );
User can customize data polling configuration using below mentioned Config class.
(1) With predefine priorities:-
new Config.Builder(getContext()) .setPriority(InTouch.BEACON_PRIORITY_FAST) .build();
(2) With custom parameters:-
new CustomConfig.Builder(context) .setBeaconStandByTimeInMins(15) .setDetectDrive(true) .setTimeWhileMovingInSec(15) .build();
Note:- it should be set before startTracking() method.
There are three predefined properties are there. InTouch.BEACON_PRIORITY_FAST - Recommended for short haul delivery tracking. InTouch.BEACON_PRIORITY_SLOW - Recommended for Long haul delivery tracking. InTouch.BEACON_PRIORITY_OPTIMAL - Recommended for all the other tracking. Data polling frequency based on the user movement.
By default, InTouch SDK uses the optimal property.
Get live device details by single or multiple IDs.
a) Get the list of all devices live data in your account.
InTouch.getDevices(<includeInActive>,<ignoreBeacon>,<lastUpdateTime>, new IDeviceListener() { @Override public void onSuccess(DevicesResponse devicesResponse) { // write your code here. } @Override public void onError(String reason, String identifier, String description) { // reason gives the error type. // errorIdentifier gives information about error code. // errorDescription gives a message for a particular error. } });
b) Get the list of selected devices live data.
InTouch.getDevices(<Long[] List of deviceIds>,<includeInActive>,<ignoreBeacon>,<lastUpdateTime>,new IDeviceListener() { @Override public void onSuccess(DevicesResponse devicesResponse) { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // errorDescription gives a message for a particular error. } });
c) Get a single device live data
InTouch.getDevice(<deviceId>,<lastUpdateTime>, new IDeviceListener() { @Override public void onSuccess(DevicesResponse devicesResponse) { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // errorDescription gives a message for a particular error. } });
DevicesResponse class object returns the API response as JSON object.
DeviceResponse result parameters:Get the Trails (Travelled path) of a device in your account using below methods.
InTouch.getLocationsEvents(<deviceId>,<startTime>,<endTime>,<skipPeriod> new ILocationEventsListener() {@Override public void onSuccess(LocationEventsResponse locationEventsResponse) { // Write your code here. } @Override public void onError(String s, String s1, String s2) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
LocationEventResponse class object returns the API response as JSON object.
Get the drive details of a vehicle/user in an InTouch account using the below method. A drive is a list of reported geo-positions with start and end location of a vehicle according to pre-defined conditions. Time duration, distance covered during the drive, HA, HB, HC events are also returned along with the drive details.
InTouch.getDrive(deviceId, startTime, endTime, new IntouchDrivesCallBack() { @Override public void onSuccess(IntouchDriveResponse intouchDriveResponse) { } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { } });
1.deviceId(Long)- Id of the device for which the drives need to be fetched. 2. startTime (Long)- The start Epoch timestamp from which the drives need to be fetched. 3. endTime (Long)- The end Epoch timestamp till which the drives need to be fetched.
DriveResponse Class object returns the API response as JSON object.
A geofence is a user-defined bounded area to trigger Entry and Exit alert of the user/vehicle. Custom areas or places can be created as a Geofence under your account, For example, it could be a hotel, Restaurant, Office, work area, retail store and so on.
MapmyIndia InTouch SDK supports Point, Circle and Polygon (Custom Region/Area) geofences. You can Create, Update or Delete geofences using below methods.
The create geofence method helps you to create a geofence under your account. Three types of geofence can be created: Point, Circle, Polygon.
Input the Lat, long and the name of the geofence to create the point geofence. A point geofence has a fixed radius of 100 meters, so the user need not put the radius of the geofence. To customize the radius of geofence refer circle geofence method.
// Point type geofence // ICreateGeoFenceListener - returns success if geofence created else error as callback methods. InTouch.createGeoFence("<geofence name>", new GeoFencePoint(<Latitude>, <Longitude>), new ICreateGeoFenceListener() { @Override public void onSuccess() { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
Create a circle geofence with a radius of your choice. Input Lat, long, Radius and name of the geofence to create the circle geofence.
// Circle type geofence, the radius will be in meters. // ICreateGeoFenceListener - returns success if geofence created else error as callback methods. InTouch.createGeoFence("<geofence name>", new GeoFencePoint(<Latitude>, <Longitude>), <range>, new ICreateGeoFenceListener() { @Override public void onSuccess(CreateGeoFenceResponse response) { // writeyour code here } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
To draw a polygon geofence we need at least three points. Multiple points can be added to create the custom shape Geofence. Input a list of geofence points (Lat,long) in the comma-separated format.
// Polygon Geofence // ICreateGeoFenceListener - returns success if geofence created else error as callback methods. InTouch.createGeoFence("<geofence name>", <list of GeoFencePoint>, new ICreateGeoFenceListener() { @Override public void onSuccess(CreateGeoFenceResponse response) { // writeyour code here } @Override public void onError(String reason, String identifier, String description) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
1.geoFenceName(String) name of the geofence. 2. geoFencePoint(GeoFencePoint) Geofence point(s). List of "GeoFencePoint" for polygon else single object required.
Response CodeCreateGeoFenceResponse class object returns the API response as JSON object.
id (Long) Id of the newly created geofence.
InTouch Get Geofences methods can be used to request the list of geofence areas using the unique geofence IDs which is being assigned by InTouch.
Get all the geofences created under your account using the below method. It returns the name and unique Id of the geofence.
// Get all geofences // IGetGeoFenceListener- returns all geoFences in response if success else error as callback methods. InTouch.getGeoFences(new IGetGeoFenceListener() { @Override public void onSuccess(InTouchGeoFenceResponse response) { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
Get the geofence response with shape by setting ignore geometry value as false. for example, the type will be either a point, polygon or circle.
// ignoreGeometry is a boolean value. If the user doesn't need geometry with geofence pass true else false. // IGetGeoFenceListener- returns all geoFences with geometry in response if success else error as callback methods. InTouch.getGeoFences(<ignoreGeometry>, new IGetGeoFenceListener() { @Override public void onSuccess(InTouchGeoFenceResponse response){ // write your code here. } @Override public void onError(String reason, String identifier, String description) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
Input Geofence Id to get a single geofence detail in the get method.
// Get single geofence // IGetGeoFenceListener- returns single geoFence in response if success else error as callback methods. InTouch.getGeoFences(<id of geofence>, new IGetGeoFenceListener() { @Override public void onSuccess(InTouchGeoFenceResponse response){ // write your code here. } @Override public void onError(String reason, String identifier, String description) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
Get a geofence with the geometry value like circle, polygon or point. Set ignoreGeometry value as false.
// Get single geofence with geometry value // IGetGeoFenceListener- returns single geoFence with geometry in response if success else error as callback methods. InTouch.getGeoFences(<id of geofence>,<ignoreGeometry>, new IGetGeoFenceListener() { @Override public void onSuccess(InTouchGeoFenceResponse response) { // write your code here. } @Override public void onError(String reason, String identifier, String description) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
Get multiple geofences for an array of geofence Ids with ignoreGeometry parameter value set as false.
// Get multiple geofences with geometry value // IGetGeoFenceListener- returns multiple geoFences in response if success else error as callback methods. InTouch.getGeoFences(<Long array of geofence ids>, <id of geofence>,<ignoreGeometry>, new IGetGeoFenceListener() { @Override public void onSuccess(InTouchGeoFenceResponse response){ // write yor code here. } @Override public void onError(String reason, String identifier, String description) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
1.id(Long) Geofence id. Use this if you want to get details of specific multiple geofence IDs. 2. ignoreGeometry(boolean) Non-mandatory field, boolean value to fetch geometry details.
Response CodeCreateGeoFenceResponse Class object returns the API response as JSON object.
- List<GeoFenceResult> List of GeoFenceResult.
Use Geofence ID to update Geofence name, latitude, longitude and radius in below method
Update geofence values like geofence name and lat, long using below method
// update single geofence // IUpdateGeoFenceListener - returns success if gefence updated successfully, else error as callback methods. InTouch.updateGeoFence(<geofence id>, <name of geofence>, <GeoFencePoint>, new IUpdateGeoFenceListener() { @Override public void onSuccess() { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
Update geofence name, latitude, longitude and Radius for a circle geofence using below method.
// update single geofence with buffer value. Buffer is like radius in meters. InTouch.updateGeoFence(<geofence id>, <name of geofence>, <GeoFencePoint>, <buffer>, new IUpdateGeoFenceListener() { @Override public void onSuccess() { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } }); });
Update the geofence name, and the latitude, longitude of the polygon geofence using below method.
// Update polygon geofence. InTouch.updateGeoFence(<geofence id>, <name of geofence>, <list of GeoFencePoint>, new IUpdateGeoFenceListener() { @Override public void onSuccess() { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
UpdateGeoFenceResponse Class object returns the API response as JSON object.
message<String> Describes the type of error based on the type of response code.
Delete Geofences by mentioning the geofence IDs in the following methods
Use the below method to delete a particular geofence by mentioning geofence ID.
// Delete single geofence // IResultListener- returns success if gefence deleted successfully, else error as callback methods. InTouch.deleteGeoFence(<geofence id>, new IResultListener() { @Override public void onSuccess() { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
Use the below method to delete a list of geofence Ids at once.
// Delete multiple geofences InTouch.deleteGeoFence( , new IResultListener() { @Override public void onSuccess() { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a } });
User can get an alert whenever a particular event occurs by configuring alarm to your vehicle or user. For example, an alert can be sent to the user whenever user or vehicle Enters/Exits the particular area or if the vehicle or user is Over Speeding or vehicle battery is low, etc. etc. These alerts are highly configurable based on different requirements.
Some of the important and more frequently used alarms for different use cases are listed below.
Configure geofence alarm by assigning the vehicle to particular Geofence to get an alert when the user or vehicle enters/ exits the particular area. Geofence should be created before assigning the vehicle to geofence in alarms configuration. Refer Create Geofence documentation to create Geofence. Get Geofence method will fetch Geofence Ids.
Mandatory parameters:Configure Ignition alarm to trigger an alert when the vehicle ignition is switched On or Off. Assign vehicles against this alarm.
Manadatory ParametersConfigure Overspeed alarm to trigger an alert when user or vehicle crosses the configured speed limit.
Mandatory parameters:Configure an unplugged alarm to trigger an alert when a vehicle tracking device is removed from the vehicle battery
Mandatory parameters:Configure Panic alert using the below method. Assign this alert to the device to trigger an alert whenever the user presses the panic button.
Mandatory parameters:Configure Stoppage alarm to alert you when the user or vehicle continuously stays in the stopped condition for more than the defined duration.
Mandatory parameters:Configure Idle alarm to alert you when the vehicle continuously stays in the Idle condition (Engine is on but the speed is less than 7 km/hr) for more than the defined duration.
Mandatory parameters:Configure Towing alarm to alert you when the vehicle moves at more than 7km/hr speed in Engine off state.
Mandatory parameters:GPRS connectivity alarm alerts you when the user or vehicle doesn't send the data to server for more than the defined duration as per configuration.
Mandatory parameters:Configure Vehicle battery alarm to alert you when the vehicle battery goes below the configured voltage value.
Mandatory parameters:Configure Mileage alarm to alert you when the vehicle or user travels the configured distance within the time duration. The distance can be configured for Daily and Monthly limit.
Mandatory parameters:Configure GPS connectivity alarm to trigger an alert when the user or vehicle doesn't send the valid location to the server for more than the defined duration as per configuration.
Mandatory parameters:Configure Distance covered alarm to trigger an alert when the vehicle or user covers the particular distance in the given duration or if the user travels less than the limit in the given duration then the alert will be triggered.
There are two types of distance covered alarm.For example At least will be used whenever a user doesn't travel 30 km within 1 hr.
At most can be used when the user travels more than 30 km in 1hr.
Mandatory parameters:Configure Internal battery alarm to alert you when the Vehicle Tracking device Internal battery goes below the configured voltage value for a certain duration.
Mandatory parameters:Define the hashmap as mentioned above based on the required alarm then call the below method.
// ICreateAlarmListener - returns success if alarm created successfully, else error as callback methods. InTouch.createAlarm(hashMap, new ICreateAlarmListener() { @Override public void onSuccess(CreateAlarmResponse createAlarmResponse) { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } }); });
Note:- User can use these request parameters as key in HashMap<String, String> according to different alarms type and mandatory fields required for that alarm type.
User may use InTouchConstants class of InTouch Sdk for different alarm type values like for geofence alarm type is 26, user can use InTouchConstants.ALARM_GEOFENCE instead of 26.
Response CodeCreateAlarmResponse class object returns the API response as JSON object.
id (Long) Id of the newly created Alarm.
Use the below methods to retrieve the configured alarms in your account with unique alarm ID.
In the getAlarmConfigs(), Input parameters like devices or Alarm type or Alarm Ids can be passed to filter the particular set alarm configurations.
\\\ Get all Alarm config // IGetAlarmsListener - returns all alarms configurations if success, else error as callback methods. InTouch.getAlarmConfigs(new IGetAlarmsListener() { @Override public void onSuccess(InTouchAlarmResponse inTouchAlarmResponse) { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
In the getAlarmConfigs(), Input parameters like devices or Alarm type or Alarm Ids can be passed to filter the particular set alarm configurations.
// Alarms configurations on the basis of different selected parameters. User can pass null if none of the given parameters is required. InTouch.getAlarmConfigs(array of alarmIds, array of deviceIds, array of alarmTypes,new IGetAlarmsListener() { @Override public void onSuccess(InTouchAlarmResponse inTouchAlarmResponse) { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
1.alarmIds (Long[]) Array of alarmIds. User can pass alarmIds array to get alarm configurations for provided ids otherwise pass null for all configurations. 2. deviceIds (Long[]) Array of deviceIds. User can pass deviceIds array for selected devices alarm configurations otherwise pass null for all configurations. 3. alarmTypes (Integer[]) Array of alarm types. User can pass alarm types array for selected alarm type alarms configurations otherwise pass null for all configurations.
Response CodeInTouchAlarmResponse class object returns the API response as a JSON object.
- ListAlarmsConfig List of AlarmsConfig.
Already created alarms can be updated using below-mentioned methods. It is similar to create alarm but additionally, alarm ID should be the input parameter to update the respective individual alarm configurations.
Alarm Id can be fetched from the Get Alarm config
Based on the Alarm type, Mandatory parameter should be passed in the Hashmap.
// IUpdateAlarmListener - returns success if alarm updated successfully, else error as callback methods. InTouch.updateAlarm(alarmId, HashMap of Alarm Parameters, new IUpdateAlarmListener() { @Override public void onSuccess() { // write your vode here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
API response will return as IUpdateAlarmListener onSuccess() or onError(String reason, String errorIdentifier, String errorDescription) methods.
deleteAlarm method can be used to delete the already configured alarm. In this method, alarm ID needs to be passed to delete the configurations.
// Delete single alarm // IResultListener- returns success if alarm deleted successfully, else error as callback methods. InTouch.deleteAlarm(alarmId, new IResultListener() { @Override public void onSuccess() { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
Delete multiple alarm InTouch.deleteAlarm(alarmIds array, new IResultListener() { @Override public void onSuccess() { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
Once the alert is triggered based on the configured alarms, the below method can be used to get the Alarm log details. Alarm log gives the information about the device name, Alarm type location and time at which alert is being triggered.
Get all type of alarm log between the start and end time of the input using the below method.
// Get Alarm Logs // IGetAlarmsLogsListener - returns all alram logs if success, else error as callback methods. InTouch.getAlarmsLogs(startTime endTime, new IGetAlarmsLogsListener() { @Override public void onSuccess(InTouchAlarmLogsResponse inTouchAlarmLogsResponse) { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
Get the filtered alarm log information between the start and end time by sending the filter details like device id, Alarm type.
with filter InTouch.getAlarmsLogs(deviceIds array, alarmType array,startTime ,endTime, new IGetAlarmsLogsListener() { @Override public void onSuccess(InTouchAlarmLogsResponse inTouchAlarmLogsResponse) { // write your code here. } @Override public void onError(String reason, String errorIdentifier, String errorDescription) { // reason gives the error type. // errorIdentifier gives information about error code. // error description gives a message for a particular error. } });
InTouchAlarmResponse Class object returns the API response as JSON object.
- ListAlarmLogs List of AlarmLogs.
1. [AUTHORIZATION_ERROR](Mapmyindia)
Your free trial ended or account was not renewed.
2. [GPS_PROVIDER_DISABLED_ERROR](mapmyindia)
Tracking won't start due to disabled gps.
3. [INVALID_PUBLISHABLE_KEY_ERROR](mapyindia)
The publishable key is invalid.
4. [PERMISSION_DENIED_ERROR](mapmyindia)
Tracking won't start due to denied (or absent) permission.
5. [UNKNOWN_ERROR](mapmyindia)
An error that we couldn't recognize.
ALARM_IGNITION = 21;
ALARM_OVERSPEED = 22;
ALARM_UNPLUGGED = 23;
ALARM_PANIC = 24;
ALARM_GEOFENCE = 26;
ALARM_STOPPAGE = 27;
ALARM_IDLE = 28;
ALARM_TOWING = 29;
ALARM_GPRS_CONNECTIVITY = 126;
ALARM_VEHICLE_BATTERY = 129
ALARM_MILEAGE = 133;
ALARM_GPS_CONNECTIVITY = 146;
ALARM_DISTANCE_COVERED = 151;
ALARM_INTERNAL_BATTERY_VOLTAGE = 161;
ALARM_GEOFENCE_ENTRY_EXIT = 1;
ALARM_GEOFENCE_ENTRY = 2;
ALARM_GEOFENCE_EXIT = 3;
ALARM_GEOFENCE_STAY_LONG = 4;
ALARM_IGNITION_ON_OFF = 1;
ALARM_IGNITION_ON = 2;
ALARM_IGNITION_OFF = 3;
ALARM_DAY_FIRST_IGNITION = 5;
AALARM_MILEAGE_DAILY = 0;
ALARM_MILEAGE_MONTHLY = 1;
ALARM_DISTANCE_COVERED_ATLEAST = 1;
ALARM_DISTANCE_COVERED_ATMOST = 2;