Skip to main content

Android SDK Guide

This document was written based on the latest version of the SDK.

SDK Information

SDK-supported version

  • minSdkVersion 19

Install SDK

"An API key is required to use the loplat SDK."

To use the loplat SDK, you must obtain an ID and Secret key provided by loplat.
Companies and developers who wish to issue a certificate should fill in the following information and send it to business@loplat.com.

  • name
  • company
  • Purpose of use

Permission

  • Automatically added permissions - The following permissions are automatically added when the SDK is installed.

  • ACCESS_FINE_LOCATION: latitude and longitude of the current location using GPS

  • ACCESS_COARSE_LOCATION: latitude and longitude of the current location using WiFi or Network

  • ACCESS_NETWORK_STATE: check the network status

  • ACCESS_WIFI_STATE / CHANGE_WIFI_STATE: scan surrounding WiFi APs

  • INTERNET: use the Internet

  • RECEIVE_BOOT_COMPLETED: broadcast after the system finishes booting

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  • Additional Permissions - Add permissions directly to AndroidManifest.xml.

  • ACCESS_BACKGROUND_LOCATION: This should be added for background location access (location-always allow) if targetSdkVersion is 29 or higher. Google's background location policy, you should always describe your UX as requiring permission and obtain user consent.

  • ACTIVITY_RECOGNITION: It is recommended to add it as it enables agile and efficient location acquisition according to the user's actions. Starting from targeSdkVersion 29 and above, the user's activity detection permission consent is required, so proper UX is required.

    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
    For which targetSdkVersion is 29 or higher, activity recognition permission is added below
    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
    The following permissions are also added for compatibility with OS versions under Android 10.
    <uses-permission
    android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"
    android:maxSdkVersion="28"/>
"Since Android 6.0, location permission is allowed & Wi-Fi scan results can only be obtained while GPS is turned on."

You must have the following permissions to scan Wi-Fi.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

Add loplat SDK to your project

Adding loplat SDK dependencies

  • Add the following code in the top-level build.gradle of your project

    allprojects {
    repositories {
    jcenter()
    mavenCentral()
    maven { url "https://maven.loplat.com/artifactory/plengi"}
    google()
    }
    }
  • Add the following code along with the above in the 'build.gradle' of your app

    implementation 'com.loplat:placeengine:[latest version]'

Prevent crashes with Firebase products

"This crash prevention must be set when using loplat SDK 2.0.9.8.4 or higher version."
  • If you are using one or more Firebase products, crashes can occur with loplat SDK. To prevent the crash, You need to call this code explicitly, FirebaseApp.initializeApp(context), at the top of Application.onCreate().
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
FirebaseApp.initializeApp(this);
...

}
}

Android Support Library Setup

  • For android libraries
implementation 'androidx.appcompat:appcompat:1.1.0'
  • For appcompat-v7 libraries, version 26 or higher is required.
implementation 'com.android.support:appcompat-v7:26.1.0'

Google Play Services Library Setup

"The Google Play Services library must be using version 11.8.0 or higher."

loplat SDK uses Google Play Services API FusedLocationProviderClient to get the current location. If you use a version earlier than 11.8.0, app operation may stop due to bugs and stability issues about the API.
For details, please refer to Google Developers - FusedLocationProviderClient.

Integrated GOOGLE PLAY SERVICES Library Setup

Only use the integrated Google Play Services library below.

implementation 'com.google.android.gms:play-services:11.8.0'
In case that you are not using the integrated GOOGLE PLAY SERVICES library
  • (Required) For efficient location information acquisition You need to apply the library to the dependencies of build.gradle as follows.

    implementation 'com.google.android.gms:play-services-location:16.0.0'
  • (Required) To use loplat X You need to apply the Google Play Services library to the dependencies of build.gradle as follows.

    implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
    "What is loplat X?"

    loplat X is an offline behavior analysis and marketing solution.
    For additional work to use loplat X, please refer to Integrating loplat X.

Retrofit / GSON library Setup
  • Starting with loplat SDK 1.7.10 and later versions, we use Retrofit and GSON libraries for communicating with the server when requesting location. Add the following to build.gradle of the project to apply Retrofit and GSON library.

    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.okhttp3:okhttp:3.11.0'
  • If you use proguard, you need to add proguard configuration.

    -dontwarn okio.**
    -dontwarn javax.annotation.**
    # (R8 compatibility for GSON Serialization) Declared before related rules
    -keepclassmembers,allowobfuscation class * {
    @com.google.gson.annotations.SerializedName <fields>;
    }
    -keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
    }

SDK initialization

1. Generate PlengiListener

Implement the interface PlengiListener.

  • All results received from the loplat server are passed through the PlengiListener.

  • Create results based on recognition events.

    • PLACE_EVENT (Enter/Leave/Nearby, Recognizer mode)
    • PLACE_TRACKING (Enter/Leave/Nearby, Tracker mode)
public class LoplatPlengiListener implements PlengiListener {
@Override
public void listen(PlengiResponse response) {
String echoCode = response.echo_code; // echo code passed when calling setEchoCode
if(response.result == PlengiResponse.Result.SUCCESS) {
/*
* If you use Lite, you will only receive advertising information as per the ability to send time-location-based messages.
*/
if (response.advertisement != null) {
// Has loplat X Advertisement information
// Without using ad notifications via loplat SDK
// Custom Notification Or When handling events directly, use the corresponding object
}

/*
* If you are using the Basic or Premium plan, you can check the location recognition result data in addition to the Lite plan features.
*/
if (response.place != null) {
// Use response.placeEvent(ENTER/LEAVE/NEARBY) values only if response.place value is not null
int event = response.placeEvent;
if (event == PlengiResponse.PlaceEvent.ENTER) {
// When a user enters a place
} else if (event == PlengiResponse.PlaceEvent.LEAVE) {
// When a user leaves the most recent location
} else if (event == PlengiResponse.PlaceEvent.NEARBY) {
// When a user visits a place (Nearby)
}
}

if (response.place != null) {
// When a place (store, section) is recognized
}
if (response.area != null) {
// When commercial rights are recognized
}
if (response.complex != null) {
// When a compound mole is recognized
}
if (response.geoFence != null) {
// GeoFences Information
}
if (response.location != null) {
// Device latitude and longitude
}
if (response.district != null) {
// administrative district
}
} else {
// Location acquisition failures and errors
// response.errorReason
// errorReason -> Location Acquisition Fail, Network Fail
// Not Allowed Client(Incorrect client_id or password), invalid scan results
if (response.result == PlengiResponse.Result.FAIL) {
// response.errorReason check
} else if (response.result == PlengiResponse.Result.ERROR_CLOUD_ACCESS) {
// response.errorReason check
}
}
}
}
2. Create Plengi instance and register EventListener
"Declare in the class inherited from the Application class."

After creating an Plengi instance, register the Listener created in step 1, and then register the created Application class in AndroidManifest.xml.

3. echoCode
"echoCode must be registered before starting the loplat SDK."
  • echo_code is an ID for user identification (for management) and tracking in the app (ex, Ad id,id,....,etc.).

  • In the created Application class (refer to 2), declare Plengi setEchoCode as follows.

    Plengi.getInstance(this).setEchoCode("[ECHO_CODE]");
"echoCode must not contain personal information."

such as email and phone number.

  • example code
"The Application class you created must be registered in AndroidManifest.xml."

Register the created Application class in AndroidManifest.xml. If not registered, the SDK will not work.

public class LoplatSampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Plengi.getInstance(this).setListener(new LoplatPlengiListener());
Plengi.getInstance(this).setEchoCode("[ECHO_CODE]");
}
}
<application
android:name=".LoplatSampleApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- skip… -->
>

Running the SDK

Start/Stop

  • You can start or stop monitoring user places/store visits. Call start right after the user agrees to the location terms and conditions.

    "Every time the app starts or logs in, you must call start after checking whether the user agrees to the location terms and conditions."
    "The SDK prevents Start/Stop from being called redundantly."

    Even if start/stop is called repeatedly, it is implemented to be called only once within the SDK.

    "Do not call Stop, in exceptional cases."

    Do not call stop for exceptional cases. Call stop only when the user refuses to agree to the location agreement.

    • For start, clientId, clientSecret should be passed as argument values.

    • clientId / clientSecret : ID and PW to access the loplat server.

  • It scans the WiFi signal at set intervals and requests a location by detecting changes in the signal.

  • The user's location information is passed to PlengiEventListener.

  • The start and stop of monitoring are declared as follows.

    Plengi.getInstance(this).start("[CLIENT_ID]", "[CLIENT_SECRET]"); //Monitoring Start
    Plengi.getInstance(this).stop(); //Monitoring Stop

Place recognition result

  • The location result value is passed as a PlengiResponse object.

Lite Plan

  • Advertising information is provided in response to real-time location-based messaging functionality. (Campaign’s achievements can be seen on loplat X.)

  • Advertisement : Advertisement (PlengiResponse.Advertisement Class, response.advertisement delivery of results)

    class Advertisement {
    private int campaign_id; // loplat X Campaign ID
    private int msg_id; // loplat X Advertisement ID
    private String title; // advertisement title
    private String body; // advertisement description
    private String intent; // advertisement landing page(deep link or HTTP URL)
    private String target_pkg; // Ad target app package name
    private String img; // advertisement Image URL
    private String client_code; // about advertisement’s client code
    }

Basic/Premium plan

  • In addition to the features of the Lite plan, you can check the location recognition result data.
"Different information is available in the PlengiResponse object depending on the place recognition result."

When recognizing a place, area (commerce information) and complex (complex mall) information are delivered according to the result of the recognized place. If only the commercial area is recognized, the place information is passed as null, so please be careful when writing the code.

  • echoCode (User identification code value)

    public String echo_code;	// user identification echo code
    • The echo_code value will be passed when setEchoCode is passed. (Please refer to the PlengiListener example)
  • result (Location recognition success/failure)

    public int result;	// Location recognition success/failure Result
    // PlengiResponse.Result.SUCCESS -> success, PlengiResponse.Result.FAIL -> failure
  • Failure case of location recognition

    • errorReason : Reasons for Location recognition Failure

      public String errorReason;	// reason for failure
      • Failed to get current location: Location Acquisition Fail
      • Client Authentication Failed: Not Allowed Client
  • Successful case of Location Recognition

    • type : location request type

      public int type; 	// location request type
      // ResponseType.PLACE On request TEST_refreshPlace_foreground() for testing
      // ResponseType.PLACE_EVENT Upon request, according to the set cycle
    • placeEvent : Recognized place event types (ENTER, NEARBY, LEAVE)

      public int placeEvent;		// Recognized event type
      // PlaceEvent.NOT_AVAILABLE No Place information, not related to Area, Complex, or Geofence
      // PlaceEvent.ENTER Enter Place
      // PlaceEvent.LEAVE Leave Place
      // PlaceEvent.NEARBY Nearby Place
      • place : Location information (PlengiResponse.Place class, can be obtained with response.place)
      class Place {
      public long loplatid; // location id
      public String name; // location name
      public String tags; // related to places
      public int floor; // floor info
      public String category; // place category
      public String category_code; // place category code
      public double lat; // latitude of the recognized place
      public double lng; // longitude of the recognized place
      public float accuracy; // accuracy
      public float threshold; // Threshold
      public String client_code; // client code
      public String address; // Place (old) address
      public String address_road; // place new address
      public String post; // Zip code
      }
      • accuracy > threshold: if you are in the current position
      • Elsewhere: if you are near your current location
    • Area: Commercial area information (PlengiResponse.Area class, can be obtained through response.area)

      • If the place is within the commercial area, the commercial area information is delivered along with the recognition result.

      • The result is delivered under the following conditions for latitude and longitude.

        • recognition result value -> latitude/longitude for recognized places
        • no recognition result -> latitude/longitude of devices
      class Area {
      public int id; // Area ID
      public String name; // commercial name
      public String tag; // commercial location tag
      public double lat; // latitude
      public double lng; // longitude
      }
    • Complex : Complex information (PlengiResponse.Complexclass, can be obtained throughresponse.complex)

      • If the recognized place is within a complex mall, the complex mall information is also included in the recognition result and delivered.
      class Complex {
      public int id; // Complex ID
      public String name; // Complex name
      public String branch_name; // Complex branch name
      public String category; // complex category
      public String category_code; // category code
      }
    • GeoFence : Geofence & Fence (PlengiResponse.Geofence class, response.geofence Result), Fence information is included in geofence and transmitted

      class Geofence {
      private double lat; // GeoFence (center) latitude
      private double lng; // GeoFence (center) longitude
      private ArrayList<Fence> fences; // List of GeoFences
      }

      class Fence {
      private long gfid; // Geofence management ID
      private float dist; // distance; Distance between the center coordinates and the user's location (optional - Property values exist only when there are center coordinates)
      private String name; // geofence name
      private String clientCode; // Customer-side managed ID
      }
    • District : administrative district (PlengiResponse.District class, response.district Result)

      class District {
      private String lv0_code; // Country code, code only supported
      private String lv1_code;
      private String lv1_name;
      private String lv2_code;
      private String lv2_name;
      private String lv3_code;
      private String lv3_name;
      }

Integrating loplat X

"Registration is required to use loplat X."

Unregistered use of the service may be restricted. For details, please get in touch with the loplat Business Team.

  • To receive notification (not FCM) through loplat X, the marketing notification setting menu and the code below must be written before plengi start.

  • When using a notification implemented by yourself (refer to the example code), you can check the Advertisement(response.advertisement) in the place recognition result for the advertisement information value.

    • If the marketing notification setting is On

      // marketing notification setting On
      // When using notifications created by the app (notifications are created by referring to the advertisement object in the place recognition result)
      Plengi.getInstance(this).enableAdNetwork(true, false);
      // When using notifications created by the SDK
      Plengi.getInstance(this).enableAdNetwork(true, true);
      // Set an icon to be displayed in notifications created by the SDK
      Plengi.getInstance(this).setAdNotiSmallIcon([small icon id]); // alarm small icon (exam : R.drawable.notification_icon)
      Plengi.getInstance(this).setAdNotiLargeIcon([large icon id]); // alarm large icon (exam : R.drawable.notification_icon)
    • If the marketing notification setting is Off

      // marketing notification setting Off
      Plengi.getInstance(this).enableAdNetwork(false);

Do Test

"Before testing the app on a device, please check the following for smooth testing."
  • location setting ON
  • Location Permission Allow all the time
  • No battery usage optimization (Application Information > Battery > Optimize Battery Usage > Find My Apps and switch OFF (Samsung Mobile))
  • ADID Tracking ON (Settings > Privacy > Advertising > Opt out Ads Personalization by selecting OFF (Samsung Mobile))
  • Good Network status (Mobile data communication status not WiFi connection is recommended)
  • Do not use fake GPS (Mock Location Provider)

sample app