pinpoint_sdk 12.2.0+21 copy "pinpoint_sdk: ^12.2.0+21" to clipboard
pinpoint_sdk: ^12.2.0+21 copied to clipboard

The Pinpoint SDK is a cross-platform (Android/iOS) Flutter plugin for positioning with Pinpoint's technology.

example/lib/main.dart

import 'dart:async';
import 'package:example/widgets.dart';
import 'package:flutter/material.dart';
import 'package:pinpoint_sdk/pinpoint_sdk.dart';

void main() {
  // initialize Geolocator
  // Note: the API key will become mandatory in a future release, at the moment it is still optional.
  initGeolocator(apiKey: 'myApiKey');
  runApp(MaterialApp(home: Example()));
}

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

  @override
  State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  /// Position stream that tracks the current location updates.
  Stream<Position>? _positioningStream;

  /// [Wgs84Reference] for the indoor position.
  /// This includes the latitude, longitude and azimuth.
  Wgs84Reference? _wgs84Reference;

  /// Determines if the [_positioningStream] is null.
  bool get _isPositioning => _positioningStream != null;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset('assets/Pin-Round-Orange@128px.png', height: 32),
            const SizedBox(width: 10),
            const Text("Pinpoint Flutter SDK Demo"),
          ],
        ),
      ),
      backgroundColor: const Color(0xFFF7F7F7),
      body: SafeArea(
        child: SingleChildScrollView(
          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
          child: StreamBuilder(
            stream: _positioningStream,
            builder: (context, snapshot) {
              bool hasPosition = snapshot.hasData;
              bool isIndoorPosition = snapshot.data is IndoorPosition;

              // Received position when the position stream is running. Can be a outdoor or indoor position.
              Position? position = snapshot.data;

              return Column(
                spacing: 15,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Row(
                        spacing: 10,
                        children: [
                          const Text(
                            "WGS84 Coordinates",
                            style: TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                          if (_isPositioning)
                            Container(
                              width: 10,
                              height: 10,
                              decoration: BoxDecoration(
                                color:
                                    isIndoorPosition
                                        ? Colors.green
                                        : Colors.red,
                                shape: BoxShape.circle,
                              ),
                            ),
                        ],
                      ),
                      if (_isPositioning && !hasPosition)
                        const CircularProgressIndicator(
                          color: Color.fromRGBO(255, 153, 26, 1),
                        ),
                      IconButton(
                        onPressed: () => _setWGS84Ref(),
                        icon: Icon(Icons.settings),
                      ),
                    ],
                  ),
                  if (_isPositioning)
                    Text(
                      isIndoorPosition ? "indoor position" : "outdoor position",
                      style: TextStyle(color: Colors.grey, fontSize: 16),
                    ),

                  ValueBox(
                    label: "Latitude",
                    value:
                        _isPositioning && hasPosition
                            ? position!.latitude.toString()
                            : "",
                    color: Colors.red.shade300,
                  ),
                  ValueBox(
                    label: "Longitude",
                    value:
                        _isPositioning && hasPosition
                            ? position!.longitude.toString()
                            : "",
                    color: Colors.green.shade300,
                  ),
                  ValueBox(
                    label: "Accuracy",
                    value:
                        _isPositioning && hasPosition
                            ? "${position!.accuracy.toStringAsFixed(2)} m"
                            : "",
                    color: Colors.blue.shade300,
                  ),

                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton(
                      onPressed:
                          _isPositioning ? _stopPositioning : _startPositioning,
                      style: ElevatedButton.styleFrom(
                        backgroundColor:
                            _isPositioning ? Colors.red : Colors.green,
                        padding: const EdgeInsets.symmetric(vertical: 14),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(12),
                        ),
                      ),
                      child: Text(
                        _isPositioning
                            ? "Stop Positioning"
                            : "Start Positioning",
                        style: const TextStyle(
                          color: Colors.white,
                          fontSize: 18,
                        ),
                      ),
                    ),
                  ),

                  Text(
                    "For indoor positioning please hold your TRACElet close to the device.",
                  ),
                ],
              );
            },
          ),
        ),
      ),
    );
  }

  ///Requests Permission and checks if the permission was granted.
  Future<bool> _checkPermissions() async {
    var permission = await Geolocator.checkPermission();

    // If permissions are deniedForever, permission dialog will not be shown until
    // the user updates the permission in the App settings
    if (permission == LocationPermission.deniedForever) {
      await Geolocator.openAppSettings();
    }

    if (permission != LocationPermission.always &&
        permission != LocationPermission.whileInUse) {
      permission = await Geolocator.requestPermission();
    }

    if (permission != LocationPermission.always &&
        permission != LocationPermission.whileInUse) {
      return false;
    }
    return true;
  }

  /// Cancels the positioning stream.
  void _stopPositioning() async {
    setState(() {
      _positioningStream = null;
    });
  }

  /// Starts the positioning stream with a distance filter of 2 m,
  /// if the [_refLatitude], [_refLongitude], [_refAzimuth] are set and [_checkPermissions] is true.
  Future<void> _startPositioning() async {
    if (_wgs84Reference == null) {
      _setWGS84Ref();
      return;
    }

    if (!await _checkPermissions()) return;

    setState(() {
      _positioningStream = Geolocator.getPositionStream(
        locationSettings: const LocationSettings(
          distanceFilter: 2,
          timeLimit: Duration(minutes: 1),
        ),
      );
    });
  }

  /// Opens the [WGS84ReferenceDialog] and updates the Georeference for indoor positioning, if the result != null.
  Future<void> _setWGS84Ref() async {
    final result = await showDialog(
      context: context,
      builder: (context) {
        return WGS84ReferenceDialog(wgs84Result: _wgs84Reference);
      },
    );

    if (result != null) {
      setState(() {
        _wgs84Reference = result;
      });
      // Needs to be set for indoor positioning
      Geolocator.updateGeoreference(
        latitude: _wgs84Reference!.latitude,
        longitude: _wgs84Reference!.longitude,
        azimuth: _wgs84Reference!.azimuth,
      );
    }
  }
}

/// Wgs84Reference with [latitude], [longitude] and [azimuth].
class Wgs84Reference {
  double latitude;
  double longitude;
  double azimuth;

  Wgs84Reference({
    required this.latitude,
    required this.longitude,
    required this.azimuth,
  });
}
2
likes
130
points
38
downloads

Documentation

API reference

Publisher

verified publisherpinpoint.de

Weekly Downloads

The Pinpoint SDK is a cross-platform (Android/iOS) Flutter plugin for positioning with Pinpoint's technology.

Homepage

License

unknown (license)

Dependencies

async, collection, flutter, flutter_blue_plus, flutter_blue_plus_windows, geolocator, logging, maps_toolkit, meta, path_provider, permission_handler, turf, vector_math

More

Packages that depend on pinpoint_sdk

Packages that implement pinpoint_sdk