Skip to main content

flutter_device_compass 2.1.0 copy "flutter_device_compass: ^2.1.0" to clipboard
flutter_device_compass: ^2.1.0 copied to clipboard

A Flutter compass plugin using device sensors. Heading is 0-360 degrees (0 = north).

flutter_device_compass #

pub package Platform License

A Flutter compass plugin using device sensors. Provides real-time device heading, orientation-compensated azimuth (0°–360°, where 0° is North), camera-mode heading for AR/camera overlays, and sensor accuracy.

Community-maintained fork of medyas/flutter_compass_v2 (lineage from hemanthrajv/flutter_compass), republished as flutter_device_compass on pub.dev for ongoing maintenance and modern Flutter (3.24+ / 3.44+) & Gradle/Kotlin compatibility.


Features #

  • 🧭 Heading Calculation: 0° to 360°, where 0° is North.
  • 📱 Orientation-Aware: Automatically compensates for device orientation changes (Portrait, Landscape Left, Landscape Right, Portrait Upside Down).
  • 📷 Camera Mode Heading: Heading out the back of the device (headingForCameraMode), ideal for Augmented Reality (AR) or camera overlays.
  • 🎯 Sensor Accuracy: Exposes calibration and accuracy deviation in degrees (accuracy).
  • 🔍 Hardware Detection: Proactively check sensor availability via FlutterCompass.hasSensors before mounting compass views.
  • ⚡ Robust Sensor Fallbacks: Uses Sensor.TYPE_ROTATION_VECTOR on Android when available with low-pass filtered accelerometer + magnetometer fallback.
  • 🛡️ Crash-Resistant: Guarded against non-finite / NaN sensor readings and negative true headings.

Getting Started #

Add flutter_device_compass to your pubspec.yaml:

dependencies:
  flutter_device_compass: ^2.1.0

Platform Setup #

iOS #

iOS requires location permissions to deliver compass/heading updates via CoreLocation.

Add the following keys to your ios/Runner/Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to heading and compass data to orient the map.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to heading and compass data to orient the map.</string>

Note: Use a permission package like permission_handler to request location permissions at runtime before listening to compass events on iOS.

Android #

No additional permissions are strictly required for sensor access. However, if your app utilizes fine location for geomagnetic declination or maps alongside the compass, add the following to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Usage Examples #

1. Basic Stream Subscription #

import 'package:flutter_device_compass/flutter_device_compass.dart';

// Subscribe to compass updates
final subscription = FlutterCompass.events?.listen((CompassEvent event) {
  print('Heading: ${event.heading}°');
  print('Camera Mode Heading: ${event.headingForCameraMode}°');
  print('Accuracy Deviation: ±${event.accuracy}°');
});

// Cancel when no longer needed
// subscription?.cancel();

2. Building a Rotating Compass UI (StreamBuilder) #

import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_device_compass/flutter_device_compass.dart';

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

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<CompassEvent>(
      stream: FlutterCompass.events,
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return Center(child: Text('Error: ${snapshot.error}'));
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }

        final heading = snapshot.data?.heading;

        // On devices without compass sensors, heading will be null
        if (heading == null) {
          return const Center(
            child: Text('Device does not have compass sensors'),
          );
        }

        return Center(
          child: Transform.rotate(
            angle: (heading * (math.pi / 180) * -1),
            child: Image.asset(
              'assets/compass.png',
              width: 250,
              height: 250,
            ),
          ),
        );
      },
    );
  }
}

3. Check Sensor Availability #

Before initiating compass-dependent features, you can verify if the device hardware supports compass sensors:

final bool? isSupported = await FlutterCompass.hasSensors;

if (isSupported == true) {
  print('Compass sensor is available on this device');
} else {
  print('Device does not support compass/heading sensors');
}

4. Read Current Heading Once #

If you only need a single heading snapshot (e.g. when capturing a photo or logging location):

Future<void> logCurrentHeading() async {
  final CompassEvent event = await FlutterCompass.events!.first;
  print('Current heading is: ${event.heading}°');
}

CompassEvent Reference #

Property Type Description
heading double? The device heading in degrees around its Z-axis (pointing direction of the top of the phone). Range: 0.0 to 360.0, where 0.0 is North. null if sensor is unavailable.
headingForCameraMode double? The heading in degrees around the device's X-axis (pointing out the back of the phone). Ideal for camera and AR alignment.
accuracy double? Estimated deviation error in degrees (±). null if uncalibrated or unavailable.

Maintainer #

Maintained with ❤️ by Nafis Kabbo.

Contributions, issues, and feature requests are welcome on GitHub!

6
likes
0
points
7.76k
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter compass plugin using device sensors. Heading is 0-360 degrees (0 = north).

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on flutter_device_compass

Packages that implement flutter_device_compass