Flutter 获取定位

由于众所周知的原因,国内无法使用location提供的谷歌定位服务,所以只能使用百度地图或者高德地图提供的定位服务。

所幸双方都已经实现了对flutter的支持。百度地图的api和配置比高德要简单那么一丢丢,不过包好像很久没更新,以至于错误很多。最终还是选了高德地图来实现。

官方文档地址

https://lbs.amap.com/api/flutter/gettingstarted

1. 获取高德Key

在控制台创建新的应用获取key

创建新应用

应用名称自定义,可以随便写。类型选择相符的就可以,这个不会严格审查的。

应用下面可以有好几个key,key的名称可以自定义,平台选择对应的平台。

调试版安全码SHA1

进入当前用户文件夹下的.android目录,通常是 C:\Users\**\.android,运行命令

keytool -list -v -keystore debug.keystore

输入密钥口令,默认是 android,即可获得SHA1安全码

发布版安全码SHA1

同样的方法,找到发布过程中生成的upload-keystore.jks文件,在文件目录下运行

keytool -list -v -keystore upload-keystore.jks

即可得到发布版安全码。

PackageName

android/app/build.gradle 中获取包名

提交保存后即可获得Key。

集成SDK

android/build.gradle 文件中,添加mavenCentral()或者 jcenter()

allprojects { repositories { jcenter() // 或者 mavenCentral() } }

android/app/build.gradle 中,配置依赖:

dependencies {
    ...
    implementation 'com.amap.api:location:latest.integration'
}

添加高德 Key

android/app/src/main/AndroidManifest.xml 文件中,添加刚刚获取到的key,并配置定位服务。

    <application android:label="****" android:icon="@mipmap/ic_launcher"
                 android:networkSecurityConfig="@xml/network_security_config">
        <!-- 配置高德地图ApiKey -->
        <meta-data android:name="com.amap.api.v2.apikey" android:value="****"/>
        <!-- 配置定位Service -->
        <service android:name="com.amap.api.location.APSService"/>

声明定位权限

android/app/src/main/AndroidManifest.xml 文件中,声明权限

点击查看代码
<!--允许访问网络,必选权限-->
    <uses-permission android:name="android.permission.INTERNET"/>
    <!--允许获取精确位置,精准定位必选-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <!--允许获取粗略位置,粗略定位必选-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <!--允许获取设备和运营商信息,用于问题排查和网络定位(无gps情况下的定位),若需网络定位功能则必选-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <!--允许获取网络状态,用于网络定位(无gps情况下的定位),若需网络定位功能则必选-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!--允许获取wifi网络信息,用于网络定位(无gps情况下的定位),若需网络定位功能则必选-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <!--允许获取wifi状态改变,用于网络定位(无gps情况下的定位),若需网络定位功能则必选-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <!--后台获取位置信息,若需后台定位则必选-->
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
    <!--用于申请调用A-GPS模块,卫星定位加速-->
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
    <!--允许写设备缓存,用于问题排查-->
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
    <!--允许写入扩展存储,用于写入缓存定位数据-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--允许读设备等信息,用于问题排查-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

引入高德定位Flutter插件

# 高德地图
amap_flutter_location: ^3.0.0

获取定位

点击查看代码
import 'dart:async';

import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:permission_handler/permission_handler.dart';

class LocationService {
  StreamSubscription<Map<String, Object>>? _locationListener;
  final AMapFlutterLocation _locationPlugin = AMapFlutterLocation();
  PermissionStatus? status;

  /// 动态申请定位权限
  Future<bool> _requestPermission() async {
    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;
      }
    }
  }

  Future<void> run() async {
    /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作
    ///
    /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
    /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
    ///
    /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
    ///
    /// [hasContains] 隐私声明中是否包含高德隐私政策说明
    ///
    /// [hasShow] 隐私权政策是否弹窗展示告知用户
    AMapFlutterLocation.updatePrivacyShow(true, true);

    /// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作
    ///
    /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
    ///
    /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
    ///
    /// [hasAgree] 隐私权政策是否已经取得用户同意
    AMapFlutterLocation.updatePrivacyAgree(true);
    bool isPermitted =  await _requestPermission();

    if(isPermitted){
      ///注册定位结果监听
      _locationListener = _locationPlugin.onLocationChanged().listen((Map<String, Object> result) {
        if (result['adCode'] != null) {
          String adCode = result['adCode'].toString();
          print("当前位置:$adCode");
          _stopLocation();
        }
      });
      _startLocation();
    }
  }

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

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

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

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

  void cancel() {
    if (null != _locationListener) {
      _locationListener?.cancel(); // 停止定位
    }
  }
}

在main.dart中使用

点击查看代码
class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  final LocationService _locationService = LocationService();

  @override
  void initState() {
    super.initState();
    _locationService.run();
  }

  @override
  void dispose() {
    _locationService.cancel();
    super.dispose();
  }
}
posted @   Bin_x  阅读(2479)  评论(1编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示