소비자 SDK를 사용하여 주문형 차량 공유 및 배송 솔루션 백엔드 서비스와 통합된 기본 소비자 앱을 빌드하고 실행할 수 있습니다. 활성 이동을 표시하고, 경로 업데이트에 응답하며, 이동 오류를 처리할 수 있는 이동 및 주문 진행 앱을 만들 수 있습니다.
Consumer SDK에는 모듈식 아키텍처가 있으므로 특정 앱에 사용하려는 API 부분을 사용하여 자체 API, Fleet Engine에서 제공하는 백엔드 서비스, Google Maps Platform의 추가 API와 통합할 수 있습니다.
최소 시스템 요구사항
휴대기기는 Android 6.0(API 수준 23) 이상을 실행해야 합니다.
Maven 구성
Consumer SDK 버전 1.99.0 이상은 Google Maven 저장소를 사용하여 사용할 수 있습니다.
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로 빌드된 앱을 실행하려면 Android 기기에 Google Play 서비스가 설치되어 있어야 합니다.
개발 프로젝트 설정하기
Google Cloud 콘솔에서 개발 프로젝트를 설정하고 프로젝트의 API 키를 가져오는 방법은 다음과 같습니다.
소비자 SDK와 함께 사용할 새 Google Cloud Console 프로젝트를 만들거나 기존 프로젝트를 선택합니다. 새 프로젝트가 Google Cloud 콘솔에 표시될 때까지 몇 분 정도 기다립니다.
데모 앱을 실행하려면 프로젝트에서 Android용 Maps SDK에 액세스할 수 있어야 합니다. Google Cloud 콘솔에서 API 및 서비스 > 라이브러리를 선택한 다음 Android용 Maps SDK를 검색하여 사용 설정합니다.
API 및 서비스 > 사용자 인증 정보 > 사용자 인증 정보 만들기 > API 키를 선택하여 프로젝트의 API 키를 가져옵니다. API 키를 가져오는 방법에 관한 자세한 내용은 API 키 가져오기를 참고하세요.
앱에 소비자 SDK 추가
소비자 SDK는 비공개 Maven 저장소를 통해 제공됩니다. 저장소에는 SDK의 프로젝트 객체 모델 (.pom) 파일과 Javadocs가 있습니다. 앱에 소비자 SDK를 추가하려면 다음 단계를 따르세요.
이전 섹션에서 설명한 대로 호스트 Maven 저장소에 액세스하도록 환경을 설정합니다.
settings.gradle
에 중앙 집중식 종속 항목 관리 구성이 선언되었다면 다음과 같이 사용 중지하세요.settings.gradle
에서 다음 코드 블록을 삭제합니다.import org.gradle.api.initialization.resolve.RepositoriesMode dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
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>
앱에 API 키 추가하기
앱에 소비자 SDK를 추가한 후 API 키를 앱에 추가합니다. 개발 프로젝트를 설정할 때 얻은 프로젝트 API 키를 사용해야 합니다.
이 섹션에서는 앱에서 더욱 안전하게 참조할 수 있도록 API 키를 저장하는 방법을 설명합니다. 버전 제어 시스템에 API 키를 체크인하면 안 됩니다. 프로젝트의 루트 디렉터리에 있는 local.properties
파일에 저장해야 합니다. local.properties
파일에 관한 자세한 내용은 Gradle 속성 파일을 참고하세요.
이 작업을 간단히 진행하고 싶다면 Android용 Secrets Gradle Plugin을 사용하세요.
플러그인을 설치하여 API 키를 저장하는 방법은 다음과 같습니다.
루트 수준
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") } }
앱 수준
build.gradle
파일을 열고plugins
요소에 다음 코드를 추가합니다.Groovy
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Android 스튜디오를 사용하는 경우 프로젝트를 Gradle과 동기화합니다.
프로젝트 수준 디렉터리에서
local.properties
를 열고 다음 코드를 추가합니다.YOUR_API_KEY
를 API 키로 변경합니다.MAPS_API_KEY=YOUR_API_KEY
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를 사용하는 경우 앱의 법적 고지 섹션에 저작자 표시 텍스트와 오픈소스 라이선스를 포함해야 합니다. 저작자 표시는 독립적인 메뉴 항목 또는 정보 메뉴 항목의 일부로 포함하는 것이 가장 좋습니다.
필요한 저작자 표시 텍스트 및 오픈소스 라이선스는 Ridesharing Consumer SDK ZIP 파일에서 찾을 수 있습니다.
NOTICE.txt
LICENSES.txt
소비자 SDK 인증
소비자 SDK는 JSON 웹 토큰을 사용한 인증을 제공합니다. JSON 웹 토큰 (JWT)은 서비스에서 하나 이상의 클레임을 제공하는 JSON 기반 액세스 토큰입니다. 예를 들어 서버에서 '관리자로 로그인'이라는 클레임을 가진 토큰을 생성하여 클라이언트에 제공할 수 있습니다. 그러면 클라이언트가 이 토큰을 사용하여 관리자로 로그인되었음을 증명할 수 있습니다.
소비자 SDK는 애플리케이션에서 제공하는 JSON 웹 토큰을 사용하여 Fleet Engine과 통신합니다. 자세한 내용은 Fleet Engine 인증 및 승인을 참조하세요.
승인 토큰은 다음 Fleet Engine 서비스에 대한 액세스를 제공합니다.
TripService
- 소비자 SDK에 차량 위치, 경로, 도착예정시간을 포함한 이동 세부정보에 대한 액세스 권한을 부여합니다. 이동 서비스의 승인 토큰에는 토큰의authorization
헤더에tripid:TRIP_ID
클레임이 포함되어야 합니다. 여기서TRIP_ID
는 이동 ID입니다.VehicleService
- 차량 밀도 레이어를 표시하고 승차 지점 도착예정시간을 추정하기 위해 퍼징된 차량 위치에 관한 정보를 소비자 SDK에 제공합니다. 소비자 SDK는 퍼징 위치만 사용하므로 차량 서비스의 승인 토큰에는vehicleid
클레임이 필요하지 않습니다.
JSON 웹 토큰 콜백
소비자 SDK는 초기화 중에 애플리케이션에 승인 토큰 콜백을 등록합니다. SDK는 애플리케이션을 호출하여 승인이 필요한 모든 네트워크 요청의 토큰을 가져옵니다.
콜백 구현에서 승인 토큰을 캐시하고 expiry
시간이 지난 경우에만 새로고침하는 것이 좋습니다. 토큰은 1시간 후에 발급되어야 합니다.
승인 토큰 콜백은 TripService
서비스에 필요한 서비스 토큰을 지정합니다. 컨텍스트에 필요한 tripId
도 제공합니다.
다음 코드 예는 승인 토큰 콜백을 구현하는 방법을 보여줍니다.
Java
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 사용자 가이드를 참조하세요.
앱은 소비자 SDK 인증에 설명된 대로 AuthTokenFactory
를 구현해야 합니다.
Java
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.0.0은 Android용 Maps SDK v18.1.0 이상을 지원합니다. 기본 Google 지도 렌더기를 지정하는 요청을 지원합니다. 자세한 내용은 새 지도 렌더기(선택)를 참고하세요.
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>
소비자 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
를 사용할 수 있습니다. 차량 공유 기능은 ConsumerMapView
와 ConsumerMapFragment
에서 모두 동일하므로 View
또는 Fragment
중 애플리케이션에 더 적합한 기능을 선택할 수 있습니다.
API 19 (KitKat) 및 벡터 드로어블 지원 추가
앱 설계에 API 19 (KitKat) 기기 및 벡터 드로어블 지원이 필요하다면 활동에 다음 코드를 추가합니다. 이 코드는 소비자 SDK에서 벡터 드로어블을 사용하도록 AppCompatActivity
를 확장합니다.
Java
// ...
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()
메서드가 getConsumerGoogleMapAsync(callback)
를 호출하여 콜백에서 ConsumerGoogleMap
를 비동기식으로 반환합니다. 그런 다음 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()
메서드에서 발생해야 합니다.
Java
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()!!
}
}
)
}
}
소비자 지도 보기
뷰는 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()
에서 발생해야 합니다. 콜백 매개변수 외에도 포함 활동 또는 프래그먼트와 MapView
의 구성 속성을 포함하는 GoogleMapOptions
(null일 수 있음)가 필요합니다. 활동 또는 프래그먼트 기본 클래스는 각각 FragmentActivity
또는 지원 Fragment
여야 합니다. 수명 주기 액세스를 제공하기 때문입니다.
Java
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
를 포함하는 레이아웃을 확장한다는 점이 다릅니다.
Java
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()에 인수로 제공할 수 있습니다.
차량 공유 및 지도 이용
애플리케이션에서 차량 공유 및 지도 상호작용을 지원하려면 ConsumerGoogleMap
및 ConsumerController
액세스 권한이 필요합니다.
ConsumerMapFragment
와 ConsumerMapView
는 모두 ConsumerMapReadyCallback
의 ConsumerGoogleMap
를 비동기식으로 반환합니다.
ConsumerGoogleMap
는 getConsumerController()
에서 ConsumerController
를 반환합니다. 다음과 같이 ConsumerGoogleMap
및 ConsumerController
에 액세스할 수 있습니다.
Java
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,
}
)
소비자 Google 지도
ConsumerGoogleMap
는 GoogleMap
클래스의 래퍼 클래스입니다. 앱에서 GoogleMap
와
동일한 API를 사용하여 지도와 상호작용할 수
있습니다. 소비자 지도를 사용하면 앱과 차량 공유에서 동일한 기본 GoogleMap과 원활하게 상호작용할 수 있습니다. 예를 들어 GoogleMap
는 단일 콜백 등록만 허용하지만 ConsumerGoogleMap
는 이중 등록 콜백을 지원합니다.
이러한 콜백을 사용하면 앱과 차량 공유에서 순차적으로 호출되는 콜백을 등록할 수 있습니다.
소비자 컨트롤러
ConsumerController
는 경로 모니터링, 이동 상태 제어, 위치 설정과 같은 차량 공유 기능에 대한 액세스를 제공합니다.
여정 공유 설정
백엔드가 소비자와 차량을 매칭한 후 JourneySharingSession
를 사용하여 사용자 인터페이스를 공유하는 여정을 시작합니다. 여정 공유에는 일치하는 차량 위치와 경로가 표시됩니다. 앱에 SDK를 구현한 후 이동 모니터링, 업데이트 수신 대기, 오류 처리를 위한 기능을 추가할 수 있습니다.
다음 절차에서는 백엔드 서비스가 마련되어 있으며 소비자와 차량을 일치시키는 서비스가 작동 중이라고 가정합니다.
TripModel
객체에 리스너를 등록하여 도착예정시간 (예상 도착 시간) 및 차량이 도착 전에 이동해야 하는 거리와 같은 이동에 관한 세부정보를 가져옵니다.Java
// 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?, ) { // ... } // ... })
TripModelOptions
을(를) 사용하여 이동을 구성합니다.Java
// 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에 대한 네트워크 요청도 중지되고 메모리 누수가 방지됩니다.
다음 샘플 코드는 여정 공유를 중지하는 방법을 보여줍니다.
Java
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 오류에 대한 매핑은 Google Cloud Platform에 설정된 것과 동일한 HTTP/RPC 가이드라인을 따릅니다.
이동 모니터링 중에 나타나는 일반적인 오류는 다음과 같습니다.
HTTP | RPC | 설명 |
---|---|---|
400 | INVALID_ARGUMENT | 클라이언트가 잘못된 이동 이름을 지정했습니다. 이동 이름은 providers/{provider_id}/trips/{trip_id} 형식을 따라야 합니다.
provider_id는 서비스 제공업체에서 소유한 Cloud 프로젝트의 ID여야 합니다. |
401 | UNAUTHENTICATED | 잘못된 JWT 토큰으로 인해 요청이 인증되지 않았습니다. 이 오류는 경로 ID 없이 JWT 토큰이 서명되었거나 JWT 토큰이 만료된 경우에 발생합니다. |
403 | PERMISSION_DENIED | 클라이언트에 충분한 권한이 없습니다. 이 오류는 JWT 토큰이 유효하지 않거나, 클라이언트에 권한이 없거나, 클라이언트 프로젝트에 API가 사용 설정되지 않은 경우에 발생합니다. JWT 토큰이 누락되었거나 토큰이 요청된 이동 ID와 일치하지 않는 이동 ID로 서명되었을 수 있습니다. |
429 | RESOURCE_EXHAUSTED | 리소스 할당량이 0이거나 트래픽 속도가 한도를 초과합니다. |
503 | UNAVAILABLE | 서비스를 사용할 수 없습니다. 일반적으로 서버가 다운됩니다. |
504 | DEADLINE_EXCEEDED | 요청 기한이 지났습니다. 이는 호출자가 메서드의 기본 기한보다 짧은 기한을 설정하고 (즉, 요청된 기한이 서버에서 요청을 처리하기에 충분하지 않음) 요청이 기한 내에 완료되지 않은 경우에만 발생합니다. |
자세한 내용은 소비자 SDK 오류 처리를 참고하세요.