Android 클라이언트에서 백엔드 API 호출

이 페이지에서는 Android 클라이언트가 App Engine용 Cloud Endpoints 프레임워크로 빌드된 백엔드 API를 호출하는 방법을 설명합니다.

클라이언트 라이브러리 생성

Android 클라이언트에는 클라이언트가 사용하는 백엔드 API로 생성한 클라이언트 라이브러리가 필요합니다. 아직 클라이언트 라이브러리가 없으면 클라이언트 라이브러리 생성에서 자세한 정보를 참조하세요. 이 문서의 단계는 Android 클라이언트 프로젝트에 클라이언트 라이브러리를 추가하는 방법을 설명합니다.

프로젝트 설정

이 안내에서는 Android 스튜디오를 사용합니다. 프레임워크를 사용하는 클라이언트를 지원하도록 Android 스튜디오를 설정하지 않은 경우 지금 설정해야 합니다.

프로젝트 구성

Android 스튜디오에서 프로젝트는 종속 항목과 기타 설정에 build.gradle 파일을 사용합니다. 기본적으로 Android 스튜디오는 상위 프로젝트 수준 build.gradle 파일과 Android 앱별 파일을 Android 모듈에 만듭니다. 다음 안내는 Android 모듈의 앱별 build.gradle을 설명합니다.

build.gradle을 구성하려면 다음 안내를 따르세요.

  1. build.gradle을 더블클릭하여 엽니다.

  2. 다음 줄을 포함하도록 이 파일을 수정합니다.

    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:1.0.0'
        }
    }
    apply plugin: 'com.android.application'
    
    repositories {
        mavenCentral()
        mavenLocal()
    }
    
    android {
        compileSdkVersion 26
    
        defaultConfig {
            applicationId "com.mycompany.myapp"
            minSdkVersion 17
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        packagingOptions {
            exclude 'META-INF/DEPENDENCIES'
        }
    }
    
    dependencies {
        implementation 'com.android.support:appcompat-v7:26.1.0'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        // BEGIN Google APIs
        // Play Services will validate the application prior to allowing OAuth2 access.
        implementation 'com.google.android.gms:play-services-auth:16.0.0'
        implementation 'com.google.android.gms:play-services-identity:16.0.0'
        // The following lines implement maven imports as defined at:
        // https://github.com/googleapis/google-api-java-client/wiki/Setup-Instructions
        // Add the Google API client library.
        implementation('com.google.api-client:google-api-client:1.28.0') {
            // Exclude artifacts that the Android SDK/Runtime provides.
            exclude(group: 'xpp3', module: 'xpp3')
            exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
            exclude(group: 'junit', module: 'junit')
            exclude(group: 'com.google.android', module: 'android')
        }
        // Add the Android extensions for the Google API client library.
        // This will automatically include play services as long as you have download that library
        // from the Android SDK manager.
        // Add the Android extensions for the Google API client library.
        implementation(group: 'com.google.api-client', name: 'google-api-client-android', version: '1.25.0') {
                   // Exclude play services, since we're not using this yet.
                  exclude(group: 'com.google.android.gms:play-services', module: 'google-play-services')
        }
        // END Google APIs
        // The following client libraries make HTTP/JSON on Android easier.
        // Android extensions for Google HTTP Client.
        implementation('com.google.http-client:google-http-client-android:1.21.0') {
            exclude(group: 'com.google.android', module: 'android')
        }
        implementation 'com.google.http-client:google-http-client-gson:1.21.0'
        // This is used by the Google HTTP client library.
        implementation 'com.google.guava:guava:18.0+'
        implementation files('libs/echo-v1-1.25.0-SNAPSHOT.jar')
    }
    
    

    com.mycompany.myapp을 고유한 값으로 바꿉니다.

  3. 파일 > 모두 저장을 클릭한 후 Android 스튜디오를 종료하고 다시 시작합니다.

프로젝트에 클라이언트 라이브러리 추가

Android 프로젝트에 클라이언트 라이브러리를 추가하려면 다음 안내를 따르세요.

  1. 프로젝트에 /libs 디렉터리가 없는 경우 지금 추가합니다. 이 디렉터리는 /src 디렉터리의 피어 디렉터리입니다.

  2. 백엔드 API에서 생성된 클라이언트 라이브러리를 /libs에 복사합니다.

  3. 방금 추가한 라이브러리를 마우스 오른쪽 버튼으로 클릭하고 라이브러리로 추가를 선택하여 프로젝트에 추가합니다.

서비스 객체 만들기

프로젝트 코드에서 백엔드 API에 요청을 보내려면 서비스 객체를 사용해야 합니다. 인증되지 않은 요청의 경우 다음과 같이 서비스 객체를 작성합니다.

BACKEND_API_NAME.Builder builder = new BACKEND_API_NAME.Builder(
    NetHttpTransport(), new GsonFactory(), null);
service = builder.build();

BACKEND_API_NAME은 백엔드 API의 이름으로 바꿉니다.

백엔드 API 호출

프로젝트에서 서비스 객체를 사용하여 API를 호출합니다. 예를 들면 다음과 같습니다.

ScoreCollection scores = service.scores().list().execute();

이 스니펫에서는 서버에 있는 모든 Score 객체의 목록을 요청합니다. list에 매개변수 또는 요청 본문이 필요하면 명령어에서 이러한 요소를 제공합니다. Android 스튜디오는 사용 가능한 메서드 호출과 필수 매개변수를 식별하기 위한 코드 완성 기능을 제공합니다.

API 호출 시 네트워크를 통해 요청이 전송되므로 자체 스레드에서 요청을 실행해야 한다는 점이 중요합니다. 이는 최근 버전의 Android에서 추가된 요구사항이지만 이전 버전에서도 이를 따르는 것이 좋습니다. 이렇게 하려면 Thread 또는 AsyncTask를 사용합니다. 예를 들면 다음과 같습니다.

private class QueryScoresTask extends AsyncTask<Void, Void, ScoreCollection>{
  Context context;

  public QueryScoresTask(Context context) {
    this.context = context;
  }

  protected Scores doInBackground(Void... unused) {
    ScoreCollection scores = null;
    try {
      scores = service.scores().list().execute();
    } catch (IOException e) {
      Log.d("TicTacToe", e.getMessage(), e);
    }
    return scores;
  }

  protected void onPostExecute(ScoreCollection scores) {
    // Do something with the result.
  }
}

인증된 호출 수행

다음 안내에서는 추가해야 하는 클라이언트 코딩만 다룹니다. 또한 사용자 인증의 설명에 따라 Endpoints 프레임워크 인증 지원을 이미 추가했다고 가정합니다.

Android 클라이언트에서 인증이 필요한 엔드포인트를 호출하는 경우 다음을 수행해야 합니다.

  • 서비스 객체에 사용자 인증 정보를 제공하도록 Android 클라이언트를 구성합니다.
  • 계정 선택도구를 사용하여 사용자의 로그인 계정 선택을 지원합니다.

다음 섹션에서는 자세한 내용을 설명합니다.

사용자 인증 정보를 제공하도록 Android 클라이언트 구성

인증이 필요한 백엔드 API 요청을 지원하려면 Android 클라이언트에서 사용자 인증 정보를 가져와 이를 서비스 객체에 전달해야 합니다.

사용자 인증 정보를 가져오고 계정 선택도구를 사용하려면 다음 Android 권한이 필요합니다.

<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />

사용자 인증 정보를 가져오려면 다음과 같이 GoogleAccountCredential.usingAudience를 호출합니다.

// Inside your Activity class onCreate method
settings = getSharedPreferences(
    "TicTacToeSample", 0);
credential = GoogleAccountCredential.usingAudience(this,
    "server:client_id:1-web-app.apps.googleusercontent.com");

여기에서 호출의 두 번째 매개변수는 백엔드 API의 웹 클라이언트 ID 앞에 추가되는 server:client_id 프리픽스입니다.

샘플 코드: 서비스 객체를 위한 사용자 인증 정보 가져오기

다음 코드는 사용자 인증 정보를 가져와서 서비스 객체에 전달하는 방법을 보여줍니다.

// Inside your Activity class onCreate method
settings = getSharedPreferences("TicTacToeSample", 0);
credential = GoogleAccountCredential.usingAudience(this,
    "server:client_id:1-web-app.apps.googleusercontent.com");
setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));

Tictactoe.Builder builder = new Tictactoe.Builder(
    NetHttpTransport(), new GsonFactory(),
    credential);
service = builder.build();

if (credential.getSelectedAccountName() != null) {
  // Already signed in, begin app!
} else {
  // Not signed in, show login window or request an account.
}

// setSelectedAccountName definition
private void setSelectedAccountName(String accountName) {
  SharedPreferences.Editor editor = settings.edit();
  editor.putString(PREF_ACCOUNT_NAME, accountName);
  editor.commit();
  credential.setSelectedAccountName(accountName);
  this.accountName = accountName;
}

앞의 샘플 코드는 Android 앱이 저장한 공유 환경설정을 조회하고 사용자가 애플리케이션 인증에 사용하려는 계정의 이름을 찾으려고 시도합니다. 성공하면 코드는 사용자 인증 정보 객체를 만들어 서비스 객체에 전달합니다. 이러한 사용자 인증 정보를 통해 Android 앱은 백엔드에 적절한 토큰을 전달할 수 있습니다.

코드 샘플은 Android 앱이 이미 사용할 계정을 알고 있는지 여부를 확인합니다. 알고 있는 경우 논리 흐름이 계속 진행되어 Android 앱을 실행할 수 있습니다. 앱이 사용할 계정을 알지 못하는 경우에는 로그인 화면을 표시하거나 사용자에게 계정을 선택하라는 메시지를 표시합니다.

마지막으로, 샘플은 사용자 인증 정보 객체를 만들어 서비스 객체에 전달합니다. Android 앱은 이러한 사용자 인증 정보를 통해 적절한 토큰을 App Engine 웹 앱에 전달할 수 있습니다.

계정 선택도구 사용

Android는 사용자 계정을 선택하기 위한 인텐트를 제공합니다. 다음과 같이 인텐트를 호출할 수 있습니다.

static final int REQUEST_ACCOUNT_PICKER = 2;

void chooseAccount() {
  startActivityForResult(credential.newChooseAccountIntent(),
      REQUEST_ACCOUNT_PICKER);
}

이 인텐트 결과를 해석하기 위한 핸들러는 다음과 같습니다.

@Override
protected void onActivityResult(int requestCode, int resultCode,
   Intent data) {
 super.onActivityResult(requestCode, resultCode, data);
 switch (requestCode) {
   case REQUEST_ACCOUNT_PICKER:
     if (data != null && data.getExtras() != null) {
       String accountName =
           data.getExtras().getString(
               AccountManager.KEY_ACCOUNT_NAME);
       if (accountName != null) {
         setSelectedAccountName(accountName);
         SharedPreferences.Editor editor = settings.edit();
         editor.putString(PREF_ACCOUNT_NAME, accountName);
         editor.commit();
         // User is authorized.
       }
     }
     break;
  }
}

로컬 개발 서버를 대상으로 Android 클라이언트 테스트

어떠한 변경 없이도 언제든지 프로덕션 App Engine에서 실행 중인 백엔드 API를 대상으로 클라이언트를 테스트할 수 있습니다. 그러나 로컬 개발 서버에서 실행 중인 백엔드 API를 대상으로 클라이언트를 테스트하려는 경우 로컬 개발 서버를 실행하는 머신의 IP 주소를 가리키도록 클라이언트에서 코드 줄을 변경해야 합니다.

필요한 대로 변경하고 로컬 개발 서버를 사용하여 테스트하는 방법은 다음과 같습니다.

  1. 로컬 개발 서버를 실행 중인 머신의 IP 주소를 기록해 둡니다. 이 IP 주소는 Android 클라이언트에 코드를 추가할 때 필요합니다.

  2. 로컬로 API 백엔드 실행 및 테스트에 설명된 대로 로컬 개발 서버를 시작합니다.

  3. Android 스튜디오 클라이언트 프로젝트에서 백엔드 API 서비스로 가는 핸들을 가져오는 코드를 찾습니다. 일반적으로 이 코드는 Builder를 사용하여 API 요청을 설정합니다.

  4. 다음 줄을 추가하여 Builder 객체에서 루트 URL(백엔드 API 호출에서 Android 클라이언트가 연결하는 URL)을 재정의합니다.

    yourBuilderObject.setRootUrl("http://YOUR_MACHINE_IP_ADDRESS:8080/_ah/api");
    

    예를 들면 다음과 같습니다.

    public static Helloworld getApiServiceHandle(@Nullable GoogleAccountCredential credential) {
      // Use a builder to help formulate the API request.
      Helloworld.Builder helloWorld = new Helloworld.Builder(AppConstants.HTTP_TRANSPORT,
          AppConstants.JSON_FACTORY,credential);
    
      helloWorld.setRootUrl("http://YOUR_MACHINE_IP_ADDRESS:8080/_ah/api");
      return helloWorld.build();
    }
    

    YOUR_MACHINE_IP_ADDRESS를 시스템의 IP 주소로 바꿉니다.

  5. Android 클라이언트 프로젝트를 다시 빌드합니다.

  6. AVD 에뮬레이터에서 클라이언트 앱을 실행하려면 다음 단계를 따릅니다.

    1. Android 스튜디오에서 도구 > Android > AVD Manager로 이동한 후 기존 AVD가 있으면 해당 AVD를 시작하고, 그렇지 않으면 새로 만든 다음 시작합니다.
    2. 실행 > 디버그 YOUR_PROJECT_NAME로 이동합니다. 여기에서 YOUR_PROJECT_NAME은 Google Cloud 프로젝트의 이름을 나타냅니다.
    3. 기기 선택 메시지가 표시되면 AVD를 선택합니다.
    4. 클라이언트를 테스트합니다.
  7. 실제 Android 기기에서 클라이언트 앱을 실행하려면 다음 안내를 따르세요.

    1. Android 기기에서 디버깅이 사용 설정되어 있는지 확인합니다.
    2. Android 스튜디오에서 실행 > YOUR_PROJECT_NAME 디버그로 이동합니다.
    3. 기기 선택 메시지가 표시되면 실제 Android 기기를 선택합니다.
    4. 클라이언트를 테스트합니다.

샘플 클라이언트 소스 코드

샘플 코드는 Android Cloud Endpoints v2.0 예시를 참조하세요.