안드로이드 SDK 가이드
해당 문서는 최신버전 의 SDK를 기준으로 작성되었습니다.
SDK 정보
SDK 지원 버전
minSdkVersion
19
2.1.2.7 이후 버전은 minSdkVersion이 21로 변경될 예정입니다. SDK 사용 시 참고 바랍니다.
SDK 적용
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" />
안드로이드 15의 백그라운드 제한으로 인해 앱이 백그라운드로 이동하면 상대적으로 빠르게 비활성 상태가 됩니다.
백그라운드 앱을 활성 상태로 유지하고 정확한 시간에 위치 정보를 제공하기 위해서는 '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"/> -
아래의 권한이 있어야만, 와이파이 스캔을 할 수 있습니다.
<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 방지
- 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 등록
Plengi
인스턴스를 생성한 후, 1번에서 생성한 Listener
를 등록해주신 후, 생성한 Application
클래스를 AndroidManifest.xml
에 등록해주세요.
3. echoCode 등
-
echo_code는 로플랫과 데이터 연동시 고객사에서 분석과 조회하기 위한 사용자 식별 코드입니다. 이 코드는 오직 고객사에 전달하는 용도로만 사용되며 별도 저장하거나 활용하지 않습니다.
-
생성한 Application 클래스(2번 항목 참조)에서 Plengi setEchoCode를 다음과 같이 선언을 합니다.
Plengi.getInstance(this).setEchoCode("[ECHO_CODE]");
echoCode
에는 개인정보가 포함되면 안됩니다."이메일, 전화번호와 같은 개인정보 혹은 광고ID(ADID, IDFA)를 전달하지 마세요.
- 예시코드
생성한 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
인자값으로 전달해주셔야합니다.clientId
/clientSecret
: loplat server로 접근하기 위한 ID와 PW입니다.- gradle에 client_id, client_secret을 작성하셨으면 파라미터를 넣지 않으셔도 gradle의 값으로 동작합니다.
-
모니터링이 시작되면 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 를 통해 알림(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) 사용금지
- 자체 심카드가 꼽혀 있는 기기 이용 (테더링을 제공하거나 테더링 제공 받아 테스트 금지)
샘플앱
- 샘플앱 다운로드 : https://github.com/loplat/loplat-sdk-android
- 샘플앱도 Gradle을 사용합니다. Gradle 사용법은 프로젝트에 로플랫 SDK 추가 에 명시되어 있습니다.
- React-Native를 사용하여 SDK API를 호출하려는 경우 React Native - Native Module 적용 샘플앱을 참고해주세요.