Android용 소비자 SDK 시작하기

소비자 SDK를 사용하여 통합된 기본 소비자 앱을 빌드하고 실행할 수 있습니다. 주문형 차량 공유 및 배송 솔루션 백엔드 서비스를 제공합니다 다음을 만들 수 있습니다. 진행 중인 이동을 표시할 수 있는 이동 및 주문 진행 상황 경로 업데이트에 응답하고, 경로 오류를 처리할 수 있습니다.

소비자 SDK는 모듈식 아키텍처이므로 특정 앱에 사용할 API를 찾고 이를 통합할 수 있습니다. 자체 API, Fleet Engine에서 제공하는 백엔드 서비스 Google Maps Platform의 추가 API를 제공합니다.

최소 시스템 요구사항

휴대기기에서 Android를 실행 중이어야 합니다. 6.0 (API 수준 23) 이상

빌드 및 종속 항목 구성

Google Maven을 사용하여 소비자 SDK 버전 1.99.0 이상을 사용할 수 있습니다. 저장소 이전에 사용된 비공개 저장소 채널은 지원 중단되었습니다.

Gradle

build.gradle 파일에 다음을 추가합니다.

repositories {
    ...
    google()
}

Maven

pom.xml 파일에 다음을 추가합니다.

<project>
  ...
  <repositories>
    <repository>
      <id>google-maven-repository</id>
      <url>https://maven.google.com</url>
    </repository>
  </repositories>
  ...
</project>

프로젝트 구성

Android용 소비자 SDK를 사용하려면 앱이 minSdkVersion 23 이상

소비자 SDK로 제작한 앱을 실행하려면 기기에 필수 Google Play 서비스 설치해야 합니다.

개발 프로젝트 설정

개발 프로젝트 설정 및 API 키 가져오기 사용자 인증 정보를 제공합니다.

  1. 사용할 새 Google Cloud 콘솔 프로젝트를 만들거나 기존 프로젝트를 선택합니다. 소비자 SDK와 함께 최적화되어 있습니다 다음 결과가 나올 때까지 몇 분 정도 기다립니다. 새 프로젝트가 Google Cloud 콘솔에 표시됩니다.

  2. 데모 앱을 실행하려면 프로젝트에 Maps SDK에 대한 액세스 권한이 있어야 합니다. 안드로이드용. Google Cloud 콘솔에서 다음을 선택합니다. API 및 서비스 > 라이브러리를 클릭한 다음, Maps SDK for Education을 Android

  3. 다음을 선택하여 프로젝트의 API 키를 가져옵니다. API 및 서비스 > 사용자 인증 정보 > 사용자 인증 정보 만들기 > API 키를 참조하세요. API 키를 가져오는 방법에 대한 자세한 내용은 다음을 참조하세요. API 키를 가져옵니다.

앱에 소비자 SDK 추가

소비자 SDK는 비공개 Maven 저장소를 통해 사용할 수 있습니다. 이 저장소에는 SDK의 프로젝트 객체 모델 (.pom) 파일과 Javadocs가 포함되어 있습니다. 앱에 소비자 SDK를 추가하는 방법은 다음과 같습니다.

  1. 다음에 설명된 대로 호스트 Maven 저장소에 액세스하도록 환경을 설정합니다. 이전 섹션에 나와 있습니다.

    SDK에 중앙 집중식 종속 항목 관리 구성이 선언된 경우 settings.gradle인 경우 다음과 같이 사용 중지합니다.

    • settings.gradle에서 다음 코드 블록을 삭제합니다.

      import org.gradle.api.initialization.resolve.RepositoriesMode
      dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
              google()
              mavenCentral()
          }
      }
      
  2. Gradle 또는 Maven 구성에 다음 종속 항목을 추가하고 원하는 소비자 SDK 버전의 VERSION_NUMBER 자리표시자

    Gradle

    build.gradle에 다음을 추가합니다.

    dependencies {
      ...
      implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-consumer:VERSION_NUMBER'
    }
    

    Maven

    pom.xml에 다음을 추가합니다.

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation</groupId>
        <artifactId>transportation-consumer</artifactId>
        <version>VERSION_NUMBER</version>
      </dependency>
    </dependencies>
    
  3. 소비자 SDK는 Maps SDK에 종속됩니다. 이 종속 항목은 SDK의 버전이 SDK에 명시적으로 정의되지 않은 경우 새 버전의 지도를 만들면 빌드 구성 파일이 출시된 후에도 소비자 SDK는 계속해서 필요한 지원 Maps SDK 버전을 제공합니다.

    Gradle

    build.gradle에 다음을 추가합니다.

    dependencies {
      ...
      implementation 'com.google.android.gms:play-services-maps:18.1.0'
    }
    

    Maven

    pom.xml에 다음을 추가합니다.

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.gms</groupId>
        <artifactId>play-services-maps</artifactId>
        <version>18.1.0</version>
      </dependency>
    </dependencies>
    

앱에 API 키 추가

앱에 소비자 SDK를 추가했으면 앱에 API 키를 추가합니다. API 키를 사용할 때 얻은 프로젝트 API 키를 사용해야 합니다. 개발 프로젝트를 설정합니다.

이 섹션에서는 보다 안전하게 API 키를 저장하는 방법을 설명합니다. 참조됩니다. 버전에 API 키를 체크인해서는 안 됩니다. 제어할 수 있습니다 local.properties 파일에 저장되어야 합니다. 이 파일은 프로젝트의 루트 디렉터리에 있습니다. 자세한 내용은 local.properties 파일, 다음을 참고하세요. Gradle 속성 파일.

이 작업을 간단히 진행하고 싶다면 Android용 Secrets Gradle Plugin을 사용하세요.

플러그인을 설치하여 API 키를 저장하는 방법은 다음과 같습니다.

  1. 루트 수준 build.gradle 파일을 열고 다음 코드를 buildscript 아래 dependencies 요소.

    Groovy

    buildscript {
        dependencies {
            // ...
            classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0"
        }
    }
    

    Kotlin

    buildscript {
        dependencies {
            // ...
            classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0")
        }
    }
    
  2. 앱 수준 build.gradle 파일을 열고 다음 코드를 plugins 요소

    Groovy

    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
    

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. Android 스튜디오를 사용한다면 프로젝트를 Gradle과 동기화합니다.

  4. 프로젝트 수준 디렉터리에서 local.properties를 열고 코드를 실행합니다. YOUR_API_KEY를 직접 생성한 API 키로 변경합니다.

    MAPS_API_KEY=YOUR_API_KEY
    
  5. AndroidManifest.xml 파일에서 com.google.android.geo.API_KEY로 이동합니다. 그리고 다음과 같이 android:value 속성을 업데이트합니다.

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="${MAPS_API_KEY}" />
    

다음 예는 샘플 앱의 전체 매니페스트를 보여줍니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.consumerapidemo">
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/_AppTheme">

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${MAPS_API_KEY}" />

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

앱에 필수 저작자 표시 포함

앱에서 소비자 SDK를 사용하는 경우 앱 법적 고지에 포함된 저작자 표시 텍스트 및 오픈소스 라이선스 섹션으로 이동합니다. 기여 분석은 독립적인 메뉴 항목으로 포함하거나 정보 메뉴 항목의 일부

라이선스 정보는 'third_party_licenses.txt'에서 확인할 수 있습니다. 파일 보관되지 않은 AAR 파일

https://developers.google.com/android/guides/opensource를 참고하세요. 을 참조하세요.

고객 SDK 인증

소비자 SDK는 JSON 웹 토큰을 사용하여 인증을 제공합니다. JSON 웹 토큰 (JWT)은 다음을 제공하는 JSON 기반 액세스 토큰입니다. 클레임할 수도 있습니다 예를 들어, 서버는 '관리자로 로그인' 클레임이 있는 토큰 kubectl 명령어 전달할 수 있습니다 그러면 클라이언트는 이 토큰을 사용하여 관리자로 로그인되어 있는 경우

소비자 SDK는 애플리케이션에서 제공하는 JSON 웹 토큰을 사용합니다. Fleet Engine과 통신할 수 있습니다 자세한 내용은 Fleet Engine 인증 및 승인을 참조하세요.

승인 토큰은 토큰의tripid:TRIP_ID authorization 헤더로, 여기서 TRIP_ID는 이동 ID입니다. 이를 통해 소비자는 차량 위치, 경로, 도착예정시간을 포함한 이동 세부정보에 대한 SDK 액세스 권한입니다.

JSON 웹 토큰 콜백

소비자 SDK가 인증 토큰 콜백을 등록합니다. 애플리케이션으로부터 시작합니다 SDK가 애플리케이션을 호출하고 를 사용하여 승인이 필요한 모든 네트워크 요청에 대한 토큰을 가져옵니다.

콜백 구현 캐시 승인은 expiry 시간이 지난 경우에만 새로고침합니다. 토큰은 1시간 후에 발급됩니다

필요한 서비스 토큰을 지정하는 승인 토큰 콜백 TripService 서비스용 또한 필수 tripId를 제공합니다. 확인할 수 있습니다

다음 코드 예는 승인을 구현하는 방법을 보여줍니다. 있습니다.

자바

class JsonAuthTokenFactory implements AuthTokenFactory {

  private static final String TOKEN_URL =
      "https://yourauthserver.example/token";

  private static class CachedToken {
    String tokenValue;
    long expiryTimeMs;
    String tripId;
  }

  private CachedToken token;

  /*
  * This method is called on a background thread. Blocking is OK. However, be
  * aware that no information can be obtained from Fleet Engine until this
  * method returns.
  */
  @Override
  public String getToken(AuthTokenContext context) {
    // If there is no existing token or token has expired, go get a new one.
    String tripId = context.getTripId();
    if (tripId == null) {
      throw new RuntimeException("Trip ID is missing from AuthTokenContext");
    }
    if (token == null || System.currentTimeMillis() > token.expiryTimeMs ||
        !tripId.equals(token.tripId)) {
      token = fetchNewToken(tripId);
    }
    return token.tokenValue;
  }

  private static CachedToken fetchNewToken(String tripId) {
    String url = TOKEN_URL + "/" + tripId;
    CachedToken token = new CachedToken();

    try (Reader r = new InputStreamReader(new URL(url).openStream())) {
      com.google.gson.JsonObject obj
          = com.google.gson.JsonParser.parseReader(r).getAsJsonObject();

      token.tokenValue = obj.get("ServiceToken").getAsString();
      token.expiryTimeMs = obj.get("TokenExpiryMs").getAsLong();

      /*
      * The expiry time could be an hour from now, but just to try and avoid
      * passing expired tokens, we subtract 5 minutes from that time.
      */
      token.expiryTimeMs -= 5 * 60 * 1000;
    } catch (IOException e) {
      /*
      * It's OK to throw exceptions here. The error listeners will receive the
      * error thrown here.
      */
      throw new RuntimeException("Could not get auth token", e);
    }
    token.tripId = tripId;

    return token;
  }
}

Kotlin

class JsonAuthTokenFactory : AuthTokenFactory() {

  private var token: CachedToken? = null

  /*
  * This method is called on a background thread. Blocking is OK. However, be
  * aware that no information can be obtained from Fleet Engine until this
  * method returns.
  */
  override fun getToken(context: AuthTokenContext): String {
    // If there is no existing token or token has expired, go get a new one.
    val tripId = 
      context.getTripId() ?: 
        throw RuntimeException("Trip ID is missing from AuthTokenContext")

    if (token == null || System.currentTimeMillis() > token.expiryTimeMs ||
        tripId != token.tripId) {
      token = fetchNewToken(tripId)
    }

    return token.tokenValue
  }

  class CachedToken(
    var tokenValue: String? = "", 
    var expiryTimeMs: Long = 0,
    var tripId: String? = "",
  )

  private companion object {
    const val TOKEN_URL = "https://yourauthserver.example/token"

    fun fetchNewToken(tripId: String) {
      val url = "$TOKEN_URL/$tripId"
      val token = CachedToken()

      try {
        val reader = InputStreamReader(URL(url).openStream())

        reader.use {
          val obj = com.google.gson.JsonParser.parseReader(r).getAsJsonObject()

          token.tokenValue = obj.get("ServiceToken").getAsString()
          token.expiryTimeMs = obj.get("TokenExpiryMs").getAsLong()

          /*
          * The expiry time could be an hour from now, but just to try and avoid
          * passing expired tokens, we subtract 5 minutes from that time.
          */
          token.expiryTimeMs -= 5 * 60 * 1000
        }
      } catch (e: IOException) {
        /*
        * It's OK to throw exceptions here. The error listeners will receive the
        * error thrown here.
        */
        throw RuntimeException("Could not get auth token", e)
      }

      token.tripId = tripId

      return token
    }
  }
}

API 초기화하기

이 절차를 수행하기 전에 먼저 소비자 SDK가 포함될 수 있습니다

ConsumerApi 인스턴스 가져오기

소비자 SDK를 사용하려면 앱에서 ConsumerApi를 비동기식으로 처리합니다. API는 싱글톤입니다. 초기화 메서드에는 AuthTokenFactory가 사용됩니다. 팩토리는 필요한 경우 사용자를 위한 JWT 토큰입니다.

providerId는 Google Cloud 프로젝트의 프로젝트 ID입니다. 자세한 내용은 Fleet Engine 사용자 가이드 를 참조하세요.

앱은 다음에 설명된 대로 AuthTokenFactory를 구현해야 합니다. 소비자 SDK 인증

자바

Task<ConsumerApi> consumerApiTask = ConsumerApi.initialize(
    this, "myProviderId", authTokenFactory);

consumerApiTask.addOnSuccessListener(
  consumerApi -> this.consumerApi = consumerApi);

Kotlin

val consumerApiTask =
  ConsumerApi.initialize(this, "myProviderId", authTokenFactory)

consumerApiTask?.addOnSuccessListener { consumerApi: ConsumerApi ->
  this@YourActivity.consumerApi = consumerApi
}

Maps SDK 및 지도 렌더기

소비자 SDK v2.x.x는 Android용 Maps SDK v18.1.0 이상을 지원합니다. 표 아래는 Maps SDK 버전별 기본 렌더기와 지원 가능 여부를 요약한 것입니다. 두 렌더러의 역할을 하게 됩니다 하지만 필요한 경우 최신 렌더기를 사용하는 것이 좋습니다. 기존 렌더기를 사용하려는 경우 MapsInitializer.initialize()

지도 SDK 버전 최신 렌더기 지원 기존 렌더기 지원 기본 렌더기
V18.1.0 이하 기존*
V18.2.0 최신

* 새 지도 렌더기의 출시와 함께, 최신 렌더기가 기본값입니다.

Maps SDK를 종속 항목으로 추가

Gradle

build.gradle에 다음을 추가합니다.

dependencies {
  //...
  implementation "com.google.android.gms:play-services-maps:VERSION_NUMBER"
}

Maven

pom.xml에 다음을 추가합니다.

 <dependencies>
   ...
   <dependency>
     <groupId>com.google.android.gms</groupId>
     <artifactId>play-services-maps</artifactId>
     <version>18.1.0</version>
   </dependency>
 </dependencies>

소비자 SDK를 초기화하기 전에 Maps SDK 초기화하기

Application 또는 스타트업 Activity 클래스에서 다음을 호출합니다. MapsInitializer.initialize() 렌더기 요청 결과를 기다린 후에 소비자 SDK

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  initViews();

  MapsInitializer.initialize(getApplicationContext(), Renderer.LATEST,
      new OnMapsSdkInitializedCallback() {
        @Override
        public void onMapsSdkInitialized(Renderer renderer) {
          switch (renderer) {
            case LATEST:
              Log.i("maps_renderer", "LATEST renderer");
              break;
            case LEGACY:
              Log.i("maps_renderer", "LEGACY renderer");
              break;
          }

          initializeConsumerSdk();
        }
      });
}

Kotlin

fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.main)
  initViews()

  MapsInitializer.initialize(
    getApplicationContext(), Renderer.LATEST,
    object : OnMapsSdkInitializedCallback() {
      fun onMapsSdkInitialized(renderer: Renderer?) {
        when (renderer) {
          LATEST -> Log.i("maps_renderer", "LATEST renderer")
          LEGACY -> Log.i("maps_renderer", "LEGACY renderer")
        }
        initializeConsumerSdk()
      }
    })
  }

사용자 인터페이스 만들기

ConsumerMapFragment 또는 ConsumerMapView를 사용하여 애플리케이션입니다. ConsumerMapFragment를 사용하면 지도를 Fragment를 사용하면 ConsumerMapView를 통해 View 차량 공유 기능은 ConsumerMapViewConsumerMapFragment, 이에 따라 하나를 선택할 수 있음 View 또는 애플리케이션에 Fragment가 더 적합합니다.

API 19 (KitKat) 및 벡터 드로어블 지원 추가

앱 디자인에 API 19 (KitKat) 기기와 벡터 드로어블 지원이 필요한 경우 다음 코드를 활동에 추가합니다. 이 코드는 AppCompatActivity: Consumer SDK의 벡터 드로어블

자바

// ...
import android.support.v7.app.AppCompatActivity;

// ...

public class ConsumerTestActivity extends AppCompatActivity {
  // ...
}

Kotlin

// ...
import android.support.v7.app.AppCompatActivity

// ...

class ConsumerTestActivity : AppCompatActivity() {
  // ...
}

지도 조각 또는 보기 추가

Android 프래그먼트 중 하나에 여행 공유를 표시하는 지도를 만듭니다. 또는 뷰(애플리케이션 레이아웃 XML 파일( /res/layout)을 입력합니다. 그러면 프래그먼트 (또는 뷰)가 여정에 대한 액세스를 제공합니다. 앱에서 액세스하고 수정할 수 있는 공유 지도 또한 지도는 ConsumerController에 대한 핸들을 추가하여 앱에서 사용자 여정 공유 환경을 맞춤설정할 수 있습니다

여정 공유 지도 및 컨트롤러

여정 공유 지도를 프래그먼트( ConsumerMapFragment) 또는 뷰 (ConsumerMapView 사용)로 로드 다음 코드 예를 참고하세요. 그러면 onCreate() 메서드가 ConsumerGoogleMap를 반환하는 getConsumerGoogleMapAsync(callback) 콜백에서 비동기로 전달됩니다. 그런 다음 ConsumerGoogleMap를 사용하여 앱의 필요에 따라 업데이트할 수 있습니다.

ConsumerMapFragment

프래그먼트는 애플리케이션 레이아웃 XML 파일에서 다음 코드 예를 참고하세요.

<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapFragment"
    android:id="@+id/consumer_map_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

getConsumerGoogleMapAsync() 호출은 onCreate()에서 가져와야 합니다. 메서드를 사용하여 축소하도록 요청합니다.

자바

public class SampleAppActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {

    // Find the ConsumerMapFragment.
    ConsumerMapFragment consumerMapFragment =
        (ConsumerMapFragment) fragmentManager.findFragmentById(R.id.consumer_map_fragment);

    // Initiate the callback that returns the map.
    if (consumerMapFragment != null) {
      consumerMapFragment.getConsumerGoogleMapAsync(
          new ConsumerMapReadyCallback() {
            // The map returned in the callback is used to access the ConsumerController.
            @Override
            public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerGoogleMap) {
              ConsumerController consumerController = consumerGoogleMap.getConsumerController();
            }
          });
    }
  }

}

Kotlin

class SampleAppActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    // Find the ConsumerMapFragment.
    val consumerMapFragment =
      fragmentManager.findFragmentById(R.id.consumer_map_fragment) as ConsumerMapFragment

    consumerMapFragment.getConsumerGoogleMapAsync(
      object : ConsumerMapReadyCallback() {
        override fun onConsumerMapReady(consumerGoogleMap: ConsumerGoogleMap) {
          val consumerController = consumerGoogleMap.getConsumerController()!!
        }
      }
    )
  }
}
ConsumerMapView

이 뷰는 XML 파일입니다.

<com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/consumer_map_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

getConsumerGoogleMapAsync() 호출은 onCreate()에서 발생해야 합니다. 포함 콜백 매개변수 외에도 포함 활동 또는 프래그먼트 및 구성을 포함하는 GoogleMapOptions (null일 수 있음) MapView의 속성입니다. 활동 또는 프래그먼트 기본 클래스는 다음 중 하나여야 합니다. 각각 FragmentActivity 또는 지원 Fragment (각각 지원)를 제공합니다. 수명 주기에 액세스할 수 있습니다

자바

public class SampleAppActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    ConsumerMapView mapView = findViewById(R.id.consumer_map_view);

    if (mapView != null) {
      mapView.getConsumerGoogleMapAsync(
          new ConsumerMapReadyCallback() {
            // The map returned in the callback is used to access the ConsumerController.
            @Override
            public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerGoogleMap) {
              ConsumerController consumerController = consumerGoogleMap.getConsumerController();
            }
          }, this, null);
    }
  }

}

Kotlin

class SampleAppActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    val mapView = findViewById(R.id.consumer_map_view) as ConsumerMapView

    mapView.getConsumerGoogleMapAsync(
      object : ConsumerMapReadyCallback() {
        // The map returned in the callback is used to access the ConsumerController.
        override fun onConsumerMapReady(consumerGoogleMap: ConsumerGoogleMap) {
          val consumerController = consumerGoogleMap.getConsumerController()!!
        }
      },
      /* fragmentActivity= */ this,
      /* googleMapOptions= */ null,
    )
  }
}

프래그먼트의 MapView는 위 MapView의 예와 동일합니다. 프래그먼트가 포함된 레이아웃을 팽창시키는 것을 제외하고는 프래그먼트 onCreateView() 메서드의 MapView

자바

public class MapViewInFragment extends Fragment {

  @Override
  public View onCreateView(
      @NonNull LayoutInflater layoutInflater,
      @Nullable ViewGroup viewGroup,
      @Nullable Bundle bundle) {
    return layoutInflater.inflate(R.layout.consumer_map_view, viewGroup, false);
  }

}

Kotlin

class MapViewInFragment : Fragment() {
  override fun onCreateView(
    layoutInflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?,
  ): View {
    return layoutInflater.inflate(R.layout.consumer_map_view, viewGroup, false)
  }
}

여행에 초점을 맞추도록 카메라 확대/축소 조정

Maps SDK에 내장된 기본 내 위치 버튼이 카메라를 기기 위치 중앙에 배치합니다.

탐색 여정 공유 세션이 진행 중이라면 카메라를 중앙에 배치하세요. 기기 위치가 아닌 여정에 집중할 수 있습니다

Android용 소비자 SDK 기본 제공 솔루션: AutoCamera

기기 위치 대신 여정에 집중할 수 있도록 소비자 SDK는 자동 카메라 기능을 제공하여 기본적으로 사용 설정되어 있습니다. 카메라가 확대/축소되어 여정 공유 경로에 초점을 맞추고 표시됩니다.

AutoCamera

카메라 동작 맞춤설정

카메라 동작을 더 세밀하게 제어해야 하는 경우 ConsumerController.setAutoCameraEnabled()를 사용하여 자동 카메라 기능을 실행합니다.

ConsumerController.getCameraUpdate()는 이 시점에 권장되는 카메라 경계를 반환합니다. 그런 다음 이 CameraUpdate를 다음으로 제공할 수 있습니다. GoogleMap.moveCamera() 또는 GoogleMap.animateCamera()

차량 공유 및 지도 액세스

애플리케이션에서 차량 공유 및 지도 상호작용을 지원하려면 액세스 권한이 필요합니다. 받는 사람: ConsumerGoogleMapConsumerController입니다. ConsumerMapFragmentConsumerMapView는 둘 다 비동기적으로 ConsumerMapReadyCallback에서 ConsumerGoogleMap입니다. 반품 가능, 수수료 ConsumerGoogleMap getConsumerController()ConsumerController입니다. 나 ConsumerGoogleMapConsumerController는 다음과 같습니다.

자바

private ConsumerGoogleMap consumerGoogleMap;
private ConsumerController consumerController;
private ConsumerMapView consumerMapView;

consumerMapView.getConsumerGoogleMapAsync(
    new ConsumerMapReadyCallback() {
      @Override
      public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerMap) {
        consumerGoogleMap = consumerMap;
        consumerController = consumerMap.getConsumerController();
      }
    },
    this, null);

Kotlin

var consumerGoogleMap: ConsumerGoogleMap
var consumerController: ConsumerController
val consumerMapView = findViewById(R.id.consumer_map_view) as ConsumerMapView

consumerMapView.getConsumerGoogleMapAsync(
  object : ConsumerMapReadyCallback() {
    override fun onConsumerMapReady(consumerMap: ConsumerGoogleMap) {
      consumerGoogleMap = consumerMap
      consumerController = consumerMap.getConsumerController()
    },
    /* fragmentActivity= */ this,
    /* googleMapOptions= */ null,
  }
)

ConsumerGoogleMap

ConsumerGoogleMapGoogleMap 클래스. 앱에 다음과 같은 기능을 제공합니다. 은(는) 다음과 동등한 API를 사용하여 지도와 상호작용합니다. GoogleMap 소비자 지도를 사용하면 앱과 차량 공유 서비스를 이용할 수 있습니다. 공유를 사용하여 동일한 기본 GoogleMap과 원활하게 상호작용할 수 있습니다. 예를 들어 GoogleMap는 단일 콜백 등록만 허용하지만 ConsumerGoogleMap는 이중 등록된 콜백을 지원합니다. 이러한 콜백을 사용하면 앱과 차량 공유에서 순차적으로 호출됩니다.

ConsumerController

ConsumerController에서 다음과 같은 차량 공유 기능에 액세스할 수 있습니다. 이동 모니터링, 이동 상태 제어, 위치 설정 등이 포함됩니다.

여정 공유 설정

백엔드가 소비자와 차량을 일치시킨 후에는 JourneySharingSession를 사용합니다. 여정 공유 사용자 인터페이스를 시작해 보세요 탐색 여정을 공유하면 일치하는 차량 위치 및 경로. 앱에 SDK를 구현한 후 이동 모니터링, 업데이트 수신 대기, 오류 처리를 위한 기능 다음 절차에서는 백엔드 서비스가 준비되었고 소비자를 차량과 연결하는 서비스가 운영되고 있습니다.

  1. TripModel 객체에 리스너를 등록하여 세부정보 가져오기 ETA (도착 예정 시간) 및 거리와 같은 이동 정보 도착하기 전에 차량이 이동해야 하는 이유입니다

    자바

    // Create a TripModel instance for listening to updates to the trip specified by this trip name.
    String tripName = ...;
    TripModelManager tripModelManager = consumerApi.getTripModelManager();
    TripModel tripModel = tripModelManager.getTripModel(tripName);
    
    // Create a JourneySharingSession instance based on the TripModel.
    JourneySharingSession session = JourneySharingSession.createInstance(tripModel);
    
    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session);
    
    // Register for trip update events.
    tripModel.registerTripCallback(new TripModelCallback() {
      @Override
      public void onTripETAToNextWaypointUpdated(
          TripInfo tripInfo, @Nullable Long timestampMillis) {
        // ...
      }
    
      @Override
      public void onTripActiveRouteRemainingDistanceUpdated(
          TripInfo tripInfo, @Nullable Integer distanceMeters) {
        // ...
      }
    
      // ...
    });
    

    Kotlin

    // Create a TripModel instance for listening to updates to the trip specified by this trip name.
    val tripName = "tripName"
    val tripModelManager = consumerApi.getTripModelManager()
    val tripModel = tripModelManager.getTripModel(tripName)
    
    // Create a JourneySharingSession instance based on the TripModel.
    val session = JourneySharingSession.createInstance(tripModel)
    
    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session)
    
    // Register for trip update events.
    tripModel.registerTripCallback(
      object : TripModelCallback() {
        override fun onTripETAToNextWaypointUpdated(
          tripInfo: TripInfo,
          timestampMillis: Long?,
        ) {
          // ...
        }
    
        override fun onTripActiveRouteRemainingDistanceUpdated(
          tripInfo: TripInfo,
          distanceMeters: Int?,
        ) {
          // ...
        }
    
      // ...
    })
    
  2. TripModelOptions를 사용하여 이동을 구성합니다.

    자바

    // Set refresh interval to 2 seconds.
    TripModelOptions tripOptions =
        TripModelOptions.builder().setRefreshIntervalMillis(2000).build();
    tripModel.setTripModelOptions(tripOptions);
    

    Kotlin

    // Set refresh interval to 2 seconds.
    val tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build()
    tripModel.setTripModelOptions(tripOptions)
    

여정 공유 중지

호스트 활동이 소멸되는 등 더 이상 필요하지 않은 경우 여정 공유를 중지해야 합니다. 여정 공유를 중지하면 Fleet Engine에 대한 네트워크 요청도 중지되고 메모리 누수가 방지됩니다.

다음 샘플 코드는 여정 공유를 중지하는 방법을 보여줍니다.

자바

public class MainActivity extends AppCompatActivity
    implements ConsumerViewModel.JourneySharingListener  {

  // Class implementation

  @Override
  protected void onDestroy() {
    super.onDestroy();

    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
  }
}

Kotlin

class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {

  // Class implementation

  override fun onDestroy() {
    super.onDestroy()

    journeySharingSession?.stop()
  }
}

경로 오류 처리

onTripRefreshError 메서드는 이동 모니터링 중에 발생하는 오류를 표시합니다. 소비자 SDK의 매핑 동일한 HTTP/RPC 가이드라인을 따르고 Google Cloud Platform 경로 모니터링 중에 표시되는 일반적인 오류는 다음과 같습니다.

HTTP RPC 설명
400 INVALID_ARGUMENT 클라이언트가 잘못된 이동 이름을 지정했습니다. 이 여행 이름은 다음 형식을 따라야 합니다. providers/{provider_id}/trips/{trip_id} provider_id는 서비스 제공업체가 소유한 클라우드 프로젝트입니다.
401 UNAUTHENTICATED 다음과 같은 이유로 요청이 인증되지 않음 잘못된 JWT 토큰입니다. 이 오류는 JWT 토큰이 이동 없이 서명된 경우 JWT 토큰이 만료되었습니다.
403 PERMISSION_DENIED 클라이언트가 권한을 부여했는지 확인합니다. 이 오류는 JWT가 토큰이 유효하지 않으면 클라이언트에 API가 사용 설정되지 않은 경우 확인할 수 있습니다 JWT 토큰은 토큰이 이동으로 서명됨 요청된 여행 ID와 일치하지 않는 ID입니다.
429 RESOURCE_EXHAUSTED 리소스 할당량이 0이거나 할당량 비율인 경우 의 트래픽이 한도를 초과합니다.
503 현재 구매할 수 없음 서비스를 사용할 수 없습니다. 일반적으로 확인할 수 있습니다
504 DEADLINE_EXCEEDED 요청 기한이 지났습니다. 이렇게 하면 호출자가 기한을 설정한 경우에만 발생합니다. 이 메서드의 기본값보다 짧은 (즉, 요청된 기한은 서버가 요청을 처리하기에 요청이 완료되지 않았으며 요청이 완료되지 않았습니다. 확인할 수 있습니다

자세한 내용은 소비자 SDK 오류 처리.