Skip to content

Both copy text to your clipboard — Build with AI copies a setup prompt to paste into Claude Code, Cursor, Codex or Copilot; Copy page as Markdown copies this page to paste into a chat. How it works

Flutter — Location & Permissions

Showing the user's own position on the map takes two objects working together: PermissionManager (requests/checks OS location permission) and the location methods on MapController (actually show/track the puck). Neither works alone — enableLocation() will fail if permission hasn't been granted, and granting permission does nothing to the map by itself.

PermissionManager cannot be used on web.

PermissionManager

dart
abstract interface class PermissionManager {
  factory PermissionManager();

  bool get backgroundLocationPermissionGranted;
  bool get locationPermissionsGranted;
  bool get runtimePermissionsRequired;

  Future<bool> requestLocationPermissions({required String explanation});
}
MemberDescription
locationPermissionsGrantedtrue if either coarse or fine location access is currently granted.
backgroundLocationPermissionGrantedtrue if background location access is granted.
runtimePermissionsRequiredtrue if the OS requires asking for location permission at runtime (i.e. Android 6+/iOS, as opposed to permissions declared only at install time).
requestLocationPermissions({required String explanation})Triggers the OS permission prompt (using explanation where the platform surfaces a rationale string) and resolves to whether it was granted.

Construct it with the plain factory constructor — no arguments:

dart
final permissionManager = PermissionManager();

Platform permission declarations

Android

xml
<!-- android/app/src/main/AndroidManifest.xml -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

iOS

xml
<!-- ios/Runner/Info.plist -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs your location to display your location on the map.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app requires access to your location.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app requires access to your location.</string>

Without these declarations the runtime permission prompt will not appear (Android) or the app will crash when requesting location (iOS).

Wiring it together

dart
import 'package:flutter/material.dart';
import 'package:mapmetrics/mapmetrics.dart';

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

  @override
  State<UserLocationPage> createState() => _UserLocationPageState();
}

class _UserLocationPageState extends State<UserLocationPage> {
  final _permissionManager = PermissionManager();
  MapController? _controller;

  Future<void> _showMyLocation() async {
    final granted = await _permissionManager.requestLocationPermissions(
      explanation: 'Show your location on the map.',
    );
    if (!granted || _controller == null) return;

    await _controller!.enableLocation();
    await _controller!.trackLocation(trackBearing: BearingTrackMode.gps);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('User Location')),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(8),
            child: OutlinedButton(
              onPressed: _showMyLocation,
              child: const Text('Show my location'),
            ),
          ),
          Expanded(
            child: MapMetricsView(
              options: MapOptions(
                initCenter: Position(-74.006, 40.7128), // New York: lng, lat
                initZoom: 9,
              ),
              onMapCreated: (controller) => _controller = controller,
            ),
          ),
        ],
      ),
    );
  }
}

Checking permission state without prompting

Read the getters directly to reflect current state in your UI (e.g. to decide whether to show a "request permission" button at all):

dart
final manager = PermissionManager();

if (!manager.locationPermissionsGranted) {
  // show a prompt / explainer before calling requestLocationPermissions
}

Once permission is granted, these live on MapController (full reference: MapController — User location):

  • enableLocation({...}) — start showing the location puck
  • trackLocation({trackLocation, trackBearing}) — re-center the camera on the user as it moves
  • showUserLocationPuck({show}) — toggle puck visibility
  • setLocationDraggable({draggable}) — allow the user to drag the puck to a new position
  • setNavigationRoute(List<Position>) / clearNavigationRoute() — snap the puck to a route line while navigating

See also