本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用七巧板 ES 安卓系統與 Amazon 定 Location Service
七巧板 ES
使用來自 HERE 的地圖時,為與 Tlezen 架構
-
泡沫包裝
-一個全功能的尋路風格,帶有興趣點的有用圖標。 -
朱砂
— 一般地圖應用的經典外觀和首選。 -
筆芯
— 一種簡約的地圖風格,專為數據可視化覆蓋而設計,靈感來自 Stamen Design 的開創性碳粉樣式。 -
Tron — TRON
視覺語言中規模轉換的探索。 -
Walkabout
— 一種以戶外為中心的風格,非常適合遠足或外出。
本指南介紹如何使用稱為朱砂的七巧板風格將 Android 版七巧板 ES 與 Amazon 位置集成。此範例可作為上 Amazon 定 Location Service 範例儲存庫的一部分提供GitHub
雖然其他七巧板樣式最好配有對地形資訊進行編碼的點陣圖磚,但 Amazon Location 尚未支援此功能。
重要
以下教學中的七巧板樣式僅與使用該樣VectorHereContrast
式設定的 Amazon 位置地圖資源相容。
構建應用程序:初始化
要初始化您的應用程序:
-
從空活動模板創建一個新的 Android 工作室項目。
-
確保為項目語言選擇了 Kotlin。
-
選擇 API 16:安卓 4.1(果凍豆)或更高版本的最低開發套件。
-
開啟專案結構以選取檔案、專案結構... ,然後選擇「相依性」區段。
-
選取後<All Modules>,選擇「+」按鈕以新增「程式庫相依性」。
-
新增 AWS 安卓開發套件 2.19.1 版或更新版本。例如:
com.amazonaws:aws-android-sdk-core:2.19.1
-
加入七巧板版本 0.13.0 或更高版本。例如:
com.mapzen.tangram:tangram:0.13.0
。注意
搜尋七巧板:
com.mapzen.tangram:tangram:0.13.0
會產生「找不到」的訊息,但選擇「確定」將允許新增該訊息。
構建應用程序:配置
若要使用您的資源和AWS區域來設定應用程式:
-
建立
app/src/main/res/values/configuration.xml
。 -
輸入資源的名稱和標識符,以及它們在其中創建的AWS地區:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="identityPoolId">
us-east-1:54f2ba88-9390-498d-aaa5-0d97fb7ca3bd
</string> <string name="mapName">TangramExampleMap
</string> <string name="awsRegion">us-east-1
</string> <string name="sceneUrl">https://www.nextzen.org/carto/cinnabar-style/9/cinnabar-style.zip</string> <string name="attribution">© 2020 HERE</string> </resources>
構建應用程序:活動佈局
編輯app/src/main/res/layout/activity_main.xml
:
-
添加一個
MapView
,用於渲染地圖。這也會設定地圖的初始中心點。 -
添加一個
TextView
,顯示歸因。
這也會設定地圖的初始中心點。
注意
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.mapzen.tangram.MapView android:id="@+id/map" android:layout_height="match_parent" android:layout_width="match_parent" /> <TextView android:id="@+id/attributionView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#80808080" android:padding="5sp" android:textColor="@android:color/black" android:textSize="10sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" tools:ignore="SmallSp" /> </androidx.constraintlayout.widget.ConstraintLayout>
構建應用程序:請求轉換
創建一個名SigV4Interceptor
為攔截AWS請求並使用簽名版本 4 簽名它們的類。創建主要活動時,這將與用於獲取地圖資源的 HTTP 客戶端進行註冊。
package aws.location.demo.okhttp import com.amazonaws.DefaultRequest import com.amazonaws.auth.AWS4Signer import com.amazonaws.auth.AWSCredentialsProvider import com.amazonaws.http.HttpMethodName import com.amazonaws.util.IOUtils import okhttp3.HttpUrl import okhttp3.Interceptor import okhttp3.Request import okhttp3.Response import okio.Buffer import java.io.ByteArrayInputStream import java.net.URI class SigV4Interceptor( private val credentialsProvider: AWSCredentialsProvider, private val serviceName: String ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() if (originalRequest.url().host().contains("amazonaws.com")) { val signer = if (originalRequest.url().encodedPath().contains("@")) { // the presence of "@" indicates that it doesn't need to be double URL-encoded AWS4Signer(false) } else { AWS4Signer() } val awsRequest = toAWSRequest(originalRequest, serviceName) signer.setServiceName(serviceName) signer.sign(awsRequest, credentialsProvider.credentials) return chain.proceed(toSignedOkHttpRequest(awsRequest, originalRequest)) } return chain.proceed(originalRequest) } companion object { fun toAWSRequest(request: Request, serviceName: String): DefaultRequest<Any> { // clone the request (AWS-style) so that it can be populated with credentials val dr = DefaultRequest<Any>(serviceName) // copy request info dr.httpMethod = HttpMethodName.valueOf(request.method()) with(request.url()) { dr.resourcePath = uri().path dr.endpoint = URI.create("${scheme()}://${host()}") // copy parameters for (p in queryParameterNames()) { if (p != "") { dr.addParameter(p, queryParameter(p)) } } } // copy headers for (h in request.headers().names()) { dr.addHeader(h, request.header(h)) } // copy the request body val bodyBytes = request.body()?.let { body -> val buffer = Buffer() body.writeTo(buffer) IOUtils.toByteArray(buffer.inputStream()) } dr.content = ByteArrayInputStream(bodyBytes ?: ByteArray(0)) return dr } fun toSignedOkHttpRequest( awsRequest: DefaultRequest<Any>, originalRequest: Request ): Request { // copy signed request back into an OkHttp Request val builder = Request.Builder() // copy headers from the signed request for ((k, v) in awsRequest.headers) { builder.addHeader(k, v) } // start building an HttpUrl val urlBuilder = HttpUrl.Builder() .host(awsRequest.endpoint.host) .scheme(awsRequest.endpoint.scheme) .encodedPath(awsRequest.resourcePath) // copy parameters from the signed request for ((k, v) in awsRequest.parameters) { urlBuilder.addQueryParameter(k, v) } return builder.url(urlBuilder.build()) .method(originalRequest.method(), originalRequest.body()) .build() } } }
構建應用程序:主要活動
主要活動負責初始化將顯示給使用者的檢視。這涉及到:
-
實例化亞 Amazon Cognito
CredentialsProvider
。 -
註冊簽名版本 4 攔截器。
-
透過將地圖指向地圖樣式、覆寫並排 URL,以及顯示適當的歸因來設定地圖。
MainActivity
也負責將生命週期事件轉寄至地圖檢視。
package aws.location.demo.tangram import android.os.Bundle import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import aws.location.demo.okhttp.SigV4Interceptor import com.amazonaws.auth.CognitoCachingCredentialsProvider import com.amazonaws.regions.Regions import com.mapzen.tangram.* import com.mapzen.tangram.networking.DefaultHttpHandler import com.mapzen.tangram.networking.HttpHandler private const val SERVICE_NAME = "geo" class MainActivity : AppCompatActivity(), MapView.MapReadyCallback { private var mapView: MapView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mapView = findViewById(R.id.map) mapView?.getMapAsync(this, getHttpHandler()) findViewById<TextView>(R.id.attributionView).text = getString(R.string.attribution) } override fun onMapReady(mapController: MapController?) { val sceneUpdates = arrayListOf( SceneUpdate( "sources.mapzen.url", "https://maps.geo.${getString(R.string.awsRegion)}.amazonaws.com/maps/v0/maps/${ getString( R.string.mapName ) }/tiles/{z}/{x}/{y}" ) ) mapController?.let { map -> map.updateCameraPosition( CameraUpdateFactory.newLngLatZoom( LngLat(-123.1187, 49.2819), 12F ) ) map.loadSceneFileAsync( getString(R.string.sceneUrl), sceneUpdates ) } } private fun getHttpHandler(): HttpHandler { val builder = DefaultHttpHandler.getClientBuilder() val credentialsProvider = CognitoCachingCredentialsProvider( applicationContext, getString(R.string.identityPoolId), Regions.US_EAST_1 ) return DefaultHttpHandler( builder.addInterceptor( SigV4Interceptor( credentialsProvider, SERVICE_NAME ) ) ) } override fun onResume() { super.onResume() mapView?.onResume() } override fun onPause() { super.onPause() mapView?.onPause() } override fun onLowMemory() { super.onLowMemory() mapView?.onLowMemory() } override fun onDestroy() { super.onDestroy() mapView?.onDestroy() } }
執行此應用程式會以您選擇的樣式顯示全螢幕地圖。此範例可作為上 Amazon 定 Location Service 範例儲存庫的一部分提供GitHub