flutter_location_services 0.0.1 copy "flutter_location_services: ^0.0.1" to clipboard
flutter_location_services: ^0.0.1 copied to clipboard

A robust Flutter package for live location tracking with background support, geofencing, routing, and Firebase synchronization.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_location_services/flutter_location_services.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:example/firebase_background_service.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Smart Location Demo',
      theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _currentIndex = 0;

  final List<Widget> _pages = [
    const BasicTrackingPage(),
    const RoutingPage(),
    const GeofencePage(),
  ];

  @override
  void initState() {
    super.initState();
    _initSmartLocation();
  }

  Future<void> _initSmartLocation() async {
    // Basic config
    SmartLocation.configure(
      accuracy: SmartAccuracy.high,
      debugMode: true,
      apiKey: 'YOUR_API_KEY_HERE', // User: Replace this with your API Key
    );
    Future.delayed(const Duration(seconds: 1), () async {
      // Trigger a permission check/request on startup
      try {
        await SmartLocation.getCurrentPosition();
      } catch (_) {
        // Ignore initial error, just to trigger permission dialog
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pages[_currentIndex],
      bottomNavigationBar: NavigationBar(
        selectedIndex: _currentIndex,
        onDestinationSelected: (i) => setState(() => _currentIndex = i),
        destinations: const [
          NavigationDestination(
            icon: Icon(Icons.my_location),
            label: 'Tracking',
          ),
          NavigationDestination(icon: Icon(Icons.directions), label: 'Routing'),
          NavigationDestination(icon: Icon(Icons.security), label: 'Geofence'),
        ],
      ),
    );
  }
}

// --- Page 1: Basic Tracking ---

class BasicTrackingPage extends StatefulWidget {
  const BasicTrackingPage({super.key});

  @override
  State<BasicTrackingPage> createState() => _BasicTrackingPageState();
}

class _BasicTrackingPageState extends State<BasicTrackingPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Live Tracking')),
      body: SmartLocationMap(showLiveLocation: true, onMapCreated: (c) {}),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton.extended(
            heroTag: 'stop_tracking',
            onPressed: () async {
              try {
                await SmartLocation.stopBackgroundTracking();
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Tracking Stopped')),
                );
              } catch (e) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                    content: Text('Error stopping tracking: $e'),
                    backgroundColor: Colors.red,
                  ),
                );
              }
            },
            label: const Text('Stop'),
            icon: const Icon(Icons.stop),
            backgroundColor: Colors.red,
          ),
          const SizedBox(height: 10),
          FloatingActionButton.extended(
            heroTag: 'start_tracking',
            onPressed: () async {
              try {
                await SmartLocation.startBackgroundTracking(
                  onBackgroundStart: firebaseOnStart,
                );
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Tracking Started')),
                );
              } on SmartLocationError catch (e) {
                if (e.type == SmartErrorType.serviceDisabled) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text(e.message),
                      backgroundColor: Colors.red,
                      action: SnackBarAction(
                        label: 'Enable',
                        onPressed: () => SmartLocation.openLocationSettings(),
                        textColor: Colors.white,
                      ),
                    ),
                  );
                } else if (e.type == SmartErrorType.permissionDenied ||
                    e.type == SmartErrorType.permissionDeniedForever) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text(e.message),
                      backgroundColor: Colors.red,
                      action: SnackBarAction(
                        label: 'Settings',
                        onPressed: () => SmartLocation.openAppSettings(),
                        textColor: Colors.white,
                      ),
                    ),
                  );
                } else {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text('Error: ${e.message}'),
                      backgroundColor: Colors.red,
                    ),
                  );
                }
              } catch (e) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                    content: Text('Error: $e'),
                    backgroundColor: Colors.red,
                  ),
                );
              }
            },
            label: const Text('Start'),
            icon: const Icon(Icons.play_arrow),
            backgroundColor: Colors.green,
          ),
        ],
      ),
    );
  }
}

// --- Page 2: Routing ---

class RoutingPage extends StatefulWidget {
  const RoutingPage({super.key});

  @override
  State<RoutingPage> createState() => _RoutingPageState();
}

class _RoutingPageState extends State<RoutingPage> {
  SmartRoute? _route;
  bool _loading = false;

  Future<void> _getRoute() async {
    setState(() => _loading = true);
    try {
      // Mock coordinates for demo (New York)
      final start = const LatLng(40.7128, -74.0060);
      final end = const LatLng(40.730610, -73.935242);

      final route = await SmartLocation.getRoute(
        source: start,
        destination: end,
      );
      setState(() => _route = route);
    } catch (e) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(SnackBar(content: Text('Error: $e')));
    } finally {
      setState(() => _loading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Routing'),
        actions: [
          IconButton(
            icon: const Icon(Icons.bug_report),
            tooltip: 'Toggle Test Mode',
            onPressed: () {
              SmartLocation.configure(
                routeProvider: RouteProviderType.mock,
                debugMode: true,
              );
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(
                  content: Text('Test Mode Enabled (Mock Routes)'),
                ),
              );
            },
          ),
        ],
      ),
      body: Stack(
        children: [
          SmartLocationMap(
            route: _route,
            showLiveLocation: false,
            markers: _route == null
                ? {}
                : {
                    Marker(
                      markerId: const MarkerId('start'),
                      position: _route!.points.first,
                    ),
                    Marker(
                      markerId: const MarkerId('end'),
                      position: _route!.points.last,
                    ),
                  },
          ),
          if (_loading) const Center(child: CircularProgressIndicator()),
        ],
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          if (_route != null) ...[
            FloatingActionButton.extended(
              heroTag: 'sim',
              onPressed: () {
                SmartLocation.startSimulation(_route!, speedKmH: 120);
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Simulation Started')),
                );
              },
              label: const Text('Simulate Trip'),
              icon: const Icon(Icons.play_arrow),
              backgroundColor: Colors.green,
            ),
            const SizedBox(height: 10),
          ],
          FloatingActionButton(
            heroTag: 'route',
            onPressed: _getRoute,
            child: const Icon(Icons.directions),
          ),
        ],
      ),
    );
  }
}

// --- Page 3: Geofence ---

class GeofencePage extends StatelessWidget {
  const GeofencePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Geofencing')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            SmartLocation.addGeofence(
              GeofenceRegion(
                id: 'home',
                latitude: 37.422,
                longitude: -122.084,
                radiusMeters: 200,
                onEnter: (_) => print('Entered Home!'),
                onExit: (_) => print('Left Home!'),
              ),
            );
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(content: Text('Geofence added at Googleplex')),
            );
          },
          child: const Text('Add Geofence (Googleplex)'),
        ),
      ),
    );
  }
}
0
likes
140
points
34
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A robust Flutter package for live location tracking with background support, geofencing, routing, and Firebase synchronization.

Repository (GitHub)

License

MIT (license)

Dependencies

dio, equatable, flutter, flutter_background_service, flutter_local_notifications, geolocator, google_maps_flutter, google_polyline_algorithm, permission_handler, rxdart, shared_preferences

More

Packages that depend on flutter_location_services