Flutter高德地图定位插件ht_amap_flutter_location的使用

Flutter高德地图定位插件ht_amap_flutter_location的使用

前述

  1. 高德定位Flutter插件
  2. 登录高德开放平台官网分别申请Android端iOS端的key
  3. 如需了解高德定位SDK的相关功能,请参阅Android定位SDK开发指南iOS定位SDK开发指南

使用高德定位Flutter插件

1. 在Flutter项目中引入插件

请参考在Flutter里使用Packages,引入ht_amap_flutter_location插件。

dependencies:
  ht_amap_flutter_location: ^版本号

2. 引入高德定位SDK


常见问题:

  1. 在iOS设备上运行或者运行iOS工程遇到:
    Invalid Podfile file: cannot load such file - /flutter/packages/flutter_tools/bin/podhelper
    
    解决方案:
    $ rm ios/Podfile
    $ flutter build ios
    

在需要的定位功能的页面中引入定位Flutter插件的dart类

import 'package:ht_amap_flutter_location/ht_amap_flutter_location.dart';
import 'package:ht_amap_flutter_location/amap_location_option.dart';

接口说明

设置定位参数

/// 设置定位参数
void setLocationOption(AMapLocationOption locationOption)

参数说明:

bool needAddress = true; // 是否需要地址信息,默认true
GeoLanguage geoLanguage = GeoLanguage.DEFAULT; // 逆地理信息语言类型,默认自动适配
bool onceLocation = false; // 是否单次定位,默认false
AMapLocationMode locationMode = AMapLocationMode.Hight_Accuracy; // Android端定位模式,默认高精度模式
int locationInterval = 2000; // Android端定位间隔,默认2000ms
bool pausesLocationUpdatesAutomatically = false; // iOS端是否允许系统暂停定位,默认false
DesiredAccuracy desiredAccuracy = DesiredAccuracy.Best; // iOS端期望的定位精度,默认最高精度
double distanceFilter = -1; // iOS端定位最小更新距离,默认不限制
AMapLocationAccuracyAuthorizationMode desiredLocationAccuracyAuthorizationMode = AMapLocationAccuracyAuthorizationMode.FullAccuracy; // iOS 14中设置期望的定位精度权限
String fullAccuracyPurposeKey = ""; // iOS 14中定位精度权限由模糊定位升级到精确定位时需要的场景key

开始定位

void startLocation()

停止定位

void stopLocation()

销毁定位

void destroy()

说明:

高德定位Flutter插件支持多实例,请在dispose()时调用当前定位插件的销毁方法。


定位结果获取

注册定位结果监听

Stream<Map<String, Object>> onLocationChanged()

_locationPlugin
    .onLocationChanged()
    .listen((Map<String, Object> result) {
      /// result即为定位结果
});

定位结果示例:

{
  /// `callbackTime`: 回调时间,格式为"yyyy-MM-dd HH:mm:ss"
  /// `locationTime`: 定位时间,格式为"yyyy-MM-dd HH:mm:ss"
  /// `locationType`: 定位类型,具体类型参考https://lbs.amap.com/api/android-location-sdk/guide/utilities/location-type
  /// `latitude`: 纬度
  /// `longitude`: 经度
  /// `accuracy`: 精确度
  /// `altitude`: 海拔, Android上只有locationType==1时才会有值
  /// `bearing`: 角度, Android上只有locationType==1时才会有值
  /// `speed`: 速度, Android上只有locationType==1时才会有值
  /// `country`: 国家,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `province`: 省,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `city`: 城市,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `district`: 城镇(区),Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `street`: 街道,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `streetNumber`: 门牌号,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `cityCode`: 城市编码,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `adCode`: 区域编码,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `address`: 地址信息,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `description`: 位置语义,Android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  /// `errorCode`: 错误码,当定位失败时才会返回对应的错误码,具体错误请参考:https://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode
  /// `errorInfo`: 错误信息,当定位失败时才会返回
}

完整示例Demo

以下是完整的示例代码:

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:ht_amap_flutter_location/ht_amap_flutter_location.dart';
import 'package:ht_amap_flutter_location/amap_location_option.dart';
import 'package:permission_handler/permission_handler.dart';

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

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Map<String, Object>? _locationResult;

  StreamSubscription<Map<String, Object>>? _locationListener;

  AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();

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

    // 设置隐私政策
    AMapFlutterLocation.updatePrivacyShow(true, true);
    AMapFlutterLocation.updatePrivacyAgree(true);

    // 动态申请权限
    requestPermission();

    // 设置Android和iOS的apiKey
    AMapFlutterLocation.setApiKey(
        "1dbf56e2e8a4d0e4cdc2df9efd36bc71", "dfb64c0463cb53927914364b5c09aba0");

    // iOS获取native精度类型
    if (Platform.isIOS) {
      requestAccuracyAuthorization();
    }

    // 注册定位结果监听
    _locationListener = _locationPlugin
        .onLocationChanged()
        .listen((Map<String, Object> result) {
      setState(() {
        _locationResult = result;
      });
    });
  }

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

    // 移除监听
    if (null != _locationListener) {
      _locationListener?.cancel();
    }

    // 销毁定位
    _locationPlugin.destroy();
  }

  // 设置定位参数
  void _setLocationOption() {
    AMapLocationOption locationOption = new AMapLocationOption();

    // 是否单次定位
    locationOption.onceLocation = false;

    // 是否需要地址信息
    locationOption.needAddress = true;

    // 逆地理信息语言类型
    locationOption.geoLanguage = GeoLanguage.DEFAULT;

    // 设置定位精度模式
    locationOption.desiredLocationAccuracyAuthorizationMode =
        AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;

    locationOption.fullAccuracyPurposeKey = "AMapLocationScene";

    // 设置Android端定位间隔
    locationOption.locationInterval = 2000;

    // 设置Android端定位模式
    locationOption.locationMode = AMapLocationMode.Hight_Accuracy;

    // 设置iOS端定位最小更新距离
    locationOption.distanceFilter = -1;

    // 设置iOS端期望的定位精度
    locationOption.desiredAccuracy = DesiredAccuracy.Best;

    // 设置iOS端是否允许系统暂停定位
    locationOption.pausesLocationUpdatesAutomatically = false;

    // 将定位参数设置给插件
    _locationPlugin.setLocationOption(locationOption);
  }

  // 开始定位
  void _startLocation() {
    _setLocationOption();
    _locationPlugin.startLocation();
  }

  // 停止定位
  void _stopLocation() {
    _locationPlugin.stopLocation();
  }

  // 创建按钮容器
  Container _createButtonContainer() {
    return new Container(
        alignment: Alignment.center,
        child: new Row(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            new ElevatedButton(
              onPressed: _startLocation,
              child: new Text('开始定位'),
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.blue),
                foregroundColor: MaterialStateProperty.all(Colors.white),
              ),
            ),
            new Container(width: 20.0),
            new ElevatedButton(
              onPressed: _stopLocation,
              child: new Text('停止定位'),
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.blue),
                foregroundColor: MaterialStateProperty.all(Colors.white),
              ),
            )
          ],
        ));
  }

  // 结果展示组件
  Widget _resultWidget(key, value) {
    return new Container(
      child: new Row(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          new Container(
            alignment: Alignment.centerRight,
            width: 100.0,
            child: new Text('$key :'),
          ),
          new Container(width: 5.0),
          new Flexible(child: new Text('$value', softWrap: true)),
        ],
      ),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    List<Widget> widgets = <Widget>[];
    widgets.add(_createButtonContainer());

    if (_locationResult != null) {
      _locationResult?.forEach((key, value) {
        widgets.add(_resultWidget(key, value));
      });
    }

    return new MaterialApp(
        home: new Scaffold(
      appBar: new AppBar(
        title: new Text('AMap Location plugin example app'),
      ),
      body: new Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: widgets,
      ),
    ));
  }

  // 获取iOS native的accuracyAuthorization类型
  void requestAccuracyAuthorization() async {
    AMapAccuracyAuthorization currentAccuracyAuthorization =
        await _locationPlugin.getSystemAccuracyAuthorization();
    if (currentAccuracyAuthorization ==
        AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
      print("精确定位类型");
    } else if (currentAccuracyAuthorization ==
        AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
      print("模糊定位类型");
    } else {
      print("未知定位类型");
    }
  }

  // 动态申请定位权限
  void requestPermission() async {
    bool hasLocationPermission = await requestLocationPermission();
    if (hasLocationPermission) {
      print("定位权限申请通过");
    } else {
      print("定位权限申请不通过");
    }
  }

  // 申请定位权限
  Future<bool> requestLocationPermission() async {
    var status = await Permission.location.status;
    if (status == PermissionStatus.granted) {
      return true;
    } else {
      status = await Permission.location.request();
      if (status == PermissionStatus.granted) {
        return true;
      } else {
        return false;
      }
    }
  }
}

更多关于Flutter高德地图定位插件ht_amap_flutter_location的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter高德地图定位插件ht_amap_flutter_location的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


ht_amap_flutter_location 是一个基于高德地图的 Flutter 定位插件,用于在 Flutter 应用中获取设备的地理位置信息。以下是如何使用 ht_amap_flutter_location 插件的详细步骤。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 ht_amap_flutter_location 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  ht_amap_flutter_location: ^版本号

替换 ^版本号 为你想要使用的插件版本号。

2. 配置高德地图 Key

AndroidManifest.xmlInfo.plist 文件中配置高德地图的 Key。

Android 配置

android/app/src/main/AndroidManifest.xml 文件中添加以下内容:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <application
        android:name=".MyApplication"
        android:label="Your App"
        android:icon="@mipmap/ic_launcher">
        
        <meta-data
            android:name="com.amap.api.v2.apikey"
            android:value="你的高德地图Key" />
            
    </application>
</manifest>

iOS 配置

ios/Runner/Info.plist 文件中添加以下内容:

<key>NSLocationWhenInUseUsageDescription</key>
<string>我们需要您的位置信息来提供更好的服务</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>我们需要您的位置信息来提供更好的服务</string>
<key>AMapKey</key>
<string>你的高德地图Key</string>

3. 初始化插件

main.dart 文件中初始化插件:

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await AMapFlutterLocation().setApiKey('你的高德地图Key');
  runApp(MyApp());
}

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

4. 获取位置信息

在需要使用定位的地方,调用 AMapFlutterLocation 的方法来获取位置信息。

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  AMapFlutterLocation _location = AMapFlutterLocation();
  LocationResult? _locationResult;

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

  void _startLocation() {
    _location.onLocationChanged().listen((LocationResult result) {
      setState(() {
        _locationResult = result;
      });
    });

    _location.startLocation();
  }

  @override
  void dispose() {
    _location.stopLocation();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('高德地图定位示例'),
      ),
      body: Center(
        child: _locationResult == null
            ? CircularProgressIndicator()
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('纬度: ${_locationResult?.latitude}'),
                  Text('经度: ${_locationResult?.longitude}'),
                  Text('地址: ${_locationResult?.address}'),
                ],
              ),
      ),
    );
  }
}

5. 处理权限

在 Android 和 iOS 上,定位功能需要用户授权。确保在应用中正确处理定位权限。

Android

AndroidManifest.xml 中添加以下权限:

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

iOS

Info.plist 中添加以下权限描述:

<key>NSLocationWhenInUseUsageDescription</key>
<string>我们需要您的位置信息来提供更好的服务</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>我们需要您的位置信息来提供更好的服务</string>
回到顶部