시작하기
Petnow Android SDK 설치 및 초기 설정 가이드.
개요
이 가이드는 Petnow Android SDK를 프로젝트에 설치하고 초기 설정하는 방법을 단계별로 안내합니다.
사전 준비사항
시작하기 전에 다음을 준비해주세요:
- Android API 28 (Android 9.0) 이상을 타겟으로 하는 프로젝트
- compileSdk 34 이상
- Java 17 이상
- Kotlin 1.9 이상
- Petnow API 키 — Petify Console에서 발급 (또는 support@petnow.io 문의)
1단계: SDK 설치
Petnow Android SDK는 AWS CodeArtifact를 통해 배포됩니다.
AWS CLI 설치
다음 링크에서 AWS CLI를 설치하세요: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
Petify Console에서 자격 증명 발급
Petify Console의 My Page에서 AWS CodeArtifact 자격 증명을 발급하고, 제공된 값으로 환경 변수를 설정하세요. (콘솔 가입·결제수단 등록·키 발급 절차는 Petify Console 문서를 참고하세요.)

export AWS_ACCESS_KEY_ID=<Petify Console에서 제공>
export AWS_SECRET_ACCESS_KEY=<Petify Console에서 제공>
export AWS_DEFAULT_REGION=<Petify Console에서 제공>
export PETNOW_CODEARTIFACT_DOMAIN=<Petify Console에서 제공>
export PETNOW_AWS_ACCOUNT_ID=<Petify Console에서 제공>
export PETNOW_ANDROID_SDK_REPOSITORY=<Petify Console에서 제공>Petnow Maven 저장소 추가
자격 증명으로부터 저장소 URL과 인증 토큰을 도출하세요:
export CODEARTIFACT_URL=$(aws codeartifact get-repository-endpoint \
--domain $PETNOW_CODEARTIFACT_DOMAIN \
--domain-owner $PETNOW_AWS_ACCOUNT_ID \
--repository $PETNOW_ANDROID_SDK_REPOSITORY \
--region $AWS_DEFAULT_REGION \
--format maven \
--query repositoryEndpoint \
--output text)
export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \
--domain $PETNOW_CODEARTIFACT_DOMAIN \
--domain-owner $PETNOW_AWS_ACCOUNT_ID \
--region $AWS_DEFAULT_REGION \
--query authorizationToken \
--output text)토큰 만료: 12시간마다, 또는 Gradle sync가 인증 오류로 실패할 때 두 명령을 모두 다시 실행하세요. CI 등 자동화 환경에서는 자격 증명을 시크릿으로 주입하고 빌드 단계에서 토큰을 갱신하세요 — AWS CodeArtifact 인증 토큰 문서 참고.
프로젝트의 settings.gradle.kts 또는 루트 build.gradle.kts 파일에 Petnow Maven 저장소를 추가하세요:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven {
name = "CodeArtifact"
url = uri(System.getenv("CODEARTIFACT_URL") ?: "YOUR_REPOSITORY_URL")
credentials {
username = "aws"
password = System.getenv("CODEARTIFACT_AUTH_TOKEN") ?: "YOUR_AUTH_TOKEN"
}
}
}
}의존성 추가
앱의 build.gradle.kts 파일에 다음 의존성을 추가하세요:
dependencies {
// Petnow SDK
implementation("io.petnow:ui:1.5.1")
}UI 모듈 사용에는 별도의 api-client 의존이 필요하지 않습니다. 서버 API 호출이 필요한 경우에는 앱 서버에서 직접 처리하세요.
2단계: 프로젝트 설정
AndroidManifest.xml 구성
앱의 AndroidManifest.xml 파일에 다음 권한과 설정을 추가하세요:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 인터넷 권한 (필수) -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 카메라 권한 (필수) -->
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:largeHeap="true"
... >
...
</application>
</manifest>| 설정 | 설명 |
|---|---|
INTERNET | API 통신 및 라이선스 검증에 필요 |
CAMERA | 카메라 프리뷰·탐지에 필요 |
largeHeap="true" | 이미지 처리와 탐지 작업 시 최적의 성능을 위해 권장 |
카메라 권한은 호스트가 요청합니다
권장 경로인 CameraView + CameraController는 카메라 권한을 자동으로 요청하지 않습니다. 위 CAMERA 권한을 선언하고, 세션을 시작하기 전에 런타임 권한을 직접 요청하세요. (레거시 PetnowCameraFragment만 권한을 자동 요청합니다.)
모듈 임포트
import io.petnow.ui.CameraController
import io.petnow.ui.CameraView
import io.petnow.ui.config.LicenseInfo
import io.petnow.callback.PetnowCameraDetectionListenerV23단계: 라이선스와 탐지 설정 이해하기
1.4.0부터 전역 초기화(v1.3.x의 PetnowApiClient.init())는 없습니다. 라이선스와 탐지 설정은 카메라 세션 단위로 전달합니다.
- 라이선스:
LicenseInfo(apiKey, environment)를 만들어CameraController생성자에 전달합니다. (별도의 전역 초기화 호출이 없습니다.)environment는 선택입니다. - 탐지 설정:
DetectionConfiguration을 만들어 세션을 시작할 때initializeCamera()에 전달합니다.
import io.petnow.ui.CameraController
import io.petnow.ui.config.LicenseInfo
// 라이선스는 CameraController를 만들 때 전달합니다.
val license = LicenseInfo(apiKey = "YOUR_API_KEY")
val controller = CameraController(
context, // Application/Activity Context
license,
coroutineScope, // 세션 동안 유효한 CoroutineScope
)apiKey는 모니터링/메트릭 용도이기도 합니다. API 키는 initializeCamera() 안에서 서버에 검증되며(프로세스당 키별 1회), 거절된 키는 PetnowUIError.InvalidLicense로 실패하고 카메라가 열리지 않습니다.
백엔드 환경 (environment)
LicenseInfo(apiKey: String, environment: PetnowEnvironment? = null)는 백엔드를 선택하는 선택 파라미터를 받습니다.
import io.petnow.ui.config.LicenseInfo
import io.petnow.ui.config.PetnowEnvironment
// enum PetnowEnvironment { PRODUCTION, STAGING }
val license = LicenseInfo(
apiKey = "YOUR_STAGING_API_KEY",
environment = PetnowEnvironment.STAGING,
)생략하면 해당 SDK가 빌드된 환경을 그대로 사용하며, 배포되는 모든 빌드는 production입니다. 이 값을 지정하지 않는 앱은 달라지는 것이 없습니다. staging 콘솔에서 발급한 키는 staging 백엔드에서만 유효하고 그 반대도 마찬가지이므로, 서로 맞지 않으면 라이선스 검증에 실패합니다.
environment가 이름 있는 환경인 것은 의도된 설계입니다. 앱의 BuildConfig.DEBUG 플래그에 연결하지 마세요. release 빌드가 실수로 staging을 선택하면, 해당 반려동물이 등록되어 있지 않은 백엔드로 실제 촬영 결과를 보내게 됩니다. (v1.3.x의 isDebugMode가 제공했던 기능으로, v1.4에서 제거되었다가 다시 돌아온 것입니다.)
프로세스당 API 키 1개
콘솔에서 여러 개의 API 키를 발급할 수 있지만, 한 프로세스는 그중 하나만 사용해야 합니다. 같은 프로세스에서 다른 API 키로 initializeCamera()를 호출하면 PetnowUIError.MultipleApiKeys가 발생하고, 먼저 사용한 키는 계속 동작합니다. 다른 키로 실행하려면 앱을 재시작하세요.
탐지 설정 (DetectionConfiguration)
import io.petnow.ui.config.DetectionConfiguration
import io.petnow.ui.config.DetectionPurpose
import io.petnow.ui.config.PetSpecies
// 강아지 프로필 등록용
val configuration = DetectionConfiguration(
species = PetSpecies.DOG,
purpose = DetectionPurpose.PET_PROFILE_REGISTRATION,
enableFakeDetection = true,
)이 설정은 세션을 시작할 때 controller.initializeCamera(configuration, captureSessionId)에 전달합니다. 자세한 흐름은 기본 사용법에서 다룹니다.
파라미터 설명
| 파라미터 | 설명 |
|---|---|
species | 반려동물 종류. 탐지 파이프라인이 결정됩니다. |
purpose | 촬영 목적. 목적에 따라 필요한 이미지 수가 결정됩니다. |
enableFakeDetection | 사진·화면·인쇄물에 대한 스푸핑 탐지. 기본값 true. |
inferenceTier | 검출기 실행 경로(AUTO 기본 / CPU / GPU). 프로세스당 한 번만 읽습니다. 아래 안내 참고. |
difficultyMode | (1.5.0부터 deprecated) 소스 호환을 위해 받기만 하고 무시됩니다. 비문 이미지 품질은 온디바이스 모델이 판정합니다. |
enableFakeDetection 기본값은 true
사진·화면·인쇄물에 대한 스푸핑 탐지가 기본으로 켜져 있습니다. false를 넘기면 해당 세션에서 스푸핑 탐지가 비활성화됩니다. 살아있는 동물이 아니라 반려동물 사진으로 SDK를 평가할 때 이렇게 사용합니다.
inferenceTier는 프로세스당 한 번 고정됩니다
inferenceTier는 프로세스가 첫 검출기 엔진을 만들 때 한 번만 읽고 그 뒤로는 고정됩니다. 이후 컨트롤러가 다른 티어를 요청해도 처음 결정된 값으로 계속 동작하며, 이때 SDK가 경고 로그를 남깁니다. 프로세스의 첫 initializeCamera()에서 지정하거나, 바꾸려면 앱을 재시작하세요. 지원팀이 특정 티어를 강제하라고 안내하지 않는 한 AUTO로 두세요.
purpose 옵션:
DetectionPurpose.PET_PROFILE_REGISTRATION- 프로필 등록DetectionPurpose.PET_IDENTIFICATION- 식별DetectionPurpose.PET_VERIFICATION- 인증
species 옵션:
PetSpecies.DOG- 강아지 (코 탐지)PetSpecies.CAT- 고양이 (얼굴 탐지)
캡처 세션 생성
필수: 카메라 세션을 시작하기 전에 반드시 서버에서 캡처 세션을 생성하고 captureSessionId를 받아와야 합니다.
import java.util.UUID
lifecycleScope.launch {
// 서버에서 captureSessionId를 받아옵니다
// (서버는 Petnow Server API의 createCaptureSession을 호출)
val captureSessionId: UUID = yourServerApi.createCaptureSession(
species = "DOG",
purpose = "PET_PROFILE_REGISTRATION"
)
// 카메라 화면으로 이동 시 captureSessionId 전달
navigateToCameraScreen(captureSessionId)
}Server API: captureSessionId는 서버에서 Petnow Server API를 통해 생성합니다. 클라이언트에서 직접 생성하지 않습니다.
캡처 세션 생성은 앱 서버의 책임입니다(클라이언트는 발급받은 captureSessionId만 사용). 목적(purpose)에 따라 petId 요건이 다릅니다(등록·검증은 필수, 식별은 불필요). 생성 파라미터·petId 요건·결과 이미지 업로드까지의 전체 서버 흐름은 서버 API – 생체 데이터를 참고하세요.
자세한 captureSessionId 전달 방법은 UI 모듈 개요를 참고하세요.
4단계: 설치 확인
SDK가 올바르게 설치되었는지 확인하려면 앱을 빌드하고 실행하세요. 의존성이 정상적으로 받아졌다면 다음 코드가 컴파일되고, 기기의 카메라 지원 여부를 확인할 수 있습니다.
import io.petnow.ui.camera.cameraInfo
// 기기 카메라 지원 여부 확인 (전역 초기화 호출은 없습니다)
val cameraInfo = context.cameraInfo
Log.d("PetnowSDK", "supported=${cameraInfo.isSupportedDevice}, front=${cameraInfo.isFrontCameraSupported}")문제 해결
패키지를 찾을 수 없음
증상: Gradle sync 실패, 의존성을 찾을 수 없음
해결 방법:
-
CodeArtifact 인증 확인
# 환경 변수 확인 echo $CODEARTIFACT_URL echo $CODEARTIFACT_AUTH_TOKEN -
토큰 갱신
- CodeArtifact 토큰은 12시간 후 만료됩니다
- 다음 명령으로 토큰을 재발급하세요:
export CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token \ --domain $PETNOW_CODEARTIFACT_DOMAIN \ --domain-owner $PETNOW_AWS_ACCOUNT_ID \ --region $AWS_DEFAULT_REGION \ --query authorizationToken \ --output text) -
Gradle 캐시 삭제
./gradlew clean ./gradlew --refresh-dependencies
API 키 관련
증상: initializeCamera()가 PetnowUIError.InvalidLicense로 실패하고 카메라가 열리지 않음
해결 방법:
- 거절된 키는
initializeCamera()에서PetnowUIError.InvalidLicense로 드러납니다. 잘못된 키로는 카메라가 열리지 않습니다. LicenseInfo(apiKey = ...)에 전달한 키가 올바른지 확인- 키와
environment가 서로 맞는지 확인하세요. staging 콘솔 키는 staging 백엔드에서만, production 키는 production에서만 유효합니다. - 같은 프로세스에서 다른 API 키를 쓰면
PetnowUIError.MultipleApiKeys로 실패하고 먼저 쓴 키가 계속 동작합니다. 프로세스당 키 1개를 사용하고, 바꾸려면 앱을 재시작하세요. - support@petnow.io로 문의
카메라 권한 오류
증상: 카메라가 표시되지 않거나 권한 요청이 실패
해결 방법:
AndroidManifest.xml에CAMERA권한을 선언했는지 확인하세요CameraView+CameraController경로에서는 호스트가 세션 시작 전에 런타임 카메라 권한을 직접 요청해야 합니다 (레거시PetnowCameraFragment만 자동 요청)- 사용자가 권한을 거부한 경우, 설정에서 수동으로 권한을 부여하도록 안내하세요
OutOfMemoryError
증상: 이미지 처리 중 메모리 부족 오류
해결 방법:
AndroidManifest.xml에android:largeHeap="true"추가 확인- 불필요한 이미지 캐시 정리
API 키 보안
LicenseInfo(apiKey = ...)에 전달하는 키는 Server API의 x-petnow-api-key에 사용하는 것과 동일한 종류의 Petnow API 키입니다. 자격 증명으로 취급하세요. 앱 바이너리에 넣은 값은 누구나 다시 읽어낼 수 있습니다.
권장 구성
- 서버에서 쓰는 키와 별도로 모바일 앱 전용 키를 발급하세요. 한 계정에 여러 개의 활성 키를 둘 수 있습니다.
- 서버 키를 앱에 임베드하지 마세요. 가능하면 앱 키를 하드코딩하지 말고, 런타임에 자체 서버에서 받아오세요.
폐기(Revocation)
- 키는 Petify Console(My Page → API Key Management)에서 비활성화합니다.
- 비활성화는 즉시 적용되며 다른 키에는 영향을 주지 않습니다.
- 비활성화된 키는 다시 활성화할 수 없습니다 — 새 키를 발급하세요.
앱 릴리즈 시 무중단 키 교체(rotation)
- 새 앱 키를 발급합니다.
- 새 키를 넣은 앱 버전을 배포합니다.
- 이전 앱 버전의 사용이 줄어들 때까지 기다립니다.
- 이전 키를 비활성화합니다.
SDK 내부에 자동 키 교체 기능은 없습니다.
1단계의 CodeArtifact / AWS 액세스 키는 빌드 시 SDK를 내려받는 용도로만 쓰이며, 런타임 인증과는 무관합니다.
다음 단계
설치와 설정이 완료되었습니다! 이제 SDK를 사용할 준비가 되었습니다.
지원
설치 중 문제가 발생하면 support@petnow.io로 문의해주세요.