建立 Android 應用程式 - Amazon Location Service

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

建立 Android 應用程式

在本節中,您將創建一個帶有地圖和位置搜索功能的 Android 應用程序。在繼續操作之前,請確保您已經創建了亞馬遜位置資源併為您的應用程序創建了 Amazon Cognito 身份,如Amazon Location Service 快速入門主題。

注意

本教程使用 Amplify、 AndroidStudio 和科特林語。您必須已擁有 AndroidStudio 和科特林建立了一個工作環境。

創建基本安卓應用程序

在本教程中,您將創建嵌入地圖的 Android 應用程序,並允許用户查找地圖上某個位置的內容。

首先,讓我們使用 AndroidStudio 的新項目嚮導創建一個空的 Kotlin 應用程序。

建立空的應用程式(安卓工作室)

  1. 啟動 Android 工作室。在功能表中,選擇File (檔案)新的新增專案

  2. 來自電話和平板電腦選項卡上,選擇空白活動,然後選擇下一頁

  3. 選擇名稱套件名稱,以及儲存位置適用於您的應用程式。

  4. 在下拉列表中語言,選擇科特林

  5. 選擇完成創建空白應用程序。

  6. (選用)。默認情況下,用於空白應用程序的主題在應用程序頂部包含一個帶有應用程序名稱的文本欄。您可以通過編輯app/manifests/AndroidManifest.xml檔案。更改行android:theme="@style/Theme.<packagename>"android:theme="@style/Theme.AppCompat.NoActionBar"

接下來,將地圖控件添加到應用程序。

將交互式地圖添加到應用程序

現在您有了框架,您可以將映射控件新增至應用程式。本教程使用 Amplify 庫來管理應用程序中的地圖視圖。地圖控件本身是GL JS庫、Amplify 和 MapLibre 從亞馬遜 Location Service 獲取地圖數據。所以此Amplify庫便於使用亞馬遜 Cognito 簽署對亞馬遜位置 API 的調用。

要添加地圖,您將執行以下步驟:

  1. 將位置依賴性新增至您的工程。

  2. 在佈局中設置地圖視圖。

  3. 編寫用於顯示地圖的代碼。

  4. 建立資源的配置文件。

以下過程將引導您完成這些步驟中的每個步驟。

1-將位置依賴項添加到您的項目

  1. 在安卓工作室中,選擇檢視菜單,然後選擇工具窗口專案。這會開啟專案窗口,您可以使用該窗口訪問您的工程中的所有文件。

  2. 在 中專案窗口, 打開Gradle 腳本,然後選擇build.gradle文件的應用程序模塊。這會開啟build.gradle檔案進行編輯。

  3. 在文件底部的依存關係部分,新增下列依賴關係。您必須進行的更改顯示在green。現有的依賴關係可能與下列內容不一樣,具體取決於您的 AndroidStudio 和為您的項目選擇的選項。

    dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.3.0' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' // added for location services: implementation 'org.maplibre.gl:android-sdk:9.5.2' implementation 'com.amplifyframework:aws-auth-cognito:1.31.3' implementation 'com.amplifyframework:aws-geo-location:0.3.1' implementation 'com.amplifyframework:maplibre-adapter:0.3.1' }
  4. 編輯完 Gradle 依賴關係後, AndroidStudio 必須重新同步項目。在build.gradle編輯窗口、 AndroidStudio 會提示您進行同步。選擇立即同步以同步您的項目,然後再繼續。

  5. 來自專案窗口, 打開app爪哇<your package name>,然後選擇MainActivity.ktfile.

  6. 在主活動 .KT 文件中,展開匯入部分(若尚未開啟的話)。新增green從下列清單導入。同樣,您的現有導入可能不匹配,具體取決於 AndroidStudio 選項。

    import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.view.animation.OvershootInterpolator import android.widget.ImageView import android.widget.TextView import com.amplifyframework.AmplifyException import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin import com.amplifyframework.core.Amplify import com.amplifyframework.geo.location.AWSLocationGeoPlugin import com.amplifyframework.geo.location.models.AmazonLocationPlace import com.amplifyframework.geo.maplibre.view.MapLibreView import com.amplifyframework.geo.maplibre.view.support.fadeIn import com.amplifyframework.geo.maplibre.view.support.fadeOut import com.amplifyframework.geo.models.Coordinates import com.amplifyframework.geo.options.GeoSearchByCoordinatesOptions import com.mapbox.mapboxsdk.camera.CameraPosition import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.maps.MapboxMap import kotlin.math.abs
    注意

    如果您的導入不包含android.util.logandroid.widget.ImageView, 或andoid.widget.TextView,您也需要添加這些導入。

  7. 保存您編輯過的文件build.gradleMainActivity.kt

這會將下列依賴項新增至您的應用程式:

  • AWS Amplify。 Amplify 提供了許多有用的函數來處理AWS,包括亞馬遜地點。

  • GL JS。此庫包括一個地圖控件,用於顯示地圖切片並且包括交互性(如平移和縮放)。此控件還允許擴展,例如在地圖上繪製自己的要素。

2-將地圖視圖添加到您的工程

  1. 在 中 AndroidStudio 專案窗口, 打開應用程式RES佈局,然後選擇activity_main.xmlfile. 這會開啟build.gradle檔案進行編輯。如果尚未選擇,請在activity_main.xml編輯窗口中,選擇程式碼以直接查看佈局的 XML。

  2. 刪除預設TextView,然後添加 Amplify 地圖視圖。您添加的 XML 顯示在green(下列內容)。

    <?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.amplifyframework.geo.maplibre.view.MapLibreView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" app:mapbox_foregroundLoadColor="@color/white" app:mapbox_renderTextureMode="true" app:mapbox_renderTextureTranslucentSurface="true" /> </androidx.constraintlayout.widget.ConstraintLayout>
  3. 保存您編輯的文件activity_main.xml

現在您已準備好編寫建立地圖視圖的代碼了。

3-為交互式地圖添加代碼

  1. 來自專案窗口, 打開app爪哇<your package name>,然後選擇MainActivity.ktfile.

  2. 將下列程式碼新增置MainActivity.ktfile. 新代碼位於green

    class MainActivity : AppCompatActivity() { private val mapView by lazy { findViewById<MapLibreView>(R.id.mapView) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) initAmplify() setContentView(R.layout.activity_main) mapView.getMapAsync { map -> val initialPosition = LatLng(47.6160281982247, -122.32642111977668) map.cameraPosition = CameraPosition.Builder() .target(initialPosition) .zoom(13.0) .build() } } private fun initAmplify() { try { Amplify.addPlugin(AWSCognitoAuthPlugin()) Amplify.addPlugin(AWSLocationGeoPlugin()) Amplify.configure(applicationContext) Log.i("AndroidQuickStart", "Initialized Amplify") } catch (error: AmplifyException) { Log.e("AndroidQuickStart", "Could not initialize Amplify", error) } } override fun onStart() { super.onStart() mapView?.onStart() } override fun onResume() { super.onResume() mapView?.onResume() } override fun onPause() { super.onPause() mapView?.onPause() } override fun onStop() { super.onStop() mapView?.onStop() } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) mapView?.onSaveInstanceState(outState) } override fun onLowMemory() { super.onLowMemory() mapView?.onLowMemory() } override fun onDestroy() { super.onDestroy() mapView?.onDestroy() } }
  3. 儲存 MainActivity.kt 檔案。

讓我們分解新代碼正在做什麼。

  • mapView函數 — 這是一個幫助函數,用於查找和引用您在佈局中創建的 MapView。

  • initAmplify— 此函數初始化 Amplify 庫。

  • mapView.getMapAsync— 此代碼,在onCreate中,設置地圖視圖的初始位置和縮放級別。

  • 覆寫的事件 (onStart等)— 這些是為了確保 MapView 獲取它需要在應用程序中正確操作的事件。

現在,該應用程序需要少量的配置,它將能夠運行,顯示一個交互式地圖。

4-創建 Amplify 配置

  1. 在安卓工作室中,選擇File (檔案)菜單,然後選擇新的Android 資源目錄。對於Resource Type (資源類型),選擇生的從下拉式清單。這也將為目錄提供名稱raw(自動進行)。選擇OK (好)來建立目錄。

  2. 在 中專案窗口, 打開應用程式RES生的在樹狀圖中。選擇或右鍵單擊生的,然後選擇新的File (檔案)。對於New File (新增檔案)名稱,選擇amplifyconfiguration.json,然後按Enter

  3. 在新文件中,新增下列代碼。替換紅色文本,使用您自己的亞馬遜地點和亞 Amazon Cognito 資源中的值。您創建了這些資源的快速入門章節。

    { "UserAgent": "aws-amplify-cli/2.0", "Version": "1.0", "geo": { "plugins": { "awsLocationGeoPlugin": { "region": "<Amazon Location region>", "maps": { "items": { "<Amazon Location map resource name>": { "style": "<A name you choose for the style of the resource>" } }, "default": "<the map resource name again>" }, "searchIndices": { "items": [ "<Amazon Location place resource name>" ], "default": "<the place resource name again>" } } } }, "auth": { "plugins": { "awsCognitoAuthPlugin": { "UserAgent": "aws-amplify-cli/0.1.0", "Version": "0.1.0", "IdentityManager": { "Default": {} }, "CredentialsProvider": { "CognitoIdentity": { "Default": { "PoolId": "<your Amazon Cognito identity pool ID>", "Region": "<the region of your Amazon Cognito identity pool>" } } } } } } }
  4. 儲存 amplifyconfiguration.json 檔案。

您現在可以構建應用程序。要運行它,您可能需要在 AndroidStudio 中設置一個設備來模擬,或者在自己的設備上使用該應用程序。使用此應用程序可以查看「Amplify」地圖控件的行為。您可以通過在地圖上拖動和捏進行縮放來進行平移。您可以自行更改地圖控件的工作方式,以便根據應用程序的需求進行自定義。

在下一節中,您將在地圖上添加一個標記,並在移動地圖時顯示標記所在位置的地址。

您的應用程序的最後一步是在地圖上添加搜索。在這種情況下,您將添加反向地理編碼搜索,以便在某個位置查找項目。為了簡化 Android 應用程序的使用,我們將搜索屏幕的中心。要查找新位置,請將地圖移動到要搜索的位置。我們將在地圖的中心放置一個標記,以顯示搜索的位置。

注意

亞馬遜 Location Service 還提供按名稱或地址進行搜索的功能,以查找地圖上的位置。

添加搜索將由兩個部分組成。

  1. 在屏幕中心添加一個標記,以顯示我們正在搜索的用户。

  2. 為結果添加文本框,然後搜索標記位置處的內容,並顯示在文本框中。

向應用程序添加標記

  1. 將此圖像保存到您的項目,在應用程序,res,可繪製文件夾中,作為red_marker.png(您也可以訪問來自 GitHub。您也可以建立自己的圖像。您也可以使用具有透明度的 .png 文件來顯示不想顯示的零件。

  2. 在安卓工作室中,展開應用程式RES佈局在樹狀圖中,然後開啟activity_main.xmlfile.

  3. 新增 ImageView 作為標記。您需要進行的更改顯示在green

    <?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"> <ImageView android:id="@+id/map_view_marker" android:layout_width="30dp" android:layout_height="30dp" android:elevation="2dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/red_marker" /> <com.amplifyframework.geo.maplibre.view.MapLibreView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" app:mapbox_foregroundLoadColor="@color/white" app:mapbox_renderTextureMode="true" app:mapbox_renderTextureTranslucentSurface="true" /> </androidx.constraintlayout.widget.ConstraintLayout>
  4. 保存文件,然後(可選)構建和運行應用以預覽功能。

您的應用現在屏幕上有一個標記。在這種情況下,它是一個不移動的靜態圖像。它用於顯示地圖視圖的中心,這是我們要搜索的位置。在下一個過程中,我們將在該位置添加搜索。

將某個位置的搜索添加到您的應用

  1. 如果它尚未打開,請打開activity_main.xml文件,如前一個程序所示。添加以下代碼,其中您需要進行的更改位於green。這將創建一個 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"> <ImageView android:id="@+id/map_view_marker" android:layout_width="30dp" android:layout_height="30dp" android:elevation="2dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/red_marker" /> <TextView android:id="@+id/description_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="70dp" android:background="#E6FFFFFF" android:elevation="4dp" android:padding="14dp" android:textAlignment="center" android:textColor="@android:color/black" app:layout_constraintBottom_toBottomOf="parent" /> <com.amplifyframework.geo.maplibre.view.MapLibreView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" app:mapbox_foregroundLoadColor="@color/white" app:mapbox_renderTextureMode="true" app:mapbox_renderTextureTranslucentSurface="true" /> </androidx.constraintlayout.widget.ConstraintLayout>
  2. 在 中應用程式java<package name>文件夾中,打開MainActivity.ktfile. 如下所示修改代碼,您需要進行的更改顯示為綠色(在這種情況下,只顯示部分文件)。

    ... class MainActivity : AppCompatActivity() { private val mapView by lazy { findViewById<MapLibreView>(R.id.mapView) } private val descriptionView by lazy { findViewById<TextView>(R.id.description_text_view) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) initAmplify() setContentView(R.layout.activity_main) mapView.getMapAsync { map -> val initialPosition = LatLng(47.6160281982247, -122.32642111977668) map.cameraPosition = CameraPosition.Builder() .target(initialPosition) .zoom(13.0) .build() map.addOnCameraMoveStartedListener { toggleDescriptionText() } map.addOnCameraIdleListener { reverseGeocode(map) } } } private fun reverseGeocode(map: MapboxMap) { val options = GeoSearchByCoordinatesOptions.builder() .maxResults(1) .build() val centerCoordinates = Coordinates().apply { longitude = map.cameraPosition.target.longitude latitude = map.cameraPosition.target.latitude } Amplify.Geo.searchByCoordinates(centerCoordinates, options, { result -> result.places.firstOrNull()?.let { place -> val amazonPlace = (place as AmazonLocationPlace) runOnUiThread { toggleDescriptionText(amazonPlace.label) } } }, { exp -> Log.e("AndroidQuickStart", "Failed to reverse geocode : $exp") } ) } private fun toggleDescriptionText(label: String? = "") { if (label.isNullOrBlank()) { descriptionView.fadeOut() } else { descriptionView.text = label descriptionView.fadeIn() } } private fun initAmplify() { try { Amplify.addPlugin(AWSCognitoAuthPlugin()) Amplify.addPlugin(AWSLocationGeoPlugin()) Amplify.configure(applicationContext) Log.i("AndroidQuickStart", "Initialized Amplify") } catch (error: AmplifyException) { Log.e("AndroidQuickStart", "Could not initialize Amplify", error) } } override fun onStart() { super.onStart() mapView?.onStart() } ...

    此代碼適用於地圖視圖。中的地圖視圖MapLibre GL由虛擬攝像機位置定義。移動地圖可以被視為移動該虛擬攝像機。

    • descriptionView函數 — 這是一個幫助函數,用於查找和引用 TextView 在佈局中創建的。

    • onCreate— 此函數更新為註冊兩個新事件。

      所以此onCameraMove事件發生在用户移動地圖時。一般來説,移動地圖時,我們希望隱藏搜索,直到用户完成移動地圖。

      所以此onCameraIdle事件發生在用户暫停移動地圖時。此活動將調用我們的reverseGeocode函數,以在地圖的中心進行搜索。

    • reverseGeocode— 這個函數,在事件onCameraIdle中,在地圖的中心搜索某個位置並更新 TextView 以顯示結果。它使用攝像機目標,該目標定義地圖的中心(攝影機所查看的位置)。

    • toggleDescriptionText— 此函數更新結果文本,或隱藏 TextView 當沒有什麼可看的。

  3. 保存您的文件,建立和運行您的應用程式,以查看其正常工作。

您的快速入門應用程序已完成。本教程向您展示瞭如何建立一個 Android 應用程式:

  • 建立用户可與之交互的地圖。

  • 處理與用户更改地圖視圖相關聯的多個地圖事件 (cameraMoveStartedCameraIdle

  • 調用亞馬遜 Location Service API,特別是要在某個位置搜索地圖,使用 Amplify 的searchByCoordinatesoperation.

查看最終應用

此應用程序的最終項目和源代碼可用GitHub 上的

後續步驟

您已完成快速入門教程,應該瞭解如何使用亞馬遜 Location Service 構建應用程序。要利用亞馬遜位置獲得更多信息,您可以查看以下資源: