---
title: SDK 문제 해결
description: Android 에뮬레이터, 로그인 callback, 권한 오류, 중복 제출 문제를 점검하세요.
---

# SDK 문제 해결 {#sdk-troubleshooting}

## 에뮬레이터에서 빠르게 확인하기 {#test-with-the-emulator}

저장소의 샘플 앱은 로컬 서버와 SDK 흐름을 확인하는 도구입니다. 개발자 콘솔에서 앱을 등록할 때 callback으로 `opentester-sample://callback`을 추가하고, 테스터 계정의 앱 참여를 승인합니다.

Android SDK와 JDK를 준비한 뒤 저장소 루트에서 실행합니다.

```sh
cd opentester-android-sdk
./gradlew :opentester:testDebugUnitTest :sample:assembleDebug
adb install -r sample/build/outputs/apk/debug/sample-debug.apk
```

`adb`가 PATH에 없다면 Android SDK의 `platform-tools/adb`를 사용합니다. 샘플의 기본 주소는 웹 `http://10.0.2.2:3000`, API `http://10.0.2.2:4000`입니다. API 서버의 허용 Origin에 샘플이 여는 웹 주소가 포함되어야 합니다.

1. 샘플에 콘솔의 앱 ID를 입력합니다.
2. 브라우저 로그인 버튼을 누르고 승인된 **테스터 계정**으로 로그인합니다.
3. 앱 연결을 승인하고 샘플로 돌아옵니다.
4. 현재 권한 확인과 버그·개선 의견 제출을 실행합니다.
5. 개발자 콘솔에서 보고서가 생성되었는지 확인합니다.

실제 USB 기기에서 로컬 서버를 사용할 때는 다음을 실행하고 샘플 주소를 `http://localhost:3000`, `http://localhost:4000`으로 바꿀 수 있습니다.

```sh
adb reverse tcp:3000 tcp:3000
adb reverse tcp:4000 tcp:4000
```

샘플은 debug manifest에서만 로컬 HTTP와 custom callback을 허용합니다. 실제 배포 앱은 [HTTPS App Links](/ko/sdk/authentication)를 구성합니다.

## 로그인 화면은 열리지만 앱으로 돌아오지 않아요 {#login-opens-but-does-not-return-to-the-app}

- 콘솔의 callback, `OpenTesterConfig.redirectUri`, manifest의 host/path가 같은지 확인합니다.
- callback 도메인의 `assetlinks.json`에 설치된 앱의 application ID와 서명 인증서 지문이 있는지 확인합니다.
- callback을 받는 Activity가 `exported="true"`이고 `VIEW`, `DEFAULT`, `BROWSABLE`을 선언했는지 확인합니다.
- 샘플 custom scheme은 로컬 개발 설정에서만 사용합니다. 배포 API는 HTTPS callback을 요구합니다.

## “진행 중인 로그인이 없습니다” 또는 state 오류가 나요 {#no-pending-login-or-invalid-state}

로그인을 시작한 SDK 인스턴스로 callback을 처리해야 합니다. 인스턴스를 `Application`이나 유지되는 객체에 두세요. 프로세스가 종료되었다면 로그인부터 다시 시작합니다.

callback은 한 번만 처리하고 Intent의 `data`를 비웁니다. `createAuthenticationUri()`를 중복 호출하면 진행 중 state가 교체됩니다. callback 교환 중 오류나 취소가 발생해도 새 로그인을 시작하세요.

## 401 또는 403이 나요 {#401-or-403-responses}

| 응답  | 점검할 내용                                                           |
| ----- | --------------------------------------------------------------------- |
| `401` | 로그인 코드가 만료·소비되었거나 토큰이 만료되었는지 확인하고 재로그인 |
| `403` | 해당 앱의 참여 상태가 `approved`인지 확인                             |

기기의 브라우저 계정은 데스크톱 브라우저와 다를 수 있습니다. 앱 소유자 계정과 테스터 계정을 혼동하지 않았는지 확인하세요. Google Group 가입만으로 앱별 SDK 참여 권한이 생기지는 않습니다.

승인 철회 후 새 요청은 실패하는 것이 정상입니다. `401`·`403` 이후 SDK의 메모리 세션도 지워집니다.

## 네트워크 오류 또는 잘못된 응답이 나요 {#network-errors-or-invalid-responses}

- `apiBaseUrl`에 `/api/v1`을 중복해서 붙이지 않았는지 확인합니다.
- `webBaseUrl`은 API 서버가 아닌 OpenTester 웹 주소여야 합니다.
- Android 에뮬레이터에서 개발 머신에 연결하려면 `10.0.2.2`를 사용합니다.
- 로컬 HTTP에는 SDK의 `allowInsecureLocalhost = true`와 Android debug 네트워크 보안 설정이 모두 필요합니다. SDK는 임의 LAN HTTP 주소를 허용하지 않습니다.
- 프록시가 API 요청을 HTML 로그인 화면으로 보내거나 redirect하는지 확인합니다. SDK는 redirect를 따라가지 않습니다.

연결 timeout은 10초, 읽기 timeout은 15초입니다. 오프라인에서 권한 확인을 성공한 것으로 처리하지 않습니다.

## 재시도했더니 같은 보고서가 돌아와요 {#a-retry-returns-the-same-report}

같은 앱·테스터·`clientRequestId`로 제출하면 기존 결과를 반환합니다. 이는 중복 생성 방지 동작입니다. 기존 UUID에 다른 내용을 전달해도 수정되지 않습니다. 새 보고서는 새 UUID를, 전송 실패의 재시도는 이전 UUID를 사용하세요.

반대로 중복 보고서가 만들어진다면 재시도 때마다 `BugReport`나 `FeedbackReport`를 새로 생성하고 있는지 확인합니다. [재시도 가이드](/ko/sdk/feedback#retry)를 참고하세요.

## 오류가 자동으로 제출되지 않아요 {#errors-are-not-submitted-automatically}

현재 SDK는 `submitBug()` 또는 `submitFeedback()` 호출에 의한 텍스트 제출을 지원합니다. uncaught exception 수집, 자동 충돌 제출, 첨부, 세션 녹화, 오프라인 큐는 구현되어 있지 않습니다.

## Maven 의존성을 찾을 수 없어요 {#maven-dependency-cannot-be-found}

Maven Central 좌표는 `app.opentester:android-sdk:0.1.0`입니다. `settings.gradle.kts`의 의존성 저장소에 `mavenCentral()`이 있는지 확인하세요. Kotlin 패키지인 `dev.opentester.sdk`와 Maven group ID는 다릅니다. JitPack을 사용한다면 저장소 `https://jitpack.io`와 좌표 `com.github.opentesterapp:opentester-android-sdk:v0.1.0`을 함께 설정하세요.

## 릴리스 빌드가 SDK 클래스를 찾지 못해요 {#release-build-cannot-find-sdk-classes}

`debugImplementation`을 사용하면 release에서는 SDK를 참조할 수 없습니다. 테스트용 Activity·Application·manifest를 `src/debug/` 또는 해당 테스트 flavor의 source set에 두고, 공통 코드에는 빌드별 구현을 주입하세요. 제공된 샘플은 SDK 검증용 앱이며 일반 사용자용 배포 템플릿은 아닙니다.
