En este artículo, vamos a aprender sobre una API llamada API de transición de reconocimiento de actividad o API de transición que está destinada a detectar la actividad de un usuario en particular, como conducir, caminar o correr, etc. Hay muchas aplicaciones que utilizan esta actividad. API de transición de reconocimiento. Por ejemplo, una aplicación de búsqueda de kilómetros comienza a ejecutarse cuando comienza a conducir un automóvil o una bicicleta y se detiene cuando deja de conducir. Otros ejemplos de este reconocimiento de actividad pueden ser cualquier aplicación de salud y estado físico que determine cuántos metros o kilómetros está corriendo o caminando en un día en particular y luego puede encontrar las calorías quemadas en ese día y mucho más.
Aquí vamos a crear una aplicación que detectará la actividad del usuario, como estar quieto, correr, caminar , conducir u otra cosa . A continuación se muestra una imagen de captura de pantalla de muestra para tener una idea de lo que vamos a hacer en este artículo.
Implementación paso a paso
Paso 1: Crear un nuevo proyecto
Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Kotlin como lenguaje de programación.
Paso 2: Agregar dependencias
// Ubicación del servicio de Google Play
implementación ‘com.google.android.gms:play-services-ubicación:18.0.0’
implementación “androidx.preference:preference-ktx:1.1.1”
// Madera
implementación ‘com.jakewharton.timber:timber:4.7.1’
// Biblioteca de notificaciones
implementación “io.karn:notify:1.3.0”
// Permisos fáciles
implementación ‘pub.devrel:permisosfáciles:3.0.0’
// Diseño de materiales
implementación ‘com.google.android.material:material:1.5.0-alpha02’
Paso 3: Agregue una referencia al repositorio maven en el build.gradle de nivel superior
todos los proyectos {
repositorios {
…
// Para la biblioteca Notificar
experto {url ‘https://jitpack.io’}
}
}
Paso 4: Trabajar con AndroidMenifest.xml
Asegúrese de agregar los siguientes permisos
<!– Obligatorio para menores de 28 años. –>
<usos-permiso android:name=”com.google.android.gms.permission.ACTIVITY_RECOGNITION” />
<!– Requerido para mayores de 29 años. –>
<usos-permiso android:name=”android.permission.ACTIVITY_RECOGNITION” />
<aplicación>
….
<actividad>
….
</actividad>
<receptor
android:name=”.ActivityTransitionReceiver”
Android: exportado = «falso»
android:permiso=”com.google.android.gms.permiso.ACTIVIDAD_RECONOCIMIENTO”>
<intent-filter>
<acción android:name=”acción.TRANSITIONS_DATA” />
</intent-filter>
</receptor>
</aplicación>
Paso 5: agregar la interfaz de usuario de la aplicación.
Vaya a la aplicación > res > diseño > actividad_principal.xml y agregue el siguiente código a ese archivo. A continuación se muestra el código para el archivo activity_main.xml .
XML
<?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.google.android.material.switchmaterial.SwitchMaterial android:id="@+id/switchActivityTransition" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Activity Transition" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Paso 6: Cree la clase Constant.kt y escriba todas las constantes requeridas aquí
Kotlin
// declare all required constants at one place object Constants { const val REQUEST_CODE_ACTIVITY_TRANSITION = 123 const val REQUEST_CODE_INTENT_ACTIVITY_TRANSITION = 122 const val ACTIVITY_TRANSITION_NOTIFICATION_ID = 111 const val ACTIVITY_TRANSITION_STORAGE = "ACTIVITY_TRANSITION_STORAGE" }
En Android, tenemos el Cliente de reconocimiento de actividad que activa su dispositivo a intervalos regulares y luego recopila la información del sensor del dispositivo y luego esta información recopilada se utilizará para determinar las actividades con la ayuda de algún cálculo de aprendizaje automático. Simplemente debe utilizar el Cliente de reconocimiento de actividad y la API terminará para usted sin ninguna razón convincente para aprender ML.
Las siguientes son las actividades que puede detectar el cliente de reconocimiento de actividad:
- STILL: cuando el dispositivo móvil esté quieto cuando el usuario esté sentado en algún lugar o el dispositivo móvil no tenga movimiento, el cliente de reconocimiento de actividad detectará la actividad STILL.
- ON_FOOT: cuando el dispositivo móvil se mueve a una velocidad normal, es decir, el usuario que lleva el dispositivo móvil camina o corre, el cliente de reconocimiento de actividad detectará la actividad ON_FOOT.
- CAMINAR: esta es una subactividad de la actividad ON_FOOT que detecta el cliente de reconocimiento de actividad cuando el usuario que lleva el dispositivo móvil está caminando.
- EJECUTANDO: Esta también es una subactividad de la actividad ON_FOOT que detecta el cliente de reconocimiento de actividad cuando el usuario que lleva el dispositivo móvil está corriendo.
- IN_VEHICLE: esta actividad se detecta cuando el dispositivo móvil está en el autobús, automóvil o algún otro tipo de vehículo o el usuario que sostiene el dispositivo móvil está presente en el vehículo.
- ON_BICYCLE: Cuando el dispositivo está en la bicicleta o el usuario que lleva el móvil está en una bicicleta entonces se detectará esta actividad.
- INCLINACIÓN: cuando el dispositivo móvil se levanta y tiene algún ángulo con la superficie plana, el cliente de reconocimiento de actividad detectará esta actividad.
- DESCONOCIDO: el cliente de reconocimiento de actividad mostrará este resultado cuando el dispositivo no pueda detectar ninguna actividad en el dispositivo móvil.
Paso 7: Cree la clase ActivityTransitionsUtil.kt que contendrá una lista de tipos de actividades y tipos de transición
Para comenzar a recibir notificaciones sobre transiciones de actividad, debemos crear un objeto ActivityTransitionRequest que determine el tipo de actividad y transición. Para ello, debemos crear una lista de objetos ActivityTransition y pasarla a la clase ActivityTransitionRequest. A continuación se muestra el código completo de la clase ActivityTransitionsUtil.kt. Se agregan comentarios dentro del código para comprender cada línea del código.
Kotlin
import android.Manifest import android.content.Context import android.os.Build import androidx.annotation.RequiresApi import com.google.android.gms.location.ActivityTransition import com.google.android.gms.location.ActivityTransitionRequest import com.google.android.gms.location.DetectedActivity import pub.devrel.easypermissions.EasyPermissions object ActivityTransitionsUtil { private fun getTransitions(): MutableList<ActivityTransition> { // List of activity transitions to track val transitions = mutableListOf<ActivityTransition>() transitions += ActivityTransition.Builder() .setActivityType(DetectedActivity.IN_VEHICLE) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) .build() transitions += ActivityTransition.Builder() .setActivityType(DetectedActivity.IN_VEHICLE) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) .build() transitions += ActivityTransition.Builder() .setActivityType(DetectedActivity.WALKING) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) .build() transitions += ActivityTransition.Builder() .setActivityType(DetectedActivity.WALKING) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) .build() transitions += ActivityTransition.Builder() .setActivityType(DetectedActivity.STILL) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) .build() transitions += ActivityTransition.Builder() .setActivityType(DetectedActivity.STILL) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) .build() transitions += ActivityTransition.Builder() .setActivityType(DetectedActivity.RUNNING) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER) .build() transitions += ActivityTransition.Builder() .setActivityType(DetectedActivity.RUNNING) .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT) .build() return transitions } // pass the list of ActivityTransition objects to the ActivityTransitionRequest class fun getActivityTransitionRequest() = ActivityTransitionRequest(getTransitions()) // ask to allow permissions @RequiresApi(Build.VERSION_CODES.Q) fun hasActivityTransitionPermissions(context: Context): Boolean = EasyPermissions.hasPermissions( context, Manifest.permission.ACTIVITY_RECOGNITION ) // types of activities fun toActivityString(activity: Int): String { return when (activity) { DetectedActivity.STILL -> "STILL" DetectedActivity.WALKING -> "WALKING" DetectedActivity.IN_VEHICLE -> "IN VEHICLE" DetectedActivity.RUNNING -> "RUNNING" else -> "UNKNOWN" } } // type of transitions fun toTransitionType(transitionType: Int): String { return when (transitionType) { ActivityTransition.ACTIVITY_TRANSITION_ENTER -> "ENTER" ActivityTransition.ACTIVITY_TRANSITION_EXIT -> "EXIT" else -> "UNKNOWN" } } }
Paso 8: Cree la clase ActivityTransitionReceiver.kt que recibe las actividades y notifica el estado del usuario
A continuación se muestra el código completo de la clase ActivityTransitionReceiver.kt. Se agregan comentarios dentro del código para comprender cada línea del código.
Kotlin
import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.widget.Toast import com.google.android.gms.location.ActivityTransitionResult import io.karn.notify.Notify import java.text.SimpleDateFormat import java.util.* class ActivityTransitionReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (ActivityTransitionResult.hasResult(intent)) { val result = ActivityTransitionResult.extractResult(intent) result?.let { result.transitionEvents.forEach { event -> // Info about activity val info = "Transition: " + ActivityTransitionsUtil.toActivityString(event.activityType) + " (" + ActivityTransitionsUtil.toTransitionType(event.transitionType) + ")" + " " + SimpleDateFormat("HH:mm:ss", Locale.US).format(Date()) // notification details Notify .with(context) .content { title = "Activity Detected" text = "I can see you are in ${ ActivityTransitionsUtil.toActivityString( event.activityType ) } state" } .show(id = Constants.ACTIVITY_TRANSITION_NOTIFICATION_ID) Toast.makeText(context, info, Toast.LENGTH_LONG).show() } } } } }
Paso 9: trabajar con MainActivity.kt. A continuación se muestra el código de MainActivity.kt
A continuación se muestra el código completo del archivo MainActivity.kt . Se agregan comentarios dentro del código para comprender cada línea del código.
Kotlin
import android.Manifest import android.app.PendingIntent import android.content.Intent import android.content.SharedPreferences import android.os.Build import android.os.Bundle import android.widget.Toast import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatActivity import com.gfg.article.activityrecognition.Constants.ACTIVITY_TRANSITION_STORAGE import com.google.android.gms.location.ActivityRecognition import com.google.android.gms.location.ActivityRecognitionClient import kotlinx.android.synthetic.main.activity_main.* import pub.devrel.easypermissions.AppSettingsDialog import pub.devrel.easypermissions.EasyPermissions class MainActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks { lateinit var client: ActivityRecognitionClient lateinit var storage: SharedPreferences override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // The Activity Recognition Client returns a // list of activities that a user might be doing client = ActivityRecognition.getClient(this) // variable to check whether the user have already given the permissions storage = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this) // check switch is on/off switchActivityTransition.isChecked = getSwitchState() switchActivityTransition.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { // check for devices with Android 10 (29+). if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q // check for permission && !ActivityTransitionsUtil.hasActivityTransitionPermissions(this) ) { switchActivityTransition.isChecked = false // request for permission requestActivityTransitionPermission() } else { // when permission is already allowed requestForUpdates() } } else { saveSwitchState(false) deregisterForUpdates() } } } // when permission is denied @RequiresApi(Build.VERSION_CODES.Q) override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { // permission is denied permanently if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { AppSettingsDialog.Builder(this).build().show() } else { requestActivityTransitionPermission() } } // after giving permission override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) { switchActivityTransition.isChecked = true saveSwitchState(true) requestForUpdates() } // request for permission override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) } // To register for changes we have to also supply the requestActivityTransitionUpdates() method // with the PendingIntent object that will contain an intent to the component // (i.e. IntentService, BroadcastReceiver etc.) that will receive and handle updates appropriately. private fun requestForUpdates() { client .requestActivityTransitionUpdates( ActivityTransitionsUtil.getActivityTransitionRequest(), getPendingIntent() ) .addOnSuccessListener { showToast("successful registration") } .addOnFailureListener { showToast("Unsuccessful registration") } } // Deregistering from updates // call the removeActivityTransitionUpdates() method // of the ActivityRecognitionClient and pass // ourPendingIntent object as a parameter private fun deregisterForUpdates() { client .removeActivityTransitionUpdates(getPendingIntent()) .addOnSuccessListener { getPendingIntent().cancel() showToast("successful deregistration") } .addOnFailureListener { e: Exception -> showToast("unsuccessful deregistration") } } // creates and returns the PendingIntent object which holds // an Intent to an BroadCastReceiver class private fun getPendingIntent(): PendingIntent { val intent = Intent(this, ActivityTransitionReceiver::class.java) return PendingIntent.getBroadcast( this, Constants.REQUEST_CODE_INTENT_ACTIVITY_TRANSITION, intent, PendingIntent.FLAG_UPDATE_CURRENT ) } // requesting for permission @RequiresApi(Build.VERSION_CODES.Q) private fun requestActivityTransitionPermission() { EasyPermissions.requestPermissions( this, "You need to allow Activity Transition Permissions in order to recognize your activities", Constants.REQUEST_CODE_ACTIVITY_TRANSITION, Manifest.permission.ACTIVITY_RECOGNITION ) } private fun showToast(message: String) { Toast.makeText(this, message, Toast.LENGTH_LONG) .show() } // save switch state private fun saveSwitchState(value: Boolean) { storage .edit() .putBoolean(ACTIVITY_TRANSITION_STORAGE, value) .apply() } // get the state of switch private fun getSwitchState() = storage.getBoolean(ACTIVITY_TRANSITION_STORAGE, false) }
Ahora, ejecuta la aplicación
Producción:
Código fuente: Haga clic aquí