본문으로 건너뛰기

안드로이드 SDK 가이드

해당 문서는 최신버전 의 SDK를 기준으로 작성되었습니다.

SDK 정보

SDK 지원 버전

  • minSdkVersion 19

SDK 적용

"loplat SDK를 사용하기 위해서는 API 키가 필요합니다."

loplat SDK를 사용하기 위해서는 로플랫에서 제공하는 ID와 Secret 키를 발급받아야 합니다.
발급을 원하시는 기업, 개발자는 아래의 내용을 기입하여 business@loplat.com 으로 보내주시기 바랍니다.

  • 이름
  • 회사
  • 사용 목적

권한

  • 자동 추가 권한 - SDK를 적용하면 아래 권한이 자동으로 추가됩니다.

    • ACCESS_FINE_LOCATION : GPS를 이용하여 현재 위치의 위도와 경도 값을 획득할 수 있는 권한
    • ACCESS_COARSE_LOCATION : WiFi 혹은 Network를 이용하여 현재 위치의 위도와 경도 값을 획득할 수 있는 권한
    • ACCESS_NETWORK_STATE : 네트워크 상태를 확인할 수 있는 권한
    • ACCESS_WIFI_STATE / CHANGE_WIFI_STATE : 주변 WiFi AP들을 스캔하기 위한 권한
    • INTERNET : 인터넷을 사용할 수 있는 권한
    • RECEIVE_BOOT_COMPLETED : 핸드폰 부팅되는 과정을 브로드캐스팅하기 위한 권한
    • FOREGROUND_SERVICE : 지속적인 위치 수집을 위한 권한
    • AD_ID : 로플랫에서 유저를 특정하기 위한 권한
    • USE_EXACT_ALARM : (android 15 이후) 로플랫에서 정확한 시간에 위치 알림을 주기 위한 권한
    <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"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="com.google.android.gms.permission.AD_ID" />
    <uses-permission android:name="android.permission.USE_EXACT_ALARM"
    android:minSdkVersion="35" />
android 15 이후로는 'USE_EXACT_ALARM' 권한이 없으면 백그라운드에서 SDK 동작을 오래 유지하지 못합니다.

안드로이드 15의 백그라운드 제한으로 인해 앱이 백그라운드로 이동하면 상대적으로 빠르게 비활성 상태가 됩니다.
백그라운드 앱을 활성 상태로 유지하고 정확한 시간에 위치 정보를 제공하기 위해서는 'USE_EXACT_ALARM' 권한이 필요합니다.

'USE_EXACT_ALARM' 권한을 가진 앱을 플레이 스토어에 출시할 때는 권한에 대한 검수 과정이 필요합니다.

'USE_EXACT_ALARM' 권한이 있으면 방문한 장소에 대한 위치 정보를 정확하게 제공한다는 장점이 있는 반면에 추가된 권한의 목적을 설명하는 검수 과정이 필요하고 검수 기간동안 앱 게시까지 시간이 지연될 수 있습니다.

검수에 관한 자세한 내용은 다음 링크를 확인해주세요.

  • 수동 추가 권한 - 개발자가 직접 앱 AndroidManifest.xml에 권한 추가

    • POST_NOTIFICATIONS : targetSdkVersion 33 이상일 경우 알림 허용 권한을 추가해야 합니다. 안드로이드 정책에 따라 사용자에게 해당 권한에 대해 설명하고 동의를 받아야 합니다.

    • ACCESS_BACKGROUND_LOCATION : targetSdkVersion 29 이상일 경우 백그라운드 위치 액세스(위치-항상허용)를 하기 위해 추가해야 합니다. 구글의 백그라운드 위치 정책에 따라 항상허용이 필요한 UX를 설명하고 사용자의 동의를 받아야 합니다.

    • ACTIVITY_RECOGNITION : 사용자 행동 기반으로 민첩하고 효율적으로 위치 획득이 가능하므로 추가하기를 권장합니다. targeSdkVersion 29 이상부터 사용자에게 활동감지 권한 동의를 받아야 하므로 적절한 UX가 필요합니다.

    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
    앱의 targetSdkVersion 이 29 이상 활동감지 권한은 아래와 같이 추가
    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
    Android 10 미만 OS 버전들과의 호환을 위해 아래 권한도 같이 추가
    <uses-permission
    android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"
    android:maxSdkVersion="28"/>
"안드로이드 6.0부터 위치 권한 허용 & GPS가 켜저있는 상태에서만 와이파이 스캔 결과값 획득이 가능합니다."

아래의 권한이 있어야만, 와이파이 스캔을 할 수 있습니다.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  • 권한 설정과 관련하여 좀 더 자세한 사항은 Android Developers 를 참고 바랍니다.

프로젝트에 loplat SDK 추가

loplat SDK 종속성 추가 하기

  • 프로젝트 내, 최상위 build.gradle 에 아래의 코드를 추가하세요.

    allprojects {
    repositories {
    jcenter()
    mavenCentral()
    maven { url "https://maven.loplat.com/artifactory/plengi"}
    google()
    }
    }
  • 이후 앱의 build.gradle 에 아래의 코드를 추가하세요.

    implementation 'com.loplat:placeengine:[최신버전]'
    • sdk 인증을 위해 loplat client_id와 client_secret을 추가해주세요.

    • client_id, client_secret 관련 정보는 메일로 전달 합니다.

      defaultConfig {
      ...
      resValue "string", "[client_id 키명]", "[client_id]"
      resValue "string", "[clinet_secret 키명]", "[client_secret]"
      }

Firebase 제품과의 crash 방지

"이 crash 방지는 loplat SDK 2.0.9.8.4 이상 버전을 사용할 경우 반드시 설정해야 합니다"
  • Firebase 제품을 한 가지라도 사용 중이라면 loplat SDK 와 crash가 발생할 수 있습니다. 이를 방지하기 위해 FirebaseApp.initializeApp(context)Application.onCreate() 최상단에 명시적으로 호출해야 합니다.
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
FirebaseApp.initializeApp(this);
...

}
}

Android Support 라이브러리 적용

  • androidX 라이브러리를 사용한다면
implementation 'androidx.appcompat:appcompat:1.4.0'
  • appcompat-v7 라이브러리를 사용한다면 26버전 이상으로 적용해주세요.
implementation 'com.android.support:appcompat-v7:26.1.0'

Google Play Services 라이브러리 적용하기

  • (필수)효율적인 위치 정보 획득을 위해서 build.gradle 의 dependency에 아래와 같이 라이브러리 적용이 필요합니다.

    implementation 'com.google.android.gms:play-services-location:21.0.1'
  • (필수)loplat X를 사용하기 위해서 build.gradle 의 dependency에 아래와 같이 Google Play Services 라이브러리 적용이 필요합니다.

    implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
    "loplat X란 무엇인가요?"

    loplat X는 오프라인 행동 분석 및 마케팅 솔루션입니다.
    loplat X 사용을 위한 추가 작업은 loplat X 연동하기 를 참고 바랍니다.

Retrofit 및 GSON 라이브러리 적용하기
  • loplat SDK 1.7.10 이상 버전부터 위치 확인 요청시 서버와의 통신을 위해 Retrofit 및 GSON 라이브러리를 사용합니다. Retrofit 및 GSON 라이브러리 적용을 위해서 프로젝트의 build.gradle 에 아래와 같이 추가합니다.

    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.okhttp3:okhttp:3.14.9'
  • Proguard를 사용한다면, 아래와 같이 proguard 설정을 추가해야 합니다.

    -dontwarn okio.**
    -dontwarn javax.annotation.**
    # R8 compatibility for GSON, Serialization 관련한 룰보다 반드시 위에 먼저 선언
    -keepclassmembers,allowobfuscation class * {
    @com.google.gson.annotations.SerializedName <fields>;
    }
    -keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
    }
    -keep class com.loplat.placeengine.cloud.ResponseMessage** {*;}

    -keep, allowobfuscation, allowshrinking interface retrofit2.Call
    -keep, allowobfuscation, allowshrinking class retrofit2.Response

SDK 초기화

1. PlengiListener 생성

PlengiListener 인터페이스를 구현합니다.

  • loplat 서버로 부터 받은 모든 결과는 해당 리스너를 통해 전달됩니다.
  • 아래와 같은 인식 이벤트에 따른 결과를 작성합니다.
    • PlaceEvent.Enter/Nearby
public class LoplatPlengiListener implements PlengiListener {
@Override
public void listen(PlengiResponse response) {
String echoCode = response.echo_code; // setEchoCode시 전달된 echo code
if(response.result == PlengiResponse.Result.SUCCESS) {
/*
* Lite 요금제를 사용할 경우 실시간 위치기반 메시지 발송 기능 제공에 따라 Advertisement 정보만 제공됩니다.
*/
if (response.advertisement != null) {
// loplat X 광고 정보가 있을 때
// loplat SDK 통한 광고 알림을 사용하지 않고
// Custom Notification 혹은 직접 이벤트 처리 할 경우 해당 객체를 사용
}

/*
* Basic 이나 Premium 요금제를 사용할 경우 Lite 요금제 기능에 더하여 위치인식 결과 데이터를 확인할 수 있습니다.
*/
if (response.place != null) {
// response.place 값이 null이 아닌 경우만 response.placeEvent(ENTER/NEARBY) 값을 사용
int event = response.placeEvent;
if (event == PlengiResponse.PlaceEvent.ENTER) {
// 사용자가 장소에 들어 왔을 때
} else if (event == PlengiResponse.PlaceEvent.NEARBY) {
// 사용자가 장소 주변(Nearby)을 방문 했을 때
}
}

if (response.place != null) {
// 장소(매장, 섹션)가 인식 되었을 때
}
if (response.area != null) {
// 상권이 인식 되었을 때
}
if (response.complex != null) {
// 복합몰이 인식 되었을 때
}
if (response.geoFence != null) {
// GeoFence 정보
}
if (response.location != null) {
// Device 위경도
}
if (response.district != null) {
// 행정구역
}
} else {
// 위치 획득 실패 및 에러
// response.errorReason 위치 획득 실패 혹은 에러 이유가 포함 되어 있음
// errorReason -> Location Acquisition Fail(위치 획득 실패), Network Fail(네트워크 연결 실패)
// Not Allowed Client(잘못된 client id, passwrod 입력), invalid scan results
if (response.result == PlengiResponse.Result.FAIL) {
// response.errorReason 확인
} else if (response.result == PlengiResponse.Result.ERROR_CLOUD_ACCESS) {
// response.errorReason 확인
}
}
}
}
2. Plengi 인스턴스 생성 및 EventListener 등록
"Application 클래스에서 상속 받은 클래스에서 작업해주세요."

Plengi 인스턴스를 생성한 후, 1번에서 생성한 Listener 를 등록해주신 후, 생성한 Application 클래스를 AndroidManifest.xml 에 등록해주세요.

3. echoCode 등
"echoCode는 loplat SDK를 start하기 전에 등록하시는 것을 권장합니다."
  • echo_code는 로플랫과 데이터 연동시 고객사에서 분석과 조회하기 위한 사용자 식별 코드입니다. 이 코드는 오직 고객사에 전달하는 용도로만 사용되며 별도 저장하거나 활용하지 않습니다.

  • 생성한 Application 클래스(2번 항목 참조)에서 Plengi setEchoCode를 다음과 같이 선언을 합니다.

    Plengi.getInstance(this).setEchoCode("[ECHO_CODE]");
"echoCode 에는 개인정보가 포함되면 안됩니다."

이메일, 전화번호와 같은 개인정보 혹은 광고ID(ADID, IDFA)를 전달하지 마세요.

  • 예시코드
"생성한 Application 클래스는 무조건 AndroidManifest.xml에 등록해야합니다."

생성한 Application 클래스를 AndroidManifest.xml 에 등록해주세요. 등록하지 않은 경우, SDK가 동작하지 않습니다.

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" >
<!-- 이하 생략... -->
>

SDK 구동하기

Start/Stop

  • 사용자 장소/매장 방문 모니터링을 시작하거나 정지 할 수 있습니다.
1. Start
  • start는 사용자의 위치약관동의 직후 호출해주세요.

    "앱 시작 혹은 로그인 할 때 마다 사용자의 위치약관동의 여부를 매번 확인해서 start를 호출해줘야만 합니다."
  • start를 위해 clientId, clientSecret 인자값으로 전달해주셔야합니다.

  • 모니터링이 시작되면 WiFi 신호를 스캔하고 신호의 변화를 감지하여 위치를 요청합니다.

  • 사용자의 위치 정보는 PlengiEventListener로 전달됩니다.

  • 모니터링 시작은 다음과 같이 선언합니다.

    "SDK에는 Start가 중복으로 호출될 수 없도록 처리되어 있습니다."

    start를 중복 호출 하더라도 SDK 내에서 1회만 호출되도록 구현되어 있습니다.

    //Monitoring Start
    //gradle에서 client_id, client_secret을 작성했으면
    Plengi.getInstance(this).start();
    //gradle에서 client_id, client_secret을 작성하지 않았으면
    Plengi.getInstance(this).start("[CLIENT_ID]", "[CLIENT_SECRET]");
2. Stop
  • stop은 사용자의 위치약관동의에 대한 거부시에만 호출해주세요.

    "예외적인 케이스에 대해서는 Stop을 호출하면 안됩니다."

    예외적인 케이스(사용자의 위치 권한 제거, 단말기 재부팅, 앱 비정상종료 등)에도 위치 모니터링이 가능합니다.

  • 모니터링 정지는 다음과 같이 선언합니다.

    "SDK에는 Stop이 중복으로 호출될 수 없도록 처리되어 있습니다."

    stop을 중복 호출 하더라도 SDK 내에서 1회만 호출되도록 구현되어 있습니다.

    //Monitoring Stop
    Plengi.getInstance(this).stop();

장소인식결과

  • 장소 결과 값은 PlengiResponse 객체로 전달 됩니다.

Lite 요금제

  • 실시간 위치기반 메시지 발송 기능 제공에 따라 Advertisement 정보가 제공됩니다. (캠페인 성과는 loplat X에서 확인할 수 있습니다.)

  • Advertisement : 광고 (PlengiResponse.Advertisement 클래스, response.advertisement 결과 전달)

    class Advertisement {
    private int campaign_id; // loplat X 캠페인 ID
    private int msg_id; // loplat X 광고 ID
    private String title; // 광고 제목
    private String body; // 광고 내용
    private String intent; // 광고 landing page(deep link or http url)
    private String target_pkg; // 광고 대상 앱 패키지 명
    private String img; // 광고 이미지 URL
    private String client_code; // 광고에 대한 client code
    }

Basic / Premium 요금제

  • Lite 요금제 기능에 더하여 위치인식 결과 데이터를 확인할 수 있습니다.
"장소 인식 결과에 따라 PlengiResponse 객체에서 사용할 수 있는 정보가 달라집니다."

장소 인식시 인식된 장소 결과에 따라 area (상권정보), complex (복합몰) 정보가 추가로 전달됩니다. 상권만 인식된 경우에는 place 정보가 null 로 넘어가니 코드 작성시 주의 부탁드립니다.

  • echoCode ( 사용자 식별 code 값 )

    public String echo_code;	// 사용자 식별 echo code
    • setEchoCode시 전달한 echo_code 값이 전달됩니다. (PlengiListener 예시를 참고 바랍니다)
  • result (위치 인식 성공/실패)

    public int result;	// 위치 인식 성공/실패 결과
    // PlengiResponse.Result.SUCCESS -> 성공, PlengiResponse.Result.FAIL -> 실패
  • 위치 인식 실패 한 경우

    • errorReason : 위치 인식 실패한 사유

      public String errorReason;	// 실패 사유
      • 현재 위치 획득 실패: Location Acquisition Fail
      • 클라이언트 인증 실패: Not Allowed Client
  • 위치 인식 성공 한 경우

    • type : 위치 요청 타입

      public int type; 	// 위치 요청 타입
      // ResponseType.PLACE 테스트 용 TEST_refreshPlace_foreground() 요청시
      // ResponseType.PLACE_EVENT 설정된 주기에 따라 요청시
    • placeEvent : 인식된 place event 타입 (ENTER, NEARBY)

      public int placeEvent;		// 인식된 event 타입
      // PlaceEvent.NOT_AVAILABLE Place정보가 없음, Area, Complex, Geofence와 관련이 없음
      // PlaceEvent.ENTER Place에 들어감
      // PlaceEvent.NEARBY Place근처에 있음
    • place : 위치 정보 (PlengiResponse.Place 클래스, response.place로 획득 가능)

      class Place {
      public long loplatid; // 장소 id
      public String name; // 장소 이름
      public String tags; // 장소와 관련된 tag
      public int floor; // 층 정보
      public String category; // 장소 유형
      public String category_code; // 장소 유형 코드
      public double lat; // 인식된 장소의 위도
      public double lng; // 인식된 장소의 경도
      public float accuracy; // 정확도
      public float threshold; // 한계치
      public String client_code; // 클라이언트 코드
      public String address; // 장소 (구)주소
      public String address_road; // 장소 신 주소
      public String post_code; // 우편번호
      }
      • accuracy > threshold: 현재 위치 내에 있는 경우
      • 그 외에 경우: 현재 위치 근처에 있는 경우
    • Area : 상권 정보 (PlengiResponse.Area 클래스, response.area로 획득 가능)

      • 장소 위치 요청한 장소가 상권 안일 경우 상권 정보가 인식 결과에 함께 같이 전달됩니다.

      • 위도 및 경도는 아래의 조건으로 결과가 전달됩니다.

        • 장소 인식 결과값이 있다면 -> 인식된 장소 위도/경도
        • 장소 인식 결과값이 없으면 -> device의 위도/경도
      class Area {
      public int id; // Area ID
      public String name; // 상권 이름
      public String tag; // 상권 위치 [도, 시 단위 ex) 서울, 경기도, 인천]
      public double lat; // 위도
      public double lng; // 경도
      }
    • Complex : Complex(복합몰) 정보 (PlengiResponse.Complex 클래스, response.complex로 획득 가능)

      • 인식된 장소가 복합몰 내인 경우 복합몰 정보도 함께 인식 결과에 포함되어 전달됩니다.
      class Complex {
      public int id; // Complex ID
      public String name; // 복합몰 이름
      public String br/anch_name; // 복합몰 지점명
      public String category; // 카테고리
      public String category_code; // 카테고리 코드
      }
    • GeoFence : Geofence & Fence (PlengiResponse.Geofence 클래스, response.geofence 결과 전달), fence 정보는 geofence에 포함되어 전달

      class Geofence {
      private double lat; // GeoFence (중심)위도
      private double lng; // GeoFence (중심)경도
      private ArrayList<Fence> fences; // GeoFence 리스트
      }

      class Fence {
      private long gfid; // 지오펜스 관리 ID
      private float dist; // 거리; 중심 좌표와 사용자 위치 간 거리 (optional - 중심 좌표가 있는 경우만 속성값 존재)
      private String name; // 이름
      private String clientCode; // 고객사 측 관리 ID
      }
    • District : 행정구역 (PlengiResponse.District 클래스, response.district 결과 전달)

      class District {
      private String lv0_code; // 국가 코드, code만 지원
      private String lv1_code; // 시, 도
      private String lv1_name;
      private String lv2_code; // 구, 군
      private String lv2_name;
      private String lv3_code; // 동, 면
      private String lv3_name;
      }

loplat X 연동하기

"loplat X를 사용하기 위해서는 등록이 필요합니다."

미등록 시 서비스 이용에 제한이 발생할 수 있습니다. 자세한 사항은 로플랫 비즈니스팀에 문의 바랍니다.

  • loplat X 를 통해 알림(FCM 아님)를 받기 위해서는 마케팅 알림 설정 메뉴와 plengi start 전에 아래와 같은 코드 작성이 필요 합니다.

  • 직접 구현한 알림을 사용할 경우 (예시 코드 참조), 광고 정보 값은 장소인식결과 내의 Advertisement(response.advertisement)를 확인하면 됩니다.

    • 마케팅 알림 설정이 On 인 경우

      // 마케팅 알림 설정이 ON 인 경우
      // 앱이 만든 알림을 사용할 경우 (장소인식결과에서 advertisement 객체를 참고하여 알림 생성)
      Plengi.getInstance(this).enableAdNetwork(true, false);
      // SDK 가 만든 알림을 사용할 경우
      Plengi.getInstance(this).enableAdNetwork(true, true);
      // SDK 가 생성한 알림에 보여줄 icon 설정
      Plengi.getInstance(this).setAdNotiSmallIcon([small icon id]); // 알림 small icon (예시 : R.drawable.notification_icon)
      Plengi.getInstance(this).setAdNotiLargeIcon([large icon id]); // 알림 large icon (예시 : R.drawable.notification_icon)
    • 마케팅 알림 설정이 Off 인 경우

      // 마케팅 알림 설정이 OFF 인 경우
      Plengi.getInstance(this).enableAdNetwork(false);

테스트 하기

"앱을 디바이스에서 테스트하기 전에 원활한 테스트를 위하여 다음 사항을 체크해주세요"
  • 위치설정 ON
  • 위치권한 항상 허용
  • 배터리 사용량 최적화 안 함 (애플리케이션 정보 > 배터리 > 배터리 사용량 최적화 > 내 앱을 찾아 스위치 OFF(삼성 모바일 기준))
  • ADID 추적 ON (설정 > 개인정보 보호 > 광고 > 광고 개인 최적화 선택 해제 OFF(삼성 모바일 기준))
  • 네트워크 통신이 원활한 상태 (WiFi 연결 상태가 아닌 모바일 데이터 통신 상태 권장)
  • Fake GPS (Mock Location Provider) 사용금지

샘플앱