> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fairytech.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Option 2) 페어리 UI 이용하여 시작하기

<Tip>
  페어리 UI를 통해 서비스를 이용하는 경우, 해당 프로젝트의 법적동의 사항이 페어리를 통해 관리됩니다.

  마케팅 수신동의를 얻은 사용자에게만 광고 알림이 수신되는 방식으로 동작합니다.
</Tip>

## 사전 준비

<Warning>
  [Getting Started > Setup](/dev-guide/getting-started/setup) 을 먼저 완료하세요.
</Warning>

# 시작하기

## STEP 1)  페어리 제공 권한동의 페이지 이용하여 시작

* `launchUI` 함수를 사용하여 권한 동의 페이지에 접속할 수 있습니다.
  * `launchUI(config, redirectTo, callback)`
* redirectTo 파라미터로 `/basic-sdk/consent` 를 입력하여 권한 동의 페이지로 이동합니다.

```kotlin theme={null}
// NOTE: userId를 설정하지 않으면 launchUI 실패
momentSdk.setUserId("...", object : MomentSDK.ResultCallback {
		override fun onSuccess() {
				momentSdk.launchUI(
						momentSdkConfig,
						"/basic-sdk/consent",
						object : MomentSDK.ResultCallback {
								override fun onSuccess() {}

								override fun onFailure(exception: MomentException) {}
            }
        )
    }
    
    override fun onFailure(exception: MomentException) {}
}
```

## STEP 2) 직접 동의받아 서비스 시작하기

### Step 2-1) 법적동의 사항 업데이트

사용자가 법적으로 필요한 동의가 완료된 상황이어야 관련된 알림을 받을 수 있습니다. 법적 동의를 직접 받으시고 아래 API를 이용하여 동의 내역을 업데이트해주세요

[사용자 권한 동의 (Consent) API](dev-guide/advanced/consent-api)

### Step 2-2) 필요 권한 동의 득하기

#### 필요권한 1: 사용정보 접근

* Moment SDK를 시작하기 위해서는 사용자에게 사용정보 접근 허용 권한을 요청해야 합니다. 아래 예시 코드를 통해 권한을 요청할 수 있습니다. ([참고: 스타터 예시](https://github.com/fairytech-external/android-x-starter/blob/eedd27ba080e3581afacb165ea2f31dd601d9756/app/src/main/java/ai/fairytech/moment/sample/ui/main/BaseMainFragment.kt#L154))

```kotlin theme={null}
val appUsagePermissionLauncher =
  registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
      if (MomentSDK.isAppUsagePermissionGranted(requireContext()) {
	      // 권한 획득 성공
      } else {
	      // 권한 획득 실패
      }
  }
  
val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.data = Uri.fromParts("package", packageName, null)
appUsagePermissionLauncher.launch(intent)
```

#### 필요권한 2: 알림 권한

* 서비스 인식 후 알림을 보내기 위한 시스템 알림권한입니다.
* [알림권한에 대한 가이드는 이 문서](https://developer.android.com/develop/ui/compose/notifications/notification-permission)를 참조해주세요

### Step 2-3) 서비스 시작

* userId 설정 후 MomentSDK.start(config, callback)을 호출하면 인식 서비스를 시작할 수 있습니다. ([참고: 스타터 예시](https://github.com/fairytech-external/android-x-starter/blob/a6a5cec4cc26c5dab9caa43026fcb251d53883e8/app/src/main/java/ai/fairytech/moment/sample/ui/main/BaseMainFragment.kt#L219))
  * `setUserId(userId, callback)` , `start(config, callback)` [method reference](/api/android)

```kotlin theme={null}
// NOTE: userId를 설정하지 않으면 start 실패
momentSdk.setUserId("test-user-id", object : MomentSDK.ResultCallback {
		override fun onSuccess() {
				momentSdk.start(
						momentSdkConfig,
						object : MomentSDK.ResultCallback {
								override fun onSuccess() {}

								override fun onFailure(exception: MomentException) {}
            }
        )
    }
    
    override fun onFailure(exception: MomentException) {}
}
```

## STEP 3) 서비스가 강제 종료되는 경우를 위해, 서비스 재시작 로직 추가

만약 사용자가 앱을 강제종료하게 되면 서비스는 어떻게 될까요? 앱과 함께 서비스도 같이 종료되게 됩니다.

이러한 경우, 사용자가 앱을 켰을 때 서비스 상태를 원래대로 복구할 수 있게, 앱 launch 시점에 아래와 같이 `init`를 호출해줘야 합니다. (1.3.0 version 보다 낮은 SDK에서는 `restartIfNeeded`를 호출해야 합니다.)\
해당 call을 하였을 때 사용자 관점에서의 차이는 없고, 서비스를 계속적으로 동작하게 하기 위함입니다.

* `init(config, callback)`  [method reference](/api/android) (v.1.3.0+)

```kotlin theme={null}
class MyApplication : Application() {
  override fun onCreate() {
      val moment = MomentSDK.getInstance(context)

      // NOTE: userId를 설정하지 않으면 init 실패
      moment.setUserId("user-id", object : MomentSDK.ResultCallback {
          override fun onSuccess() {
              moment.init(
                  config,
                  object : MomentSDK.RestartResultCallback {
                      override fun onSuccess(resultCode: MomentSDK.RestartResultCode) {
                          if (resultCode == MomentSDK.RestartResultCode.SERVICE_RESTARTED) {
                              // restart에 성공했습니다.
                          }
                      }

                      override fun onFailure(exception: MomentException) {
                          // restart에 실패했습니다.
                      }
                  }
              )
          }

          override fun onFailure(exception: MomentException) {}
      })
  }
}
```

* `restartIfNeeded(config, callback)` (v.1.3.0 미만)

```kotlin theme={null}
class MyApplication : Application() {
	override fun onCreate() {
		MomentSDK.getInstance(context).restartIfNeeded(
			config,
			object : MomentSDK.RestartResultCallback {
				override fun onSuccess(resultCode: MomentSDK.RestartResultCode) {
			    if (resultCode == MomentSDK.RestartResultCode.SERVICE_RESTARTED) {
				    // restart에 성공했습니다.
          }
        }

        override fun onFailure(exception: MomentException) {
				   // restart에 실패했습니다.
        }
    }
}
```

# 페어리 UI 동의페이지 변경 값 조회하기

* 웹뷰가 종료된 시점을 브로캐스트로 수신 할 수 있습니다.
* AndroidManifest.xml 파일에 receiver 를 추가합니다.

```xml theme={null}
<application
	...>	
	<receiver
	  android:name="..."
	  android:enabled="true"
	  android:exported="false"
	>
	  <intent-filter>
	    <action android:name="ai.fairytech.moment.action.CASHBACK_PAGE_CLOSED" />
	  </intent-filter>
	</receiver>
</application>
```

* 법적동의/권한설정 읽기
* (추가 예정) 필수 법적동의 true 인 경우 성별/연령대 정보를 SDK로 전달하기
* [SDK Reference](/api/android)

```kotlin theme={null}
class WebViewClosedReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action != "ai.fairytech.moment.action.CASHBACK_PAGE_CLOSED") return

        val moment = MomentSDK.getInstance(context.applicationContext)
        
        // 인식 서비스 실행 여부 - boolean
        val isRunning = moment.isRunning()
        
        // App Usage 권한 설정 여부 - boolean
        // 해당 권한이 없으면 인식 서비스를 실행 할 수 없습니다.
        val isAppUsagePermissionGranted = MomentSDK.isAppUsagePermissionGranted(context.applicationContext)
        
        // Notification 권한 설정 여부 - boolean
        // 해당 권한이 없으면 인식 서비스가 실행 중이어도 알림을 보낼 수 없습니다.
        val isNotificationPermissionGranted = MomentSDK.isNotificationPermissionGranted(context.applicationContext)

        val pendingResult = goAsync()
        moment.getConsent(object : MomentSDK.CallbackWithResult<GetUserConsentResponse> {
            override fun onSuccess(result: GetUserConsentResponse) {
                // result 처리
                // (가이드 추가 예정) 필수 법적동의 on 인 경우 성별/연령대 정보를 SDK로 전달하기
                pendingResult.finish()
            }

            override fun onFailure(exception: MomentException) {
                // exception 처리
                pendingResult.finish()
            }
        })
    }
}
```

####
