Skip to Content
EmpezandoSDK de aleteo

Flutter SDK: uniendo Dart y Native

Tracelet es único porque lleva casi toda la lógica a los SDK nativos de iOS y Android. ¿Por qué? Porque los aislados de Dart son pesados ​​y activar un motor Flutter en segundo plano cada vez que el usuario da un paso destruye la vida útil de la batería.

Esta página explica cómo interactúa la capa Flutter con el motor nativo en escenarios del mundo real.


Escenario 1: la suscripción a la interfaz de usuario

Conceptos explorados: Flujos de eventos, ejecución sin cabeza

El problema

Estás creando una aplicación de fitness. Cuando el usuario mira la pantalla, desea que un pequeño punto azul se mueva en un mapa de Google en tiempo real. Cuando el usuario bloquea la pantalla, aún desea registrar la ejecución en la base de datos, pero no necesita actualizar una interfaz de usuario que nadie está mirando.

Cómo lo resuelve Tracelet

Tracelet separa el Native Tracking Engine de los Dart UI Streams.

Cuando llamas a Tracelet.start(), el motor nativo de iOS/Android se enciende. Maneja la detección de movimiento, el filtrado de GPS, el guardado de SQLite y la sincronización HTTP completamente en Swift/Kotlin.

En tu interfaz de usuario de Flutter, simplemente te suscribes a la transmisión:

import 'package:tracelet/tracelet.dart' as tl; void initializeTracking() async { // 1. Listen to events in the UI tl.Tracelet.onLocation((tl.Location location) { print('Update UI map marker: ${location.coords.latitude}, ${location.coords.longitude}'); }); tl.Tracelet.onMotionChange((tl.Location location) { print('User started/stopped moving: ${location.isMoving}'); }); // 2. Start the native engine await tl.Tracelet.ready(tl.Config.balanced()); await tl.Tracelet.start(); }

La Magia: Si el usuario fuerza su aplicación, la transmisión onLocation Dart muere. Pero el motor de seguimiento nativo sigue funcionando. Sigue guardando ubicaciones en SQLite. Cuando el usuario vuelva a abrir la aplicación más tarde, puede consultar la base de datos SQLite utilizando su Adaptador de base de datos para representar su ruta.


Escenario 2: el flujo de incorporación

Conceptos explorados: Manejo de permisos, rechazos

El problema

Está creando una aplicación para que los pacientes de edad avanzada realicen un seguimiento de las deambulaciones. Necesita permiso de ubicación en segundo plano “Siempre”. Si simplemente les muestra el cuadro de diálogo de permiso del sistema, se confundirán, tocarán “Denegar” y la aplicación se volverá inútil.

Cómo lo resuelve Tracelet

Tracelet nunca solicita permisos automáticamente. Deja que el flujo de la interfaz de usuario dependa completamente de su código Flutter, lo que le permite mostrar cuadros de diálogo educativos personalizados antes de activar las aterradoras indicaciones del sistema operativo.

import 'package:tracelet/tracelet.dart' as tl; // 1. Check current status final status = await tl.Tracelet.requestLocationAuthorization(); // 2. The user permanently denied permission in the past if (status == tl.AuthorizationStatus.deniedForever) { // Show a beautifully designed Flutter dialog explaining WHY you need it. // Add a button that calls: await tl.Tracelet.openAppSettings(); return; } // 3. We haven't asked yet, or they selected "Ask Next Time" if (status == tl.AuthorizationStatus.notDetermined || status == tl.AuthorizationStatus.denied) { // Ask for foreground permission first final result = await tl.Tracelet.requestLocationAuthorization(); if (result == tl.AuthorizationStatus.whenInUse) { // They granted "When In Use" // Show a second Flutter dialog explaining why "Always" is needed. // Then upgrade the permission: await tl.Tracelet.requestLocationAuthorization(); } }

Tracelet.requestLocationAuthorization() devuelve una enumeración AuthorizationStatus:

  • notDetermined: Aún no has preguntado.
  • denied: Usuario denegado (puede volver a preguntar en Android).
  • whenInUse: Se concede únicamente en primer plano.
  • always: Acceso en segundo plano concedido.
  • deniedForever: El usuario marcó “No volver a preguntar” o iOS lo negó permanentemente. DEBES enviarlos a la configuración.