Flutter指南针功能插件flutter_nhan_compass的使用

Flutter指南针功能插件flutter_nhan_compass的使用


flutter_nhan_compass

Hi my name is NhanTran. 一个用于Flutter应用的指南针插件。指南针的方向值在0到360度之间,0度表示北方。

注意:

  • Android Only: 当没有可用传感器时,null将作为方向返回。

使用方法

要使用此插件,在项目的pubspec.yaml文件中添加flutter_nhan_compass依赖。例如:

dependencies:
  flutter_nhan_compass: ^0.0.2

iOS配置

确保在Info.plist文件中添加以下键,并附上适当的描述:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysAndWhenInUseUsageDescription

参考示例代码:

<key>NSLocationWhenInUseUsageDescription</key>
<string>我们需要您的位置信息来提供指南针功能。</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>我们需要您的位置信息来提供指南针功能。</string>

Android配置

确保在AndroidManifest.xml文件中添加以下权限:

  • android.permission.INTERNET
  • android.permission.ACCESS_COARSE_LOCATION
  • android.permission.ACCESS_FINE_LOCATION

参考示例代码:

<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"/>

推荐支持插件

推荐使用Flutter Permission handler Plugin插件,它可以帮助你在跨平台(iOS, Android)环境中轻松请求和检查权限。

参考示例代码:

dependencies:
  permission_handler: ^8.1.4

完整示例代码

import 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:flutter_nhan_compass/flutter_nhan_compass.dart';
import 'package:permission_handler/permission_handler.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _hasPermissions = false;
  CompassEvent? _lastRead;
  DateTime? _lastReadAt;

  [@override](/user/override)
  void initState() {
    super.initState();

    _fetchPermissionStatus();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          title: const Text('Flutter 指南针'),
        ),
        body: Builder(builder: (context) {
          if (_hasPermissions) {
            return Column(
              children: <Widget>[
                _buildManualReader(),
                Expanded(child: _buildCompass()),
              ],
            );
          } else {
            return _buildPermissionSheet();
          }
        }),
      ),
    );
  }

  Widget _buildManualReader() {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Row(
        children: <Widget>[
          ElevatedButton(
            child: Text('读取值'),
            onPressed: () async {
              final CompassEvent tmp = await FlutterCompass.events!.first;
              setState(() {
                _lastRead = tmp;
                _lastReadAt = DateTime.now();
              });
            },
          ),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    '$_lastRead',
                    style: Theme.of(context).textTheme.caption,
                  ),
                  Text(
                    '$_lastReadAt',
                    style: Theme.of(context).textTheme.caption,
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildCompass() {
    return StreamBuilder<CompassEvent>(
      stream: FlutterCompass.events,
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return Text('读取方向错误: ${snapshot.error}');
        }

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

        double? direction = snapshot.data!.heading;

        // 如果方向为null,则设备不支持该传感器
        // 显示错误消息
        if (direction == null)
          return Center(
            child: Text("设备不支持传感器!"),
          );

        return Material(
          shape: CircleBorder(),
          clipBehavior: Clip.antiAlias,
          elevation: 4.0,
          child: Container(
            padding: EdgeInsets.all(16.0),
            alignment: Alignment.center,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
            ),
            child: Transform.rotate(
              angle: (direction * (math.pi / 180) * -1),
              child: Image.asset('assets/compass.jpg'),
            ),
          ),
        );
      },
    );
  }

  Widget _buildPermissionSheet() {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text('需要位置权限'),
          ElevatedButton(
            child: Text('请求权限'),
            onPressed: () {
              Permission.locationWhenInUse.request().then((ignored) {
                _fetchPermissionStatus();
              });
            },
          ),
          SizedBox(height: 16),
          ElevatedButton(
            child: Text('打开应用设置'),
            onPressed: () {
              openAppSettings().then((opened) {
                //
              });
            },
          )
        ],
      ),
    );
  }

  void _fetchPermissionStatus() {
    Permission.locationWhenInUse.status.then((status) {
      if (mounted) {
        setState(() => _hasPermissions = status == PermissionStatus.granted);
      }
    });
  }
}

更多关于Flutter指南针功能插件flutter_nhan_compass的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter指南针功能插件flutter_nhan_compass的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_nhan_compass 是一个Flutter插件,用于在Flutter应用中实现指南针功能,显示设备当前的朝向。通过这个插件,开发者可以轻松获取设备的方位信息,并将其展示在UI中。

安装

pubspec.yaml 文件中添加 flutter_nhan_compass 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_nhan_compass: ^1.0.0  # 请查看最新版本

然后运行 flutter pub get 来安装依赖。

使用方法

  1. 导入包

在需要使用指南针功能的地方导入 flutter_nhan_compass 包:

import 'package:flutter_nhan_compass/flutter_nhan_compass.dart';
  1. 初始化插件

在使用指南针功能之前,需要初始化插件。通常可以在 initState 方法中进行初始化:

Compass compass = Compass();
  1. 获取方位信息

使用 compass.events 来监听设备的方位变化。compass.events 是一个 Stream,它会在设备的方位发生变化时发出事件。

class CompassExample extends StatefulWidget {
  @override
  _CompassExampleState createState() => _CompassExampleState();
}

class _CompassExampleState extends State<CompassExample> {
  double _heading = 0.0;

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

  void _startCompass() {
    Compass().events.listen((CompassEvent event) {
      setState(() {
        _heading = event.heading;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Compass Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Heading: $_heading',
              style: TextStyle(fontSize: 24),
            ),
            Transform.rotate(
              angle: -_heading * (3.1415926535897932 / 180),
              child: Icon(
                Icons.arrow_upward,
                size: 100,
                color: Colors.blue,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在上面的代码中,_heading 表示设备当前的朝向角度,Transform.rotate 用于根据 _heading 旋转一个箭头图标来表示当前的朝向。

  1. 停止监听

如果你不再需要监听方位信息,可以停止监听:

Compass().stop();

注意事项

  • 权限:在某些设备上,可能需要请求位置权限才能正确获取方位信息。你可以在 AndroidManifest.xml (Android) 或 Info.plist (iOS) 中添加相应的权限声明。

    • Android:

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

      <key>NSLocationWhenInUseUsageDescription</key>
      <string>We need access to your location to provide compass functionality.</string>
回到顶部