Flutter地理位置获取插件geolocator_tizen的使用

Flutter地理位置获取插件geolocator_tizen的使用

geolocator_tizen

pub package

geolocator_tizen 是对 geolocator 插件在 Tizen 平台上的实现。


使用

此插件并非 geolocator 的官方推荐实现。因此,您需要在项目的 pubspec.yaml 文件中同时包含 geolocatorgeolocator_tizen 作为依赖项。

dependencies:
  geolocator: ^8.0.0
  geolocator_tizen: ^1.0.6

然后在 Dart 代码中导入 geolocator

import 'package:geolocator/geolocator.dart';

有关详细用法,请参阅 geolocator 文档


必需的权限

要使用此插件,您需要在应用的 tizen-manifest.xml 文件中声明以下权限:

<privileges>
  <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
  <privilege>http://tizen.org/privilege/location</privilege>
  <privilege>http://tizen.org/privilege/location.coarse</privilege>
</privileges>

支持的设备

  • Galaxy Watch 系列(运行 Tizen 4.0 或更高版本)

支持的 API

API 状态
Geolocator.isLocationServiceEnabled ✅ 支持
Geolocator.getServiceStatusStream ✅ 支持
Geolocator.checkPermission ✅ 支持
Geolocator.requestPermission ✅ 支持
Geolocator.getLastKnownPosition ✅ 支持
Geolocator.getCurrentPosition (支持参数: timeLimit) ✅ 支持
Geolocator.getPositionStream (支持参数: locationSettings.timeLimit) ✅ 支持
Geolocator.getLocationAccuracy ❌ 不支持
Geolocator.requestTemporaryFullAccuracy (仅限 iOS) ❌ 不支持
Geolocator.openAppSettings (不支持模拟器) ✅ 支持
Geolocator.openLocationSettings (不支持模拟器) ✅ 支持

完整示例代码

以下是完整的示例代码,展示了如何使用 geolocator_tizen 获取地理位置信息。

import 'dart:async';
import 'dart:io' show Platform;

import 'package:baseflow_plugin_template/baseflow_plugin_template.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

/// 定义主主题颜色。
final MaterialColor themeMaterialColor =
    BaseflowPluginExample.createMaterialColor(
        const Color.fromRGBO(48, 49, 60, 1));

void main() {
  runApp(const GeolocatorWidget());
}

/// 示例 [Widget],展示 geolocator 插件的功能。
class GeolocatorWidget extends StatefulWidget {
  /// 创建一个新的 GeolocatorWidget。
  const GeolocatorWidget({Key? key}) : super(key: key);

  /// 工具方法,用于创建带有 Baseflow 模板的页面。
  static ExamplePage createPage() {
    return ExamplePage(
        Icons.location_on, (context) => const GeolocatorWidget());
  }

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

class _GeolocatorWidgetState extends State<GeolocatorWidget> {
  static const String _kLocationServicesDisabledMessage =
      '位置服务已禁用。';
  static const String _kPermissionDeniedMessage = '权限被拒绝。';
  static const String _kPermissionDeniedForeverMessage =
      '权限被永久拒绝。';
  static const String _kPermissionGrantedMessage = '权限已授予。';

  final GeolocatorPlatform _geolocatorPlatform = GeolocatorPlatform.instance;
  final List<_PositionItem> _positionItems = [];
  StreamSubscription<Position>? _positionStreamSubscription;
  StreamSubscription<ServiceStatus>? _serviceStatusStreamSubscription;
  bool positionStreamStarted = false;

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

  PopupMenuButton _createActions() {
    return PopupMenuButton(
      elevation: 40,
      onSelected: (value) async {
        switch (value) {
          case 1:
            _getLocationAccuracy();
            break;
          case 2:
            _requestTemporaryFullAccuracy();
            break;
          case 3:
            _openAppSettings();
            break;
          case 4:
            _openLocationSettings();
            break;
          case 5:
            setState(() => _positionItems.clear);
            break;
          default:
            break;
        }
      },
      itemBuilder: (context) => [
        if (Platform.isIOS)
          const PopupMenuItem(
            child: Text("获取位置精度"),
            value: 1,
          ),
        if (Platform.isIOS)
          const PopupMenuItem(
            child: Text("请求临时高精度"),
            value: 2,
          ),
        const PopupMenuItem(
          child: Text("打开应用设置"),
          value: 3,
        ),
        const PopupMenuItem(
          child: Text("打开位置设置"),
          value: 4,
        ),
        const PopupMenuItem(
          child: Text("清除"),
          value: 5,
        ),
      ],
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    const sizedBox = SizedBox(height: 10);

    return BaseflowPluginExample(
        pluginName: 'Geolocator',
        githubURL: 'https://github.com/Baseflow/flutter-geolocator',
        pubDevURL: 'https://pub.dev/packages/geolocator',
        appBarActions: [
          Padding(
            padding: const EdgeInsets.only(right: 50),
            child: _createActions(),
          ),
        ],
        pages: [
          ExamplePage(
            Icons.location_on,
            (context) => Scaffold(
              backgroundColor: Theme.of(context).colorScheme.background,
              body: ListView.builder(
                itemCount: _positionItems.length,
                itemBuilder: (context, index) {
                  final positionItem = _positionItems[index];

                  if (positionItem.type == _PositionItemType.log) {
                    return ListTile(
                      title: Text(positionItem.displayValue,
                          textAlign: TextAlign.center,
                          style: const TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                          )),
                    );
                  } else {
                    return Card(
                      child: ListTile(
                        tileColor: themeMaterialColor,
                        title: Text(
                          positionItem.displayValue,
                          style: const TextStyle(color: Colors.white),
                        ),
                      ),
                    );
                  }
                },
              ),
              floatingActionButton: Column(
                crossAxisAlignment: CrossAxisAlignment.end,
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  FloatingActionButton(
                    child: (_positionStreamSubscription == null ||
                            _positionStreamSubscription!.isPaused)
                        ? const Icon(Icons.play_arrow)
                        : const Icon(Icons.pause),
                    onPressed: () {
                      positionStreamStarted = !positionStreamStarted;
                      _toggleListening();
                    },
                    tooltip: (_positionStreamSubscription == null)
                        ? '开始位置更新'
                        : _positionStreamSubscription!.isPaused
                            ? '恢复'
                            : '暂停',
                    backgroundColor: _determineButtonColor(),
                  ),
                  sizedBox,
                  FloatingActionButton(
                    child: const Icon(Icons.my_location),
                    onPressed: _getCurrentPosition,
                  ),
                  sizedBox,
                  FloatingActionButton(
                    child: const Icon(Icons.bookmark),
                    onPressed: _getLastKnownPosition,
                  ),
                ],
              ),
            ),
          )
        ]);
  }

  Future<void> _getCurrentPosition() async {
    final hasPermission = await _handlePermission();

    if (!hasPermission) {
      return;
    }

    final position = await _geolocatorPlatform.getCurrentPosition();
    _updatePositionList(
      _PositionItemType.position,
      position.toString(),
    );
  }

  Future<bool> _handlePermission() async {
    bool serviceEnabled;
    LocationPermission permission;

    // 测试位置服务是否启用。
    serviceEnabled = await _geolocatorPlatform.isLocationServiceEnabled();
    if (!serviceEnabled) {
      // 如果位置服务未启用,则提示用户启用。
      _updatePositionList(
        _PositionItemType.log,
        _kLocationServicesDisabledMessage,
      );

      return false;
    }

    permission = await _geolocatorPlatform.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await _geolocatorPlatform.requestPermission();
      if (permission == LocationPermission.denied) {
        _updatePositionList(
          _PositionItemType.log,
          _kPermissionDeniedMessage,
        );

        return false;
      }
    }

    if (permission == LocationPermission.deniedForever) {
      _updatePositionList(
        _PositionItemType.log,
        _kPermissionDeniedForeverMessage,
      );

      return false;
    }

    _updatePositionList(
      _PositionItemType.log,
      _kPermissionGrantedMessage,
    );
    return true;
  }

  void _updatePositionList(_PositionItemType type, String displayValue) {
    _positionItems.add(_PositionItem(type, displayValue));
    setState(() {});
  }

  bool _isListening() =>
      !(_positionStreamSubscription == null || _positionStreamSubscription!.isPaused);

  Color _determineButtonColor() {
    return _isListening() ? Colors.green : Colors.red;
  }

  void _toggleServiceStatusStream() {
    if (_serviceStatusStreamSubscription == null) {
      final serviceStatusStream = _geolocatorPlatform.getServiceStatusStream();
      _serviceStatusStreamSubscription =
          serviceStatusStream.handleError((error) {
        _serviceStatusStreamSubscription?.cancel();
        _serviceStatusStreamSubscription = null;
      }).listen((serviceStatus) {
        String serviceStatusValue;
        if (serviceStatus == ServiceStatus.enabled) {
          if (positionStreamStarted) {
            _toggleListening();
          }
          serviceStatusValue = '启用';
        } else {
          if (_positionStreamSubscription != null) {
            setState(() {
              _positionStreamSubscription?.cancel();
              _positionStreamSubscription = null;
              _updatePositionList(
                  _PositionItemType.log, '位置流已取消');
            });
          }
          serviceStatusValue = '禁用';
        }
        _updatePositionList(
          _PositionItemType.log,
          '位置服务已 $serviceStatusValue',
        );
      });
    }
  }

  void _toggleListening() {
    if (_positionStreamSubscription == null) {
      final positionStream = _geolocatorPlatform.getPositionStream();
      _positionStreamSubscription = positionStream.handleError((error) {
        _positionStreamSubscription?.cancel();
        _positionStreamSubscription = null;
      }).listen((position) => _updatePositionList(
            _PositionItemType.position,
            position.toString(),
          ));
      _positionStreamSubscription?.pause();
    }

    setState(() {
      if (_positionStreamSubscription == null) {
        return;
      }

      String statusDisplayValue;
      if (_positionStreamSubscription!.isPaused) {
        _positionStreamSubscription!.resume();
        statusDisplayValue = '已恢复';
      } else {
        _positionStreamSubscription!.pause();
        statusDisplayValue = '已暂停';
      }

      _updatePositionList(
        _PositionItemType.log,
        '监听位置更新 $statusDisplayValue',
      );
    });
  }

  [@override](/user/override)
  void dispose() {
    if (_positionStreamSubscription != null) {
      _positionStreamSubscription!.cancel();
      _positionStreamSubscription = null;
    }

    super.dispose();
  }

  void _getLastKnownPosition() async {
    final position = await _geolocatorPlatform.getLastKnownPosition();
    if (position != null) {
      _updatePositionList(
        _PositionItemType.position,
        position.toString(),
      );
    } else {
      _updatePositionList(
        _PositionItemType.log,
        '无最后已知位置可用',
      );
    }
  }

  void _getLocationAccuracy() async {
    final status = await _geolocatorPlatform.getLocationAccuracy();
    _handleLocationAccuracyStatus(status);
  }

  void _requestTemporaryFullAccuracy() async {
    final status = await _geolocatorPlatform.requestTemporaryFullAccuracy(
      purposeKey: "TemporaryPreciseAccuracy",
    );
    _handleLocationAccuracyStatus(status);
  }

  void _handleLocationAccuracyStatus(LocationAccuracyStatus status) {
    String locationAccuracyStatusValue;
    if (status == LocationAccuracyStatus.precise) {
      locationAccuracyStatusValue = '精确';
    } else if (status == LocationAccuracyStatus.reduced) {
      locationAccuracyStatusValue = '降低';
    } else {
      locationAccuracyStatusValue = '未知';
    }
    _updatePositionList(
      _PositionItemType.log,
      '$locationAccuracyStatusValue 位置精度已授予',
    );
  }

  void _openAppSettings() async {
    final opened = await _geolocatorPlatform.openAppSettings();
    String displayValue;

    if (opened) {
      displayValue = '已打开应用设置';
    } else {
      displayValue = '打开应用设置失败';
    }

    _updatePositionList(
      _PositionItemType.log,
      displayValue,
    );
  }

  void _openLocationSettings() async {
    final opened = await _geolocatorPlatform.openLocationSettings();
    String displayValue;

    if (opened) {
      displayValue = '已打开位置设置';
    } else {
      displayValue = '打开位置设置失败';
    }

    _updatePositionList(
      _PositionItemType.log,
      displayValue,
    );
  }
}

enum _PositionItemType {
  log,
  position,
}

class _PositionItem {
  _PositionItem(this.type, this.displayValue);

  final _PositionItemType type;
  final String displayValue;
}

更多关于Flutter地理位置获取插件geolocator_tizen的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地理位置获取插件geolocator_tizen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


geolocator_tizen 是一个用于在 Tizen 平台上获取地理位置的 Flutter 插件。它是 geolocator 插件的一个扩展,专门为 Tizen 设备提供支持。使用这个插件,你可以在 Tizen 设备上获取设备的当前位置、监听位置变化等。

安装

首先,你需要在 pubspec.yaml 文件中添加 geolocator_tizen 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  geolocator_tizen: ^9.0.0

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

配置

在 Tizen 设备上使用地理位置功能,你需要在 tizen-manifest.xml 文件中添加相应的权限:

<privileges>
  <privilege>http://tizen.org/privilege/location</privilege>
</privileges>

使用

1. 获取当前位置

你可以使用 getCurrentPosition 方法来获取设备的当前位置:

import 'package:geolocator_tizen/geolocator_tizen.dart';

void getLocation() async {
  bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
  if (!serviceEnabled) {
    // 位置服务未启用
    return;
  }

  LocationPermission permission = await Geolocator.checkPermission();
  if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
    if (permission == LocationPermission.denied) {
      // 权限被拒绝
      return;
    }
  }

  if (permission == LocationPermission.deniedForever) {
    // 权限被永久拒绝
    return;
  }

  Position position = await Geolocator.getCurrentPosition();
  print(position.latitude);
  print(position.longitude);
}

2. 监听位置变化

你可以使用 getPositionStream 方法来监听设备位置的变化:

import 'package:geolocator_tizen/geolocator_tizen.dart';

void listenLocation() {
  Geolocator.getPositionStream().listen((Position position) {
    print(position.latitude);
    print(position.longitude);
  });
}

3. 检查位置服务是否启用

你可以使用 isLocationServiceEnabled 方法来检查设备的位置服务是否启用:

bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
  // 位置服务未启用
}

4. 请求位置权限

你可以使用 requestPermission 方法来请求位置权限:

LocationPermission permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
  // 权限被拒绝
}

注意事项

  1. 权限管理:在 Tizen 设备上,用户需要明确授予应用访问位置的权限。如果权限被拒绝,应用将无法获取位置信息。
  2. 位置服务:确保设备的位置服务已启用,否则无法获取位置信息。
  3. 模拟器支持:在 Tizen 模拟器上,可能需要手动设置模拟位置来测试地理位置功能。

示例

以下是一个完整的示例,展示了如何在 Tizen 设备上获取和监听位置信息:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Geolocator Tizen Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: getLocation,
                child: Text('Get Location'),
              ),
              ElevatedButton(
                onPressed: listenLocation,
                child: Text('Listen Location'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void getLocation() async {
    bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      print('Location services are disabled.');
      return;
    }

    LocationPermission permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        print('Location permissions are denied');
        return;
      }
    }

    if (permission == LocationPermission.deniedForever) {
      print('Location permissions are permanently denied, we cannot request permissions.');
      return;
    }

    Position position = await Geolocator.getCurrentPosition();
    print('Latitude: ${position.latitude}, Longitude: ${position.longitude}');
  }

  void listenLocation() {
    Geolocator.getPositionStream().listen((Position position) {
      print('Latitude: ${position.latitude}, Longitude: ${position.longitude}');
    });
  }
}
回到顶部