美文网首页
Flutter 获取定位

Flutter 获取定位

作者: 晓函 | 来源:发表于2022-01-11 16:30 被阅读0次

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

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

    官方文档地址

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

    1. 获取高德Key

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

    创建新应用

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

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

    申请key需要填写debug版本和release版本的keystore

    keystore和Keytool是什么

    Keytool是一个Java数据证书的管理工具 ,Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中。 在keystore里,包含两种数据:

    密钥实体(Key entity)——密钥(secret key)又或者是私钥和配对公钥(采用非对称加密)
    可信任的证书实体(trusted certificate entries)——只包含公钥
    Keystore可以简单理解为一个存放应用签名的文件。

    调试版安全码SHA1

    我是mac,进入当前用户文件夹下的~/.android目录(windows在c:/user/.android),里面有debug.keystore文件,运行命令获取该文件sha1

    cd ~/.android
    keytool -list -v -keystore debug.keystore
    

    如果keytool不存在则需要安装jdk。

    image.png

    如果debug.keystore不存在,则需要使用keytool -genkey命令生成一个debug.keystore

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

    image

    发布版安全码SHA1

    如果没有过apk还没有keystore签名文件,则需要生成,

    生成keystore签名文件

    keytool -genkey -v -keystore mykey.keystore -alias key -keyalg RSA -keysize 2048 -validity 10000
    

    填写好资料


    image.png

    生成后的文件在mac用户目录


    image.png

    命令行直接使用keytool进行得到mykey.keystore的sha1,在文件目录下运行

    keytool -list -v -keystore mykey.keystore
    
    image.png

    即可得到发布版安全码,apk就用这个keystore文件进行签名,这样就没问题了。

    如果需要把apk签名,具体方法请看:
    https://www.jianshu.com/p/398d41128b02

    PackageName

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

    image

    提交保存后即可获得Key。

    集成SDK

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

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

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

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

    添加服务、声明定位权限

    Android:
    在 android/app/src/main/AndroidManifest.xml 文件中
    1、添加服务

        <application android:label="****" android:icon="@mipmap/ic_launcher">
            <!-- 配置定位Service -->
            <service android:name="com.amap.api.location.APSService"/>
    

    2、声明权限

    <!--允许访问网络,必选权限-->
        <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"/>
    

    ios:
    1、ios/info.plist加入

        <key>NSLocationWhenInUseUsageDescription</key>
        <string>使用当前位置信息</string>
        <key>NSLocationAlwaysUsageDescription</key>
        <string>实时使用当前的位置信息</string>
        <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
        <string>实时使用当前的位置信息</string>
    

    2、ios/Padfile末尾加入

        target.build_configurations.each do |config|
        # Here are some configurations automatically generated by flutter
    
          # You can enable the permissions needed here. For example to enable camera
          # permission, just remove the `#` character in front so it looks like this:
          #
          # ## dart: PermissionGroup.camera
          # 'PERMISSION_CAMERA=1'
          #
          #  Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
            '$(inherited)',
    
            ## dart: PermissionGroup.calendar
            # 'PERMISSION_EVENTS=1',
    
            ## dart: PermissionGroup.reminders
            # 'PERMISSION_REMINDERS=1',
    
            ## dart: PermissionGroup.contacts
            # 'PERMISSION_CONTACTS=1',
    
            ## dart: PermissionGroup.camera
            'PERMISSION_CAMERA=1',
    
            ## dart: PermissionGroup.microphone
            'PERMISSION_MICROPHONE=1',
    
            ## dart: PermissionGroup.speech
            # 'PERMISSION_SPEECH_RECOGNIZER=1',
    
            ## dart: PermissionGroup.photos
            'PERMISSION_PHOTOS=1',
    
            ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
            'PERMISSION_LOCATION=1',
    
            ## dart: PermissionGroup.notification
            # 'PERMISSION_NOTIFICATIONS=1',
    
            ## dart: PermissionGroup.mediaLibrary
            # 'PERMISSION_MEDIA_LIBRARY=1',
    
            ## dart: PermissionGroup.sensors
            # 'PERMISSION_SENSORS=1',   
    
            ## dart: PermissionGroup.bluetooth
            # 'PERMISSION_BLUETOOTH=1',
    
            ## dart: PermissionGroup.appTrackingTransparency
            # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
    
            ## dart: PermissionGroup.criticalAlerts
            # 'PERMISSION_CRITICAL_ALERTS=1'
          ]
    
        end
    

    如图:


    image.png

    引入高德定位Flutter插件

    # 高德地图
    amap_flutter_location: ^3.0.0
    

    获取定位

    代码中填入申请好的高德apikey)

    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';
    
    /*
    //使用
    
        locationUtil.getCurrentLocation((Map result){
          print('接收到result:$result');
        }).catchError((err){
          Fluttertoast.showToast(msg: err);
        });
    
    */
    
    class LocationUtil {
      StreamSubscription<Map<String, Object>>? _locationListener;
      final AMapFlutterLocation _locationPlugin = AMapFlutterLocation();
      PermissionStatus? status;
    
    
      LocationUtil(){
        AMapFlutterLocation.setApiKey(
          "xxxxxx",//androidkey
          "xxxxxx"//ioskey
        );
    
    
        /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位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);
    
      }
    
      /// 动态申请定位权限
      Future<bool> _requestPermission() async {
        status = await Permission.location.status;
    
        if (status == PermissionStatus.granted) {
          return true;
        } else {
          //未授权则发起一次申请
          status = await Permission.location.request();
          print('status=$status');
          if (status == PermissionStatus.granted) {
            return true;
          } else {
            return false;
          }
        }
      }
    
    
      Future<void> getCurrentLocation(Function(Map result) onLocationChanged,{once=true}) async {
    
        bool isPermitted =  await _requestPermission();
        print('isPermitted=$isPermitted');
        if(!isPermitted){
          throw('请在手机设置中开启本app位置权限');
        }
    
        if(isPermitted){
          ///注册定位结果监听
          _locationListener = _locationPlugin.onLocationChanged().listen((Map<String, Object> result) {
            onLocationChanged(result);
            if (result['longitude'] != null) {
              //print("当前位置:$result");
              if(once) _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(); // 停止定位
        }
      }
    }
    

    错误

    Could not resolve com.amap.api:location:latest.integration.


    image.png

    如果出现这个错误,是因为build的时候,会去云端仓库请求最新的包列表,如果请求不到,则会无法build。我们可以指定包。
    查看最新的包:https://lbs.amap.com/api/android-location-sdk/guide/create-project/android-studio-create-project
    编辑android/app/build.gradle

    dependencies {
        implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
        implementation 'com.amap.api:location:3.3.0'//指定版本高德定位插件,
        //implementation 'com.amap.api:location:latest.integration'//最新版高德定位插件
    }
    

    相关文章

      网友评论

          本文标题:Flutter 获取定位

          本文链接:https://www.haomeiwen.com/subject/elabcrtx.html