Para agregar el rastreo a su aplicación de ejemplo, siga estos pasos:
Agregue dependencias del SDK de rastreo y autenticación a su proyecto.
Incluya las entradas de permisos y servicios en su archivo AndroidManifest.xml.
Configure el código del botón de iniciar/detener el rastreo con composición.
Agregue código para crear un objeto de LocationTracker e iniciar y detener el rastreo.
Cree una ruta de prueba con el emulador de Android.
Agregue dependencias del SDK de rastreo y autenticación a su proyecto.
En la ventana Proyecto, abra Gradle y, a continuación, abra el archivo
libs.versions.toml
en la vista de árbol. Esto abrirá el archivolibs.versions.toml
para editarlo. Ahora agregue la siguiente versión y los datos de librerías en el archivolibs.versions.toml
.[versions] ... auth = "0.0.1" tracking = "0.0.1" [libraries] ... auth = { group = "software.amazon.location", name = "auth", version.ref = "auth" } tracking = { module = "software.amazon.location:tracking", version.ref = "tracking" } [plugins] ...
Cuando termine de editar el archivo
libs.versions.toml
, Android Studio debe volver a sincronizar el proyecto. En la parte superior de la ventana de ediciónlibs.versions.toml
, AndroidStudio le pide que sincronice. Seleccione “Sincronizar ahora” para sincronizar el proyecto antes de continuar.En la ventana Proyecto, abra Scripts de Gradle en la vista de árbol y seleccione el archivo
build.gradle
para el módulo de la aplicación. Esto abrirá el archivobuild.gradle
para editarlo.En la parte inferior del archivo, en la sección de dependencias, agregue las siguientes dependencias.
dependencies { ... implementation(libs.auth) implementation(libs.tracking) }
Cuando termine de editar las dependencias de Gradle, AndroidStudio debe volver a sincronizar el proyecto. En la parte superior de la ventana de edición build.gradle, AndroidStudio le pide que sincronice. Seleccione Sincronizar para sincronizar el proyecto antes de continuar.
Incluya las entradas de permisos y servicios en su archivo AndroidManifest.xml.
Para incluir las entradas de permisos y servicios correctas en su
AndroidManifest.xml file
, actualice el archivo con el siguiente código:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.AndroidQuickStartApp" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true" android:label="@string/app_name" android:theme="@style/Theme.AndroidQuickStartApp"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Configure el código del botón de iniciar/detener el rastreo con composición.
Agregue dos imágenes de reproducción y pausa en res en drawable denominadas ic_pause e ic_play. También puede acceder a la imagen desde GitHub
. Si aún no está abierto, abra e archivo
MapLoadScreen.kt
como en el procedimiento anterior. Añada el código siguiente. Esto creará una vista del botón de composición en el que podremos hacer clic para iniciar y detener el rastreo.// ...other imports import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults @Composable fun MapLoadScreen( mapReadyCallback: OnMapReadyCallback, mainViewModel: MainViewModel, onStartStopTrackingClick: () -> Unit ) { Box( modifier = Modifier .fillMaxWidth() .fillMaxHeight(), ) { MapView(mapReadyCallback) Box( modifier = Modifier .align(Alignment.Center), ) { Image( painter = painterResource(id = R.drawable.red_marker), contentDescription = "marker", modifier = Modifier .size(40.dp) .align(Alignment.Center), ) } if (mainViewModel.isLabelAdded) { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Bottom ) { Box( modifier = Modifier .fillMaxWidth() .background(Color.White), ) { Text( text = mainViewModel.label, modifier = Modifier .padding(16.dp) .align(Alignment.Center) .testTag("label") .semantics { contentDescription = "label" }, fontSize = 14.sp, ) } Spacer(modifier = Modifier.height(80.dp)) } } Column( modifier = Modifier .fillMaxSize() .padding(bottom = 16.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Bottom, ) { Button( onClick = onStartStopTrackingClick, modifier = Modifier .padding(horizontal = 16.dp) ) { Text( text = if (mainViewModel.isLocationTrackingForegroundActive) "Stop tracking" else "Start tracking", color = Color.Black ) Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing)) Image( painter = painterResource(id = if (mainViewModel.isLocationTrackingForegroundActive) R.drawable.ic_pause else R.drawable.ic_play), contentDescription = if (mainViewModel.isLocationTrackingForegroundActive) "stop_tracking" else "start_tracking" ) } } } } @Composable fun MapView(mapReadyCallback: OnMapReadyCallback) { AndroidView( factory = { context -> val mapView = org.maplibre.android.maps.MapView(context) mapView.onCreate(null) mapView.getMapAsync(mapReadyCallback) mapView }, ) }
Agregue código para crear un objeto de LocationTracker e iniciar y detener el rastreo.
Agregue el siguiente código dentro del archivo
MainViewModel.kt
.... var isLocationTrackingForegroundActive: Boolean by mutableStateOf(false) var locationTracker: LocationTracker? = null
Agregue el siguiente código al archivo
MainActivity.kt
.// ...other imports import software.amazon.location.auth.AuthHelper import software.amazon.location.auth.LocationCredentialsProvider import software.amazon.location.tracking.LocationTracker import software.amazon.location.tracking.aws.LocationTrackingCallback import software.amazon.location.tracking.config.LocationTrackerConfig import software.amazon.location.tracking.database.LocationEntry import software.amazon.location.tracking.filters.DistanceLocationFilter import software.amazon.location.tracking.filters.TimeLocationFilter import software.amazon.location.tracking.util.TrackingSdkLogLevel class MainActivity : ComponentActivity(), OnMapReadyCallback, MapLibreMap.OnCameraMoveStartedListener, MapLibreMap.OnCameraIdleListener { private val mainViewModel: MainViewModel by viewModels() private val poolId = "
YOUR_AWS_IDENTITY_POOL_ID
" private val trackerName = "YOUR_AWS_TRACKER_NAME
" private val region = "YOUR_AWS_REGION
" private val mapName = "YOUR_AWS_MAP_NAME
" private val apiKey = "YOUR_AWS_API_KEY
" private val coroutineScope = MainScope() private lateinit var locationCredentialsProvider: LocationCredentialsProvider private lateinit var authHelper: AuthHelper override fun onCreate(savedInstanceState: Bundle?) { MapLibre.getInstance(this) super.onCreate(savedInstanceState) setContent { TestMapAppTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { MapLoadScreen(this, mainViewModel, onStartStopTrackingClick = { if (mainViewModel.isLocationTrackingForegroundActive) { mainViewModel.isLocationTrackingForegroundActive = false mainViewModel.locationTracker?.stop() } else { if (checkLocationPermission(this)) return@MapLoadScreen mainViewModel.isLocationTrackingForegroundActive = true mainViewModel.locationTracker?.start(locationTrackingCallback = object : LocationTrackingCallback { override fun onLocationAvailabilityChanged(locationAvailable: Boolean) { } override fun onLocationReceived(location: LocationEntry) { } override fun onUploadSkipped(entries: LocationEntry) { } override fun onUploadStarted(entries: ListLocationEntry
) { } override fun onUploaded(entries: ListLocationEntry
) { } }) } }) } } } authenticateUser() } private fun authenticateUser() { coroutineScope.launch { authHelper = AuthHelper(applicationContext) locationCredentialsProvider = authHelper.authenticateWithCognitoIdentityPool( poolId, ) locationCredentialsProvider.let { val config = LocationTrackerConfig( trackerName = trackerName, logLevel = TrackingSdkLogLevel.DEBUG, latency = 1000, frequency = 5000, waitForAccurateLocation = false, minUpdateIntervalMillis = 5000, ) mainViewModel.locationTracker = LocationTracker( applicationContext, it, config, ) mainViewModel.locationTracker?.enableFilter(TimeLocationFilter()) mainViewModel.locationTracker?.enableFilter(DistanceLocationFilter()) } } } private fun checkLocationPermission(context: Context) = ActivityCompat.checkSelfPermission( context, Manifest.permission.ACCESS_FINE_LOCATION, ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( context, Manifest.permission.ACCESS_COARSE_LOCATION, ) != PackageManager.PERMISSION_GRANTED override fun onMapReady(map: MapLibreMap) { map.setStyle( Style.Builder() .fromUri( "https://maps.geo.$region.amazonaws.com/maps/v0/maps/$mapName/style-descriptor?key=$apiKey" ), ) { mainViewModel.mapLibreMap = map map.uiSettings.isAttributionEnabled = true map.uiSettings.isLogoEnabled = false map.uiSettings.attributionGravity = Gravity.BOTTOM or Gravity.END val initialPosition = LatLng(47.6160281982247, -122.32642111977668) map.cameraPosition = CameraPosition.Builder() .target(initialPosition) .zoom(14.0) .build() map.addOnCameraMoveStartedListener(this) map.addOnCameraIdleListener(this) map.cameraPosition.target?.let { latLng -> mainViewModel.reverseGeocode( LatLng( latLng.latitude, latLng.longitude ), apiKey ) } } } override fun onCameraMoveStarted(p0: Int) { mainViewModel.label = "" mainViewModel.isLabelAdded = false } override fun onCameraIdle() { if (!mainViewModel.isLabelAdded) { mainViewModel.mapLibreMap?.cameraPosition?.target?.let { latLng -> mainViewModel.reverseGeocode( LatLng( latLng.latitude, latLng.longitude ), apiKey ) } } } }El código anterior muestra cómo crear un objeto de
LocationTracker
conAuthHelper
y cómo iniciar y detener el rastreo con LocationTracker.authenticateUser()
: este método crea objetos de AuthHelper y LocationTracker.onStartStopTrackingClick
: Esta devolución de llamada se activa cuando el usuario hace clic en el botón de iniciar/detener el rastreo, que iniciará o detendrá el rastreo con el SDK de rastreo.
Cree una ruta de prueba con el emulador de Android.
Abra el emulador iniciando el AVD con Android Studio.
Abra los controles ampliados haciendo clic en el icono Más (tres puntos) de la barra de herramientas del emulador.
Abra la ubicación seleccionando Ubicación en la barra lateral.
Cree una ruta con datos GPX o haga clic en el mapa y elija los datos de origen y destino.
Inicie la simulación haciendo clic en REPRODUCIR RUTA para empezar a simular la ruta GPS.
Pruebe la aplicación ejecutándola y observando cómo gestiona la ruta simulada.
Esta es la demostración completa de la aplicación Android Quick Start.
Siguientes pasos
Ha completado el tutorial de inicio rápido y debería entender, más o menos, cómo se utiliza Amazon Location Service para crear aplicaciones.
El código fuente de esta aplicación está disponible en GitHub
Para sacar más provecho de Amazon Location, puede consultar los siguientes recursos:
-
Profundice en los conceptos de Amazon Location Service
-
Obtenga más información sobre cómo utilizar las funciones y características de Amazon Location
-
Descubra cómo ampliar este ejemplo y crear aplicaciones más complejas consultando ejemplos de código con Amazon Location