BuzzScreen Migration SDK 연동

Introduction

반드시 버즈빌 BD 팀과 협의 후 진행해야 하며, 가이드를 반영한 M앱과 L앱의 APK 파일을 마켓에 업로드하기 전에 버즈빌 BD 팀에 전달하여 반드시 리뷰를 거쳐야 합니다.

구글 정책 대응을 위해, 기존 버즈스크린을 연동한 어플리케이션의 잠금화면을 새로운 잠금화면 전용 어플리케이션의 잠금화면으로 마이그레이션 하기 위한 가이드입니다. 아래의 사항을 숙지한 후 연동을 진행해주세요.

  • 용어 정의

    • 이하 기존 버즈스크린을 연동한 어플리케이션을 “M(Main) 앱”으로 지칭하고,

    • 새로운 잠금화면 전용 어플리케이션을 “L(LockScreen) 앱”으로 지칭합니다.

  • 요약: 이 SDK 의 연동작업을 통해, M앱의 버즈스크린 사용자를 L앱의 버즈스크린 사용자로 자연스럽게 & 최소한의 연동 코스트로 전환 가능합니다.

    • 사용 상황: L앱 내에 자체 로그인 기능 구현이 어렵거나 / M앱의 로그인 관리를 그대로 L앱에서 사용하고 싶은 경우

      • 필요한 유저 정보(유저아이디, 나이, 성별 등) 및 잠금화면 활성화 동의 여부를 M앱에서 수집하여 L앱으로 가져올 수 있도록 SDK에서 지원합니다. 따라서 L앱의 자체 로그인 시스템이 불필요합니다.

    • 보안: 다른 앱에서의 접근을 막기 위해 안드로이드의 protectionLevel="signature" 권한을 사용합니다.

    • 참고: L앱의 설치 (APK 파일 다운로드 & 설치) 는 유저의 액션 없이 진행할 수 없기에 자동화가 불가능합니다.

Migration SDK Workflow

 


M앱 마이그레이션 구현

Basic Usage

  • 버즈스크린 연동에 필요한 유저 프로필 정보는 기존처럼 M앱에서 수집하고, 마이그레이션 SDK를 통해 L앱으로 자동으로 전달됩니다.

  • M앱은 마이그레이션 이후에도 L앱에서 잠금화면 활성화에 필요한 정보들을 제공해주는 역할을 합니다.

  • L앱은 항상 실행 시에 M앱의 상태를 체크하여 L앱의 잠금화면 활성화 가능 여부를 판단합니다.

1. build.gradle 설정

1) manifestPlaceholders 추가

1 2 3 4 5 6 android { defaultConfig { // my_app_key 에는 버즈스크린 연동 시 발급받은 앱키를 입력합니다. manifestPlaceholders = [buzzScreenAppKey:"my_app_key"] } }

2) dependencies 에 추가

M앱을 위한 마이그레이션 라이브러리를 추가하고, BuzzScreen SDK 버전 1.6.3 이상으로 업데이트해야 합니다.

기존 버즈스크린 연동

M앱을 위한 마이그레이션 라이브러리
1 2 3 4 5 6 7 8 9 10 11 12 13 repositories { maven { url "https://dl.bintray.com/buzzvil/maven/" } } ... dependencies { // 라이브러리명이 L앱과 다름에 주의! implementation 'com.buzzvil.buzzscreen.ext:migration-host:1.4.0' // (optional) migration SDK에서 제공하는 암호화를 사용하는 경우, 아래의 library를 추가해 주어야 합니다. // implementation 'com.github.joshjdevl.libsodiumjni:libsodium-jni-aar:1.0.8' }

 

2. Application Class 에 코드 추가

기존 버즈스크린 연동을 위해 추가한 BuzzScreen.init 다음에 MigrationHost.init을 호출합니다.

  • MigrationHost.init(Context context, String lockScreenPackageName) : 마이그레이션을 위한 M앱의 초기화 코드

    • Parameters

      • context : Application context 를 this 로 전달

      • lockScreenPackageName : L앱의 패키지명

    • 사용 예시

      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class App extends Application { @Override public void onCreate() { super.onCreate(); // 기존 버즈스크린 초기화 코드. BuzzScreen.init("app_key", this, SimpleLockerActivity.class, R.drawable.image_on_fail); // 마이그레이션을 위한 초기화 // L앱의 패키지명이 com.buzzvil.buzzscreen.sample_lock_light 인 경우 사용 예시 MigrationHost.init(this, "com.buzzvil.buzzscreen.sample_lock_light"); // L앱에서 버즈스크린이 활성화되어 M앱에서 잠금화면이 비활성화 되는 경우 호출되는 리스너 등록 예시 MigrationHost.setOnDeactivatedByLockScreenAppListener(new MigrationHost.OnDeactivatedByLockScreenAppListener() { @Override public void onDeactivated() { Log.i("MainApp", "LockScreen is deactivated by LockScreen App"); } }); } }

3. 잠금화면 활성화 화면 변경

L앱은 M앱의 유저 정보로 잠금화면을 활성화 할 뿐 직접 유저에게 정보나 동의를 받는 과정이 없습니다. 이 때문에 L앱에서는 M앱의 잠금화면 활성화 화면 (유저 프로필, 사용동의, 활성화/비활성화 설정 화면) 을 변경하여 사용하게 됩니다.

항목

코드

내용

항목

코드

내용

1

M앱의 잠금화면 활성화 화면으로 이동하는 딥링크 설정

-

  • L앱에서 잠금화면 활성화에 필요한 정보나 유저 사용 동의가 필요한 경우 M앱의 잠금화면 활성화 화면으로 이동시켜 이 과정을 진행합니다.

  • 만약 해당 딥링크가 없으면 M앱의 초기화면을 실행합니다.

2

L앱을 통해 잠금화면 활성화

MigrationHost.requestActivationWithLaunch()

  • L앱이 설치되지 않은 경우 마켓을 통해 설치 후 자동으로 활성화됨

  • L앱이 설치된 경우 L앱을 실행하면서 자동으로 잠금화면이 활성화됨

앱 내의 잠금화면 활성화 화면에서 활성화/비활성화를 설정하는 스위치를 배너 형태로 변경합니다. 해당 배너 클릭 시, 혹은 잠금화면 사용 동의를 받고 잠금화면을 활성화 하는 곳 (기존 BuzzScreen.getInstance().activate() 호출하는 지점과 동일) 에서 본 함수를 호출합니다.

  • 마이그레이션을 지원하는 M앱 버전에서는 이 배너가 L앱으로 마이그레이션을 수행하는 하나의 채널이 될 뿐만 아니라, M앱에서 잠금화면을 처음으로 사용하려는 유저를 L앱으로 유도하는 채널이 되기도 합니다.

MigrationHost.requestActivationWithLaunch() 을 호출하기 전에도 이전 버즈스크린 연동처럼 BuzzScreen.getInstance().getUserProfile()를 통해 유저 정보를 설정하는 코드는 미리 호출되어야 합니다. 이 정보를 그대로 L앱에서 활용하여 잠금화면이 활성화됩니다.

L앱 잠금화면 활성화 과정

 

4. 로그아웃 처리

M앱에서 로그아웃이 일어나는 경우 아래 두 함수를 호출합니다.
L앱에서의 잠금화면을 비활성화하고, 다음 활성화 시에 L앱에서 새로운 유저 정보를 M앱으로부터 제공받기 위함입니다.

  • BuzzScreen.getInstance().logout() : M앱에서 잠금화면을 비활성화하고, 유저정보를 초기화합니다.

  • MigrationHost.requestDeactivation() : L앱에서 잠금화면이 활성화되어 있는 경우 해당 잠금화면을 비활성화합니다.

+. 버즈스크린 활성화/비활성화 관련 코드 제거 선택

M앱에서 L앱으로의 마이그레이션 이후 M앱의 잠금화면을 지원하지 않을 경우, 잠금화면 활성화/비활성화를 위해 삽입했던 BuzzScreen.getInstance().activate(), BuzzScreen.getInstance().deactivate() 코드를 모두 제거합니다.

 

Advanced Usage

그 외 유용한 함수들

항목

코드

내용

항목

코드

내용

L앱의 잠금화면 활성화 여부 확인

MigrationHost.isLockScreenAppActivated()

  • L앱에서 잠금화면이 활성화되어 있으면 true

  • 비활성화되어 있으면 false를 리턴

M앱에서 변경된 유저 아이디를 L앱에 동기화

MigrationHost.requestUserProfileSync(boolean encrypt)

기존 M앱에서 주기적으로 유저 아이디가 변경되는 경우에는, setUserId() 호출 이후에 이 함수를 호출하여 L앱에도 변경된 유저 정보값으로 동기화를 합니다.

  • encrypt 선택 : 유저 정보값 동기화 시 L앱에 전달하는 유저 정보를 암호화하기 위한 인자입니다. 암호화하고자 하는 경우 encrypttrue를 전달하여 호출합니다.

    • v1.0.2.0 이상에서 사용 가능

이 함수를 호출하지 않으면 L앱에서는 다음 checkAvailability 호출 전까지는 변경된 유저 정보가 반영되지 않습니다.

커스텀 마켓 링크 설정

MigrationHost.setLockScreenAppMarketLink(String link)

  • 호출 위치: requestActivationWithLaunch() 전에 설정해야 함

requestActivationWithLaunch() 통해 L앱 설치하는 경우, 패키지명으로 생성된 기본 마켓 uri 가 아닌 유입 경로 분석을 위해 커스텀 링크를 적용하고 싶으면 이 함수를 사용합니다.

  • Parameters

    • link : 커스텀 마켓 링크

L앱의 실행 없이 L앱의 잠금화면 활성화

MigrationHost.requestActivation(OnRequestActivateResponseListener listener, boolean encrypt)

MigrationHost.requestActivationWithLaunch() 와 다른 점은 L앱의 실행없이 L앱의 잠금화면이 활성화 된다는 점입니다.

M앱의 MigrationHost 0.9.4 이상에서 호출되어야 하며, L앱 역시 MigrationClient 0.9.4 이상이 적용되어야 합니다.

잠금화면을 활성화 할때는 M앱에서 설정된 유저 정보를 사용하게 됩니다.

  • Parameters

    • OnRequestActivateResponseListener

      • onAlreadyActivated() : L앱에서 버즈스크린이 이미 활성화가 되어있는 경우 호출됩니다.

      • onActivated() : L앱에서 버즈스크린이 활성화가 된 경우 호출됩니다.

      • onError(RequestActivationError error) : L앱의 버즈스크린 활성화에 실패한 경우 호출됩니다.

        • LOCKSCREEN_APP_NOT_INSTALLED : L앱이 설치되지 않아 활성화에 실패한 경우

        • LOCKSCREEN_APP_MIGRATION_NOT_SUPPORTED : L앱에서 마이그레이션 연동이 되지 않아 활성화에 실패한 경우

        • UNKNOWN_ERROR : 잘못된 연동 혹은 일시적인 에러로 발생한 경우

    • encrypt 선택: 잠금화면 활성화 시 L앱에 전달하는 유저 정보를 암호화하기 위한 인자입니다. 암호화하고자 하는 경우 encrypttrue를 전달하여 호출합니다.

      • v1.0.2.0 이상에서 사용 가능

 


 

L앱 마이그레이션 구현

항목

내용

항목

내용

1

유저정보 설정 및 사용 동의

  • L앱의 버즈스크린 연동에서 유저 정보 설정 과정은 따로 진행하지 않아도 됩니다.

    • 마이그레이션 SDK를 통해 M앱에서 설정된 버즈스크린 유저 정보를 그대로 가져와서 사용하게 됩니다.

  • L앱은 M앱으로부터 잠금화면에 필요한 정보와 사용자 동의를 획득하여 잠금화면을 활성화 할 수 있습니다. 기존에 M앱에서 잠금화면을 사용하고 있던 유저는 이미 잠금화면 사용 동의가 되었다고 간주합니다.

2

활성화/비활성화

  • L앱 잠금화면 활성화에 필요한 정보가 없을 경우 M앱의 잠금화면 활성화 화면을 통해 잠금화면을 활성화해야 한다고 유저에게 알려주게 됩니다.

    • 이 과정에서 M앱의 잠금화면 활성화 화면으로 연결되는 딥링크가 있으면 자연스러운 유저경험을 만들 수 있습니다.

  • M앱에서 로그아웃 시점에 MigrationHost.requestDeactivation() 를 호출하거나 M앱이 제거되면 자동으로 L앱의 잠금화면이 비활성화됩니다.

3

L앱 구현

  • L앱의 샘플을 활용하여 손쉽게 L앱을 만들 수 있습니다. (아래 Appendix 참고)

  • 마이그레이션 SDK 이외에도 통신 모듈을 사용하여 M앱과 L앱 간의 추가적인 통신을 구현할 수 있습니다. (https://buzzvil.atlassian.net/wiki/spaces/BDG/pages/386957479 참고)

    • 이를 통해 L앱에서는 M앱의 기능이나 데이터를 활용할 수 있습니다.

Basic Usage

1. build.gradle 설정

1) manifestPlaceholders 추가

1 2 3 4 5 6 android { defaultConfig { // my_app_key 에는 버즈스크린 연동 시 발급받은 앱키를 입력합니다. manifestPlaceholders = [buzzScreenAppKey:"my_app_key"] } }

2) dependencies 추가

L앱을 위한 마이그레이션 라이브러리뿐만 아니라 버즈스크린 라이브러리도 추가합니다. BuzzScreen SDK 1.6.3 버전 이상이 필요합니다.

버즈스크린 연동

L앱을 위한 마이그레이션 라이브러리
1 2 3 4 5 6 7 8 9 10 11 12 13 repositories { maven { url "https://dl.bintray.com/buzzvil/maven/" } } ... dependencies { // migration-host 와 버전이 반드시 일치해야 합니다. implementation 'com.buzzvil.buzzscreen.ext:migration-client:1.4.0' // (optional) migration SDK에서 제공하는 암호화를 사용하는 경우, 아래의 library를 추가해 주어야 합니다. // implementation 'com.github.joshjdevl.libsodiumjni:libsodium-jni-aar:1.0.8' }

2. AndroidManifest.xml 변경

버즈스크린 연동을 위해 app_license는 새로 발급 받아 L앱에 적용해야 합니다. 버즈빌 BD 매니저에게 문의해주세요.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <manifest> <application> ... <!-- Configuration for BuzzScreen--> <!-- <app_license> 를 기존 M앱과 다른 새로운 값으로 교체합니다. --> <meta-data android:name="app_license" android:value="<app_license>" /> <!-- BuzzScreen SDK 1.9.0.7 이상 사용 시 아래 plist 관련 코드는 불필요 --> <!-- <plist> 를 기존 M앱과 다른 새로운 값으로 교체합니다. --> <meta-data android:name="com.buzzvil.locker.mediation.baidu.plist" android:value="<plist>" /> </application> </manifest>

 

3. Application Class 에 코드 추가

버즈스크린 연동을 위한 BuzzScreen.init 와 마이그레이션 연동을 위한 MigrationClient.init를 순서대로 호출합니다.

항목

코드 & 호출 위치

세부내용

항목

코드 & 호출 위치

세부내용

마이그레이션을 위한 L앱의 초기화 코드 필수

MigrationClient.init(Context context, String mainPackageName)

버즈스크린 연동을 위한 BuzzScreen.init 뒤에 호출

Parameters

  • context : Application context 를 this 로 전달

  • mainPackageName : M앱의 패키지명

L앱에서의 잠금화면이 비활성화되는 경우의 리스너 등록 필수

MigrationClient.setOnDeactivatedByMainAppListener(OnDeactivatedByMainAppListener listener)

호출되는 경우

  • M앱에서 MigrationHost.requestDeactivation()를 호출한 경우

  • M앱을 삭제한 경우

Parameters

  • OnDeactivatedByMainAppListener

    • onDeactivated : L앱의 잠금화면이 비활성화 될 때 호출됨

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class App extends Application { @Override public void onCreate() { super.onCreate(); // 기존 버즈스크린 초기화 코드. BuzzScreen.init("app_key", this, SimpleLockerActivity.class, R.drawable.image_on_fail); // 마이그레이션을 위한 코드 // M앱의 패키지명이 com.buzzvil.buzzscreen.sample_main_light 인 경우 사용 예시 MigrationClient.init(this, "com.buzzvil.buzzscreen.sample_main_light"); // M앱에 의해 L앱에서의 잠금화면이 비활성화되는 경우 호출되는 리스너를 등록 예시 MigrationClient.setOnDeactivatedByMainAppListener(new MigrationClient.OnDeactivatedByMainAppListener() { @Override public void onDeactivated() { Toast.makeText(App.this, "Main App의 상태가 변경(앱 삭제, 로그아웃, 탈퇴 등)되어 잠금화면을 비활성화합니다.", Toast.LENGTH_LONG).show(); } }); } }

4. 잠금화면 활성화와 마이그레이션

L앱에서의 잠금화면 활성화는 1) M앱에서 정보 가져오기 → 2) 버즈스크린 활성화 과정으로 진행됩니다.

  1. L앱이 실행될 때 이 과정이 진행되면서 마이그레이션이 되고, 이후에도 M앱의 정보를 통해 L앱의 잠금화면을 활성화시키게 됩니다.

  2. L앱의 잠금화면이 활성화되면 자동으로 M앱의 잠금화면이 비활성화 됩니다.

버즈스크린 활성화 과정에서는 기존 버즈스크린 연동처럼 BuzzScreen.getInstance().launch()BuzzScreen.getInstance().activate() 를 그대로 사용합니다. (https://buzzvil.atlassian.net/wiki/spaces/BDG/pages/384860182 참고)

M앱의 정보를 가져오기 위해 MigrationClient에서 다음 함수를 제공합니다.

  • checkAvailability(OnCheckAvailabilityListener listener, boolean encrypt)

    • 호출 위치: L앱 진입화면의 onResume 에서 호출하여 L앱 진입 시 항상 수행되도록 합니다.

    • 비동기로 M앱에서 버즈스크린 활성화에 필요한 정보들을 가져오고, M앱의 상태에 따라 자동으로 잠금화면을 활성화합니다.

      • 자동으로 잠금화면 활성화 되는 조건

        1. M앱에서 잠금화면을 사용 중인 경우

        2. MigrationHost.requestActivationWithLaunch()를 호출하여 L앱을 실행한 경우

파라미터

리스폰스

세부내용

파라미터

리스폰스

세부내용

OnCheckAvailabilityListener필수

onAvailable(boolean autoActivated)

  • 버즈스크린을 활성화 할 수 있는 경우 호출됨

  • 잠금화면이 활성화되는 경우의 플로우: 위 ‘L앱 잠금화면 활성화 과정’ 도식 참고

onAvailable(boolean autoActivated)

autoActivated

  • 자동으로 잠금화면이 활성화되면 true

  • 그렇지 않으면 false

onError(AvailabilityCheckError error)

  • 버즈스크린을 사용할 수 없는 경우 호출됨

  • 해당 경우의 플로우는 아래 도식 참고 ('checkAvailability Error Flow')

MAIN_APP_NOT_INSTALLED

M앱이 설치되지 않은 경우

→ M앱의 설치를 유도

MAIN_APP_MIGRATION_NOT_SUPPORTED

M앱이 마이그레이션을 지원하지 않는 버전

→ M앱의 업데이트를 유도

NOT_ENOUGH_USER_INFO

버즈스크린을 활성화하는데 필요한 정보가 충분하지 않은 경우

→ M앱의 잠금화면 활성화 페이지로 이동

UNKNOWN_ERROR

잘못된 연동 혹은 일시적인 에러로 발생

  • 일시적인 에러인 경우에는 재시도를 유도

migration-client 1.0.1 이상 버전 사용시에는 UNKNOWN_ERROR 발생시 1.0.1 미만 버전과 달리 잠금화면이 자동으로 비활성화 되지 않으므로, 유저가 사용할 수 있게 비활성화 버튼을 추가해주어야 합니다.

encrypt 선택

-

  • 유저 정보값 동기화 시 M앱으로부터 전달받는 유저 정보를 암호화하기 위한 인자

  • 암호화하고자 하는 경우 encrypttrue를 전달하여 호출

v1.0.2.0 이상에서 사용 가능

checkAvailability Error Flow

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 public class MainActivity extends AppCompatActivity { private MigrationClient migrationClient = new MigrationClient(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 기존 버즈스크린 연동 BuzzScreen.getInstance().launch(); } @Override protected void onResume() { super.onResume(); migrationClient.checkAvailability(new MigrationClient.OnCheckAvailabilityListener() { @Override public void onAvailable(boolean autoActivated) { if (autoActivated) { showAutoActivatedDialog(); } // 잠금화면을 on/off 할 수 있는 레이아웃 구성 showSwitchLayout(); } @Override public void onError(MigrationClient.AvailabilityCheckError error) { switchActivateLock.setChecked(false); switch (error) { case MAIN_APP_NOT_INSTALLED: sendToPlayStore("앱이 설치되어 있지 않습니다.\n설치 링크로 이동합니다."); break; case MAIN_APP_MIGRATION_NOT_SUPPORTED: sendToPlayStore("앱이 최신 버전이 아닙니다.\n설치 링크로 이동합니다."); break; case NOT_ENOUGH_USER_INFO: // Main App 을 통해 유저 정보 및 사용자 동의를 받을 수 있도록 합니다. sendToMain(); break; case UNKNOWN_ERROR: Toast.makeText(MainActivity.this, "에러가 발생했습니다. 다시 시도해주세요.", Toast.LENGTH_SHORT).show(); break; } } }); } @Override public void onPause() { super.onPause(); // checkAvailability 를 중단하기위해 호출합니다. // 여기서 중단하지 않으면 onAvailable or onError 가 호출됩니다. migrationClient.abort(); } }

 

Advanced Usage

M앱과 L앱 간의 통신 유틸

마이그레이션 SDK에서 제공하는 기능 이외에도 M앱과 L앱 간의 통신이 필요하다면 여기서 제공하는 통신 모듈을 사용하여 개발할 수 있습니다. 자세한 내용은 https://buzzvil.atlassian.net/wiki/spaces/BDG/pages/386957479 문서를 참고해주세요.

Appendix

간단한 방법으로 L앱 빌드하기

sample_lock_light에서 확인할 수 있는 샘플 잠금화면 앱은 위 가이드의 구현을 담았을 뿐만 아니라 최소한의 기능도 구현되어있습니다. 따라서 sample_lock_light 을 다운받고 다음 과정만 진행해도 잠금화면 앱이 완성됩니다.

기능 구현

  1. build.gradle 변경 : my_app_key는 기존에 발급받았던 버즈스크린 앱키로 변경하고, applicationId 는 새롭게 만드는 잠금화면 앱의 패키지명으로 변경합니다.

  2. BuzzScreen.init() 에서 사용되는 appKey 를 신규 값으로 변경합니다.

  3. AndroidManifest.xml 변경 : <app_license>를 새롭게 발급받은 값으로 변경합니다.

  4. M앱 잠금화면 활성화 페이지 딥링크 설정 : App.java 파일 내의 DEEP_LINK_ONBOARDING 를 M앱 잠금화면 활성화 화면 딥링크로 설정합니다.

디자인 변경

  • 아이콘 : ic_launcher.png 변경

  • 색상 : res/colors.xml 변경만으로 메인 색상 적용 가능

  • 로고 : activity_main.xml에서 툴바의 로고 변경

이 외의 잠금화면 UI 및 기능 커스텀은 https://buzzvil.atlassian.net/wiki/spaces/BDG/pages/385253519 문서를 참고해주세요.

샘플앱에 대해 궁금한 사항이나 지원이 필요하다면 언제든지 버즈빌에 문의주세요.
버즈빌 기술지원팀 메일: tech-support@buzzvil.com