flutter_map_background_location 1.0.0 copy "flutter_map_background_location: ^1.0.0" to clipboard
flutter_map_background_location: ^1.0.0 copied to clipboard

A Flutter plugin for tracking location in both foreground and background modes, similar to flutter_background_geolocation.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_map_background_location/background_location_tracker_library.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Background Location Tracker Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const LocationTrackerDemo(),
    );
  }
}

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

  @override
  State<LocationTrackerDemo> createState() => _LocationTrackerDemoState();
}

class _LocationTrackerDemoState extends State<LocationTrackerDemo> {
  final BackgroundLocationTracker _locationTracker =
      BackgroundLocationTracker();

  LocationData? _currentLocation;
  LocationPermissionStatus _permissionStatus =
      LocationPermissionStatus.notDetermined;
  bool _isServiceEnabled = false;
  bool _isTracking = false;
  final List<String> _locationHistory = [];
  final List<String> _errors = [];

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

  Future<void> _initializeLocationTracking() async {
    // Check service status
    final serviceEnabled = await _locationTracker.isLocationServiceEnabled();
    setState(() {
      _isServiceEnabled = serviceEnabled;
    });

    // Check permission
    final permission = await _locationTracker.checkPermission();
    setState(() {
      _permissionStatus = permission;
    });

    // Listen to location updates
    _locationTracker.onLocationUpdate.listen((location) {
      setState(() {
        _currentLocation = location;
        _locationHistory.insert(
          0,
          '${location.timestamp.toLocal()}: ${location.latitude.toStringAsFixed(6)}, ${location.longitude.toStringAsFixed(6)}',
        );
        if (_locationHistory.length > 20) {
          _locationHistory.removeLast();
        }
      });
    });

    // Listen to errors
    _locationTracker.onError.listen((error) {
      setState(() {
        _errors.insert(0, '${DateTime.now().toLocal()}: $error');
        if (_errors.length > 10) {
          _errors.removeLast();
        }
      });
    });
  }

  Future<void> _requestPermission() async {
    final permission = await _locationTracker.requestPermission();
    setState(() {
      _permissionStatus = permission;
    });
  }

  Future<void> _requestBackgroundPermission() async {
    final permission = await _locationTracker.requestPermission(
      requestBackgroundPermission: true,
    );
    setState(() {
      _permissionStatus = permission;
    });
  }

  Future<void> _getCurrentLocation() async {
    final location = await _locationTracker.getCurrentLocation();
    if (location != null) {
      setState(() {
        _currentLocation = location;
      });
    }
  }

  Future<void> _startTracking({bool background = false}) async {
    final settings = LocationSettings(
      accuracy: LocationAccuracy.high,
      distanceFilter: 10.0,
      timeInterval: 5000,
      enableBackgroundTracking: background,
      showBackgroundNotification: background,
      notificationTitle: 'Location Tracking Demo',
      notificationText: 'Məkanınız izlənilir',
      allowMockLocations: false,
    );

    final success = await _locationTracker.startTracking(settings);
    setState(() {
      _isTracking = success;
    });
  }

  Future<void> _stopTracking() async {
    await _locationTracker.stopTracking();
    setState(() {
      _isTracking = false;
    });
  }

  @override
  void dispose() {
    _locationTracker.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Background Location Tracker'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // Status Card
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Status',
                      style: Theme.of(context).textTheme.titleLarge,
                    ),
                    const SizedBox(height: 8),
                    _buildStatusRow(
                      'Location Service',
                      _isServiceEnabled ? 'Enabled' : 'Disabled',
                      _isServiceEnabled ? Colors.green : Colors.red,
                    ),
                    _buildStatusRow(
                      'Permission',
                      _permissionStatus.name,
                      _permissionStatus.isGranted ? Colors.green : Colors.red,
                    ),
                    _buildStatusRow(
                      'Tracking',
                      _isTracking ? 'Active' : 'Inactive',
                      _isTracking ? Colors.green : Colors.grey,
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // Current Location Card
            if (_currentLocation != null)
              Card(
                child: Padding(
                  padding: const EdgeInsets.all(16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        'Current Location',
                        style: Theme.of(context).textTheme.titleLarge,
                      ),
                      const SizedBox(height: 8),
                      _buildInfoRow('Latitude',
                          _currentLocation!.latitude.toStringAsFixed(6)),
                      _buildInfoRow('Longitude',
                          _currentLocation!.longitude.toStringAsFixed(6)),
                      _buildInfoRow('Accuracy',
                          '${_currentLocation!.accuracy.toStringAsFixed(2)}m'),
                      if (_currentLocation!.altitude != null)
                        _buildInfoRow('Altitude',
                            '${_currentLocation!.altitude!.toStringAsFixed(2)}m'),
                      if (_currentLocation!.speed != null)
                        _buildInfoRow('Speed',
                            '${_currentLocation!.speed!.toStringAsFixed(2)}m/s'),
                      if (_currentLocation!.heading != null)
                        _buildInfoRow('Heading',
                            '${_currentLocation!.heading!.toStringAsFixed(2)}°'),
                      _buildInfoRow('Timestamp',
                          _currentLocation!.timestamp.toLocal().toString()),
                      _buildInfoRow('Mock Location',
                          _currentLocation!.isMocked ? 'Yes' : 'No'),
                    ],
                  ),
                ),
              ),
            const SizedBox(height: 16),

            // Permission Buttons
            Text(
              'Permissions',
              style: Theme.of(context).textTheme.titleMedium,
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _requestPermission,
              icon: const Icon(Icons.location_on),
              label: const Text('Request Foreground Permission'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _requestBackgroundPermission,
              icon: const Icon(Icons.location_searching),
              label: const Text('Request Background Permission'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: () => _locationTracker.openAppSettings(),
              icon: const Icon(Icons.settings),
              label: const Text('Open App Settings'),
            ),
            const SizedBox(height: 16),

            // Tracking Buttons
            Text(
              'Tracking',
              style: Theme.of(context).textTheme.titleMedium,
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _getCurrentLocation,
              icon: const Icon(Icons.my_location),
              label: const Text('Get Current Location'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _isTracking ? null : () => _startTracking(),
              icon: const Icon(Icons.play_arrow),
              label: const Text('Start Foreground Tracking'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _isTracking
                  ? null
                  : () => _startTracking(background: true),
              icon: const Icon(Icons.play_circle_filled),
              label: const Text('Start Background Tracking'),
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _isTracking ? _stopTracking : null,
              icon: const Icon(Icons.stop),
              label: const Text('Stop Tracking'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.red,
                foregroundColor: Colors.white,
              ),
            ),
            const SizedBox(height: 16),

            // Location History
            if (_locationHistory.isNotEmpty) ...[
              Text(
                'Location History',
                style: Theme.of(context).textTheme.titleMedium,
              ),
              const SizedBox(height: 8),
              Card(
                child: Container(
                  constraints: const BoxConstraints(maxHeight: 200),
                  child: ListView.builder(
                    shrinkWrap: true,
                    itemCount: _locationHistory.length,
                    itemBuilder: (context, index) {
                      return ListTile(
                        dense: true,
                        leading: const Icon(Icons.location_pin, size: 16),
                        title: Text(
                          _locationHistory[index],
                          style: const TextStyle(fontSize: 12),
                        ),
                      );
                    },
                  ),
                ),
              ),
            ],
            const SizedBox(height: 16),

            // Errors
            if (_errors.isNotEmpty) ...[
              Text(
                'Errors',
                style: Theme.of(context).textTheme.titleMedium,
              ),
              const SizedBox(height: 8),
              Card(
                color: Colors.red.shade50,
                child: Container(
                  constraints: const BoxConstraints(maxHeight: 150),
                  child: ListView.builder(
                    shrinkWrap: true,
                    itemCount: _errors.length,
                    itemBuilder: (context, index) {
                      return ListTile(
                        dense: true,
                        leading: const Icon(Icons.error, size: 16, color: Colors.red),
                        title: Text(
                          _errors[index],
                          style: const TextStyle(fontSize: 12, color: Colors.red),
                        ),
                      );
                    },
                  ),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }

  Widget _buildStatusRow(String label, String value, Color color) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(label),
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
            decoration: BoxDecoration(
              color: color.withValues(alpha: 0.2),
              borderRadius: BorderRadius.circular(12),
            ),
            child: Text(
              value,
              style: TextStyle(
                color: color,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildInfoRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(label, style: const TextStyle(fontWeight: FontWeight.w500)),
          Text(value),
        ],
      ),
    );
  }
}
1
likes
0
points
--
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for tracking location in both foreground and background modes, similar to flutter_background_geolocation.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, geolocator, permission_handler, plugin_platform_interface

More

Packages that depend on flutter_map_background_location

Packages that implement flutter_map_background_location