Skip to content

Using flutter_compass to Integrate a Compass in Your Flutter App

  • by

Introduction

The flutter_compass package provides an easy way to integrate a compass into your Flutter application. The compass heading ranges from 0 to 360 degrees, with 0 being north. This package supports both Android and iOS platforms, though there are specific considerations for each.

Installation

Step 1: Adding the Dependency

First, add flutter_compass to your project’s pubspec.yaml file:

dependencies:
  flutter_compass: ^0.8.0

Alternatively, you can run the following command in your terminal:

flutter pub add flutter_compass

Step 2: Importing the Package

After adding the dependency, import it into your Dart code:

import 'package:flutter_compass/flutter_compass.dart';

Platform-Specific Configurations

iOS Configuration

For iOS, you need to update your Info.plist file to include location usage descriptions. Add the following keys with appropriate descriptions:

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to show the compass heading.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need your location to show the compass heading.</string>

Android Configuration

For Android, ensure that you have the necessary permissions in your AndroidManifest.xml file:

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

Example Code

Below is a simple example demonstrating how to use the flutter_compass package to display a compass in your Flutter app.

Main Dart File

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Compass Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CompassScreen(),
    );
  }
}

class CompassScreen extends StatefulWidget {
  @override
  _CompassScreenState createState() => _CompassScreenState();
}

class _CompassScreenState extends State<CompassScreen> {
  double? _heading;

  @override
  void initState() {
    super.initState();
    FlutterCompass.events?.listen((event) {
      setState(() {
        _heading = event.heading;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Compass Demo'),
      ),
      body: Center(
        child: _heading == null
            ? CircularProgressIndicator()
            : Transform.rotate(
                angle: ((_heading ?? 0) * (3.141592653589793 / 180) * -1),
                child: Image.asset('assets/compass.png'),
              ),
      ),
    );
  }
}

Adding a Compass Image

To make the compass more visually appealing, you can add a compass image. Save a suitable compass image in your project’s assets directory and reference it in the code.

Updating pubspec.yaml for Assets

Ensure you declare the assets in your pubspec.yaml file:

flutter:
  assets:
    - assets/compass.png

Handling Permissions

It’s recommended to use the permission_handler package to manage permissions more effectively. Here is how you can do it:

Adding permission_handler Dependency

Add the permission_handler package to your pubspec.yaml:

dependencies:
  permission_handler: ^10.0.0

Requesting Permissions in Code

import 'package:permission_handler/permission_handler.dart';

class CompassScreen extends StatefulWidget {
  @override
  _CompassScreenState createState() => _CompassScreenState();
}

class _CompassScreenState extends State<CompassScreen> {
  double? _heading;

  @override
  void initState() {
    super.initState();
    _requestPermissions();
    FlutterCompass.events?.listen((event) {
      setState(() {
        _heading = event.heading;
      });
    });
  }

  Future<void> _requestPermissions() async {
    if (await Permission.locationWhenInUse.request().isGranted) {
      // Permissions granted
    } else {
      // Permissions denied
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Compass Demo'),
      ),
      body: Center(
        child: _heading == null
            ? CircularProgressIndicator()
            : Transform.rotate(
                angle: ((_heading ?? 0) * (3.141592653589793 / 180) * -1),
                child: Image.asset('assets/compass.png'),
              ),
      ),
    );
  }
}

Conclusion

By following the steps outlined above, you can successfully integrate a compass into your Flutter application using the flutter_compass package. Ensure you handle platform-specific permissions and configurations correctly to provide a seamless user experience. This setup not only enhances your app’s functionality but also offers a practical use case for location-based services.

Creating a mini-project with the flutter_compass package can be a great way to solidify your understanding and demonstrate the capabilities of a Flutter application with compass functionality. Let’s expand the project idea to create a comprehensive mini-project that includes additional features like location tracking and a user interface with a compass and map integration.

Project Overview

The mini-project will be a Flutter app named Compass Navigator. It will have the following features:

  1. Compass Integration: Display a real-time compass.
  2. Location Tracking: Display the user’s current location.
  3. Map Integration: Show the user’s location on a map.
  4. User Interface: A well-designed UI with a compass image and map.

Step-by-Step Implementation

1. Project Setup

First, create a new Flutter project:

flutter create compass_navigator
cd compass_navigator

Update your pubspec.yaml to include the necessary dependencies:

dependencies:
  flutter:
    sdk: flutter
  flutter_compass: ^0.8.0
  permission_handler: ^10.0.0
  geolocator: ^9.0.2
  google_maps_flutter: ^2.0.6

2. Adding Necessary Permissions

iOS Configuration

Update the ios/Runner/Info.plist file with the following keys:

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to show the compass heading and map.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need your location to show the compass heading and map.</string>
Android Configuration

Update the android/app/src/main/AndroidManifest.xml file with the following permissions:

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

3. Main Dart Code

Create a main.dart file and implement the following code:

import 'package:flutter/material.dart';
import 'package:flutter_compass/flutter_compass.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Compass Navigator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CompassNavigator(),
    );
  }
}

class CompassNavigator extends StatefulWidget {
  @override
  _CompassNavigatorState createState() => _CompassNavigatorState();
}

class _CompassNavigatorState extends State<CompassNavigator> {
  double? _heading;
  Position? _currentPosition;
  GoogleMapController? _mapController;

  @override
  void initState() {
    super.initState();
    _requestPermissions();
    _initializeCompass();
    _initializeLocation();
  }

  Future<void> _requestPermissions() async {
    await Permission.locationWhenInUse.request();
    await Permission.locationAlways.request();
  }

  void _initializeCompass() {
    FlutterCompass.events?.listen((event) {
      setState(() {
        _heading = event.heading;
      });
    });
  }

  void _initializeLocation() {
    Geolocator.getPositionStream().listen((Position position) {
      setState(() {
        _currentPosition = position;
        _mapController?.animateCamera(
          CameraUpdate.newLatLng(
            LatLng(position.latitude, position.longitude),
          ),
        );
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Compass Navigator'),
      ),
      body: Column(
        children: <Widget>[
          _buildCompass(),
          _buildMap(),
        ],
      ),
    );
  }

  Widget _buildCompass() {
    return Expanded(
      child: Center(
        child: _heading == null
            ? CircularProgressIndicator()
            : Transform.rotate(
                angle: ((_heading ?? 0) * (3.141592653589793 / 180) * -1),
                child: Image.asset('assets/compass.png'),
              ),
      ),
    );
  }

  Widget _buildMap() {
    return Expanded(
      child: _currentPosition == null
          ? Center(child: CircularProgressIndicator())
          : GoogleMap(
              onMapCreated: (controller) {
                _mapController = controller;
              },
              initialCameraPosition: CameraPosition(
                target: LatLng(
                  _currentPosition!.latitude,
                  _currentPosition!.longitude,
                ),
                zoom: 15,
              ),
              myLocationEnabled: true,
              myLocationButtonEnabled: true,
            ),
    );
  }
}

4. Adding Assets

Add a compass image to your project under the assets directory.

Update the pubspec.yaml to include the assets:

flutter:
  assets:
    - assets/compass.png

5. Running the Application

Make sure you have set up your development environment for both Android and iOS, and then run the application:

flutter run

Conclusion

This mini-project integrates various Flutter plugins to create a functional and interactive application. By following the steps above, you can:

  • Display a real-time compass heading using the flutter_compass package.
  • Track the user’s current location using the geolocator package.
  • Show the user’s location on a map using the google_maps_flutter package.

This project provides a strong foundation for building more complex location-based applications and serves as a practical example of integrating multiple Flutter plugins into a cohesive application.

Leave a Reply

Your email address will not be published. Required fields are marked *