es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Iniciar un servicio cuando la aplicación se finaliza a través de una notificación push.

Estoy intentando implementar el seguimiento de ubicación en segundo plano a través de una notificación persistente. Puedo iniciar fácilmente el servicio con la notificación si la aplicación está en primer plano o abierta en el administrador de tareas del teléfono. Sin embargo, quiero activar el inicio del servicio a través de una notificación push, por ejemplo. Cuando lo hago, no puedo iniciar el servicio en absoluto y el onMessageReceived solo activa el super.onMessageReceived. ¿Hay alguna solución alternativa para esto?

Aquí está el código que tengo en el método:

override fun onMessageReceived(p0: RemoteMessage) {
    Intent(this, MyService::class.java).also { intent ->
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startForegroundService(intent) else startService(intent)
    }
}

Cuando menciono activar el super, me refiero a que solo muestra la notificación predeterminada con el título/descripción que escribí en la pestaña de Mensajería en la nube de Firebase.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución para implementar el seguimiento de ubicación en segundo plano mediante una notificación persistente

    Si estás intentando implementar el seguimiento de ubicación en segundo plano utilizando una notificación persistente, es posible que encuentres problemas al intentar iniciar el servicio a través de una notificación push. El método onMessageReceived puede desencadenar solo super.onMessageReceived, pero el servicio no se inicia. Aquí tienes una solución para este problema:

    1. Asegúrate de registrar tu servicio en el archivo de manifiesto.
    <service android:name=".MyService" android:exported="false"></service>
    
    1. Asegúrate de que los servicios de ubicación de tu dispositivo estén activados y se haya otorgado el permiso.
    2. Modifica tu método onMessageReceived para incluir un PendingIntent.

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        val intent = Intent(this, MyService::class.java)
        val pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    
        NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(remoteMessage.notification?.title)
            .setContentText(remoteMessage.notification?.body)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()
            .also { notification ->
                NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notification)
            }
    }
    
    1. En tu servicio, sobrescribe el método onStartCommand y devuelve la bandera START_STICKY.
    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        if (intent.action == ACTION_START_FOREGROUND_SERVICE) {
            startForegroundService()
        }
    
        return START_STICKY
    }
    
    private fun startForegroundService() {
        // Inicia el seguimiento de ubicación
    }
    
    1. Finalmente, inicia el servicio en tu clase MyService utilizando la acción START_FOREGROUND_SERVICE.
    class MyService: Service() {
    
        override fun onBind(intent: Intent?): IBinder? {
            return null
        }
    
        override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
            if (intent?.action == ACTION_START_FOREGROUND_SERVICE) {
                startForegroundService()
            }
    
            return START_STICKY
        }
    
        private fun startForegroundService() {
            // Inicia el seguimiento de ubicación
        }
    }
    

    ¡Eso es todo! Con esta solución, ahora puedes iniciar el servicio de seguimiento de ubicación incluso si la aplicación está en segundo plano o no se está ejecutando.

Comments are closed.