Android 게임 문제 해결

이 페이지에서는 Play 게임즈 SDK로 Android 게임을 개발하는 동안 발생할 수 있는 문제를 해결하는 방법을 설명합니다.

로그인할 수 없음

플레이어가 게임에 로그인할 수 없는 경우 클라이언트 ID 생성게임 서비스 구성 안내를 따랐는지 확인합니다. 로그인 오류가 계속 발생하면 다음 항목을 확인하여 게임이 올바르게 설정되었는지 확인합니다.

메타데이터 태그 확인

AndroidManifest.xml에 게임 메타데이터 태그가 포함되어 있어야 합니다. 다음에 따라 메타데이터 태그가 올바로 설정되었는지 확인합니다.

  1. AndroidManifest.xml을 열고 아래와 같이 meta-data 태그가 포함되어 있는지 확인합니다.

    <meta-data android:name="com.google.android.gms.games.APP_ID"
        android:value="@string/app_id" />
    
  2. @string/app_id 리소스의 정의를 찾습니다. 일반적으로 res/xml 디렉터리에 있는 XML 파일에 정의되어 있습니다(예: res/xml/strings.xml 또는 res/xml/ids.xml).

  3. @string/app_id 리소스의 값이 애플리케이션의 숫자 ID와 같은지 확인합니다. 이 리소스의 값은 숫자만 포함해야 합니다. 예를 들면 다음과 같습니다.

    <string name="app_id">123456789012</string>
    

패키지 이름 확인

게임의 패키지 이름은 클라이언트 ID의 패키지 이름과 일치해야 합니다. 패키지 이름을 확인하려면 다음 안내를 따르세요.

  1. AndroidManifest.xml을 열고 게임의 패키지 이름이 올바른지 확인합니다. 패키지 이름은 manifest 태그의 package 속성 값입니다.
  2. 클라이언트 ID를 만들 때 제공한 패키지 이름을 확인합니다. Google Play Console에서 패키지 이름을 확인하려면 Google Play Console로 이동하여 게임에 해당하는 항목을 클릭하세요. 연결된 앱 탭에서 클라이언트 ID 목록을 확인합니다. 이 목록에 패키지 이름이 AndroidManifest.xml의 패키지 이름과 일치하는 Android 연결 앱이 있습니다.
  3. 일치하지 않는 경우 올바른 패키지 이름으로 새 클라이언트 ID를 만들고 다시 로그인해 봅니다.

인증서 지문 확인

게임에 서명하는 데 사용하는 인증서는 클라이언트 ID와 연결된 인증서 지문과 일치해야 합니다. 이를 확인하려면 먼저 인증서의 SHA1 지문을 확인합니다.

  1. 인증서 파일을 찾아 SHA1 지문을 가져옵니다. 다음 명령어를 실행하여 SHA1 지문을 가져올 수 있습니다.

    keytool -exportcert -alias your-key-name -keystore /path/to/your/keystore/file -list -v
    
  2. 출력 결과에서 SHA1:로 라벨이 지정된 16진수 숫자의 순서를 확인합니다. 이것이 인증서의 지문입니다.

그런 다음 빌드 도구가 이 인증서를 사용하는지 확인합니다.

  1. 빌드 도구에서 게임의 APK를 생성하고 원하는 인증서로 서명합니다. 생성된 APK를 임시 디렉터리에 복사합니다.
  2. 임시 디렉터리에서 다음 명령어를 실행하여 APK 압축을 풉니다.

    unzip YourGame.apk
    
  3. RSA 인증서 파일을 사용하여 비공개 키를 생성합니다.

    keytool -printcert -file META-INF/CERT.RSA
    

    또는 DSA 인증서 파일을 사용하여 비공개 키를 생성할 수 있습니다.

    keytool -printcert -file META-INF/CERT.DSA
    
  4. SHA1:로 라벨이 지정된 행의 16진수 숫자의 순서를 확인합니다.

    숫자의 순서는 이전 단계의 인증서 지문과 같아야 합니다. 일치하지 않을 경우 빌드 도구 또는 시스템이 인증서로 애플리케이션에 서명하도록 구성되지 않은 것입니다. 이러한 경우 빌드 환경 문서를 참고하여 올바로 구성하는 방법을 확인하고 다시 로그인을 시도합니다.

그런 다음, 인증서 지문이 클라이언트 ID에 구성된 지문과 일치하는지 확인합니다. 다음 단계를 따르세요.

  1. Google Play Console을 열고 게임으로 이동합니다.
  2. 게임 세부정보 페이지에서 아래로 스크롤하고 연결된 Google Cloud Platform 프로젝트의 링크를 클릭합니다.
  3. Google Cloud Platform에서 프로젝트를 선택합니다.
  4. 왼쪽 사이드바에서 API 및 인증을 선택합니다. 표시된 API 목록에 Google Play 게임즈 서비스 API 상태가 사용으로 설정되어 있는지 확인합니다.
  5. 왼쪽 사이드바에서 등록된 앱을 선택합니다.
  6. OAuth 2.0 클라이언트 ID 섹션을 펼치고 인증서 지문(SHA1)을 확인합니다.

이 지문이 이전 단계에서의 인증서 지문과 일치하지 않을 경우 올바른 인증서 지문으로 클라이언트 ID를 새로 만들어야 합니다. Google Cloud Platform이 아닌 Google Play Console에서 새 클라이언트 ID를 만들어야 합니다.

테스트 계정이 사용 설정되어 있는지 확인

게임을 게시하기 전에 Google Play Console에서 게임을 만든 계정은 테스터로도 사용 설정되어 있어야 합니다. 올바르게 구성되었는지 확인하려면 다음 단계를 따르세요.

  1. Google Play Console을 열고 게임으로 이동합니다.
  2. 테스트 탭을 엽니다.
  3. 로그인하려는 계정이 테스터 목록에 있는지 확인합니다.

로그인하려는 계정이 목록에 없으면 목록에 그 계정을 추가하고 몇 분 기다린 후에 다시 로그인을 시도합니다.

Proguard 관련 문제

Proguard를 사용하는 경우 난독화된 APK에서 오류가 발생하면 AndroidManifest.xml에서 대상 API 수준을 확인합니다. 17 이상으로 설정되어 있는지 확인합니다.

설정 문제의 기타 원인

오류의 다른 일반적인 원인을 확인합니다.

  • 게임이 게시된 경우 게임 설정도 게시되었는지 확인합니다(게임 설정을 게시하지 않고 애플리케이션을 게시하게 될 수 있습니다). 이렇게 하려면 Google Play Console에서 앱으로 이동한 후 게임 이름 옆의 박스에 게임이 게시되었다는 표시가 있는지 확인합니다. '게시 준비 완료' 또는 '테스트 준비 완료' 등 다른 상태임을 나타내는 경우 그 상자를 클릭하고 게임 게시를 선택합니다.
  • 게임을 게시할 수 없다면 클라이언트 ID 중 정확히 하나만 이 앱은 새 설치에 적합합니다 옵션이 사용 설정되었는지 확인합니다.

익명 리스너

익명 리스너를 사용하지 마세요. 익명 리스너는 아래와 같이 인라인으로 정의되는 리스너 인터페이스의 구현입니다.

    ImageManager im = ...;

    // Anonymous listener -- dangerous:
    im.loadImage(new ImageManager.OnImageLoadedListener() {
        @Override
        public void onImageLoaded(Uri uri, Drawable drawable) {
            // ...code...
        }
    }

익명 리스너는 Play 게임즈 SDK가 이를 약한 참조로 관리하기 때문에 신뢰성이 떨어집니다. 즉, 익명 리스너는 호출되기 전에 가비지 컬렉터에 의해 회수될 수 있습니다. 대신 Activity와 같은 영구 객체를 사용하여 리스너를 구현해야 합니다.

    public class MyActivity extends Activity
            implements ImageManager.OnImageLoadedListener {

        private void loadOurImages() {
            ImageManager im = ...;
            im.loadImage(this);
        }

        @Override
        public void onImageLoaded(Uri uri, Drawable drawable) {
            // ...code...
        }
    }