flutter 集成百度地图

作者: Faith_K | 来源:发表于2020-04-07 17:38 被阅读0次

    1.去百度地图官网下载插件地址
    http://lbsyun.baidu.com/index.php?title=flutter/loc/download

    1. 在工程根目录下新建一个 plugins,把下载好的 bdmap_location_flutter_plugin 拖入到这个文件夹里面。如图


      image.png

      3.打开工程里面的 pubspec.yaml 添加以下代码 然后点package get

      bdmap_location_flutter_plugin:
        path: plugins/bdmap_location_flutter_plugin
    
    image.png

    出现以下表示正常已经下载好包

    /Users/xxx/flutter/bin/flutter --no-color packages get
    Running "flutter pub get" in flutter_app_demo...                    1.5s
    Process finished with exit code 0
    

    4.这个时候我们一定要运行下工程 ,一定要运行下工程 在强调一遍,因为运行成功会执行pod install...会把百度地图的依赖给配置好。

    Launching lib/main.dart on Faith6p in debug mode...
    Automatically signing iOS for device deployment using specified development team in Xcode project: C6VZ64TH78
    Running pod install...
    Running Xcode build...
    Xcode build done.                                           12.2s
    Failed to build iOS app
    Error output from Xcode build:
    ↳
        ** BUILD FAILED **
     #import "BMKLocationkit/BMKLocationComponent.h"
    
    

    5.到这来会出错会提示import导入的这个文件没有找到。这个时候我们需要打开xcode 手动配置依赖系统库与百度图的BMKLocationComponent,右击选择打开如下图


    image.png

    这里一定要打开Runner.xcworkspace因为这个是iospod管理的工程

    6.打开工程选中 pods,然后在选中 bdmap_location_flutter_plugin 添加系统库以及一个百度官方的BMKLocationkit
    添加BMKLocationkit 我需要点 + 然后选中 Add other,然后在点击Add file,将解压后的 BMKLocationKit.framework 文件复制或拖拽到工程文件夹中,左侧目录选中工程名,在TARGETS->Build Phases->Link Binary With Libaries中点击“+”按钮,在弹出的窗口中点击“Add Other”按钮,选择工程目录下的 BMKLocationKit.framework文件添加到工程中。如果不知道看下面的图


    image.png

    需要引入的系统库文件包括如下:

    CoreLocation.framework
    SystemConfiguration.framework
    Security.framework
    libsqlite3.0.tbd(xcode7以前为 libsqlite3.0.dylib)
    CoreTelephony.framework
    libc++.tbd(因需适配iOS12,需要将libstdc++.6.0.9.tbd 更新为libc++.tbd)
    AdSupport.framework
    

    在 TARGETS->General->Linked Frameworks and Libraries 中点击“+”,依次查找上述文件,添加到工程中,完成系统库文件的引入操作。

    image.png

    注意: 静态库中采用Objective-C++实现,因此需要您保证您工程中至少有一个.mm后缀的源文件(您可以将任意一个.m后缀的文件改名为.mm),或者在工程属性中指定编译方式,即在Xcode的Project -> Edit Active Target -> Build Setting 中找到 Compile Sources As,并将其设置为"Objective-C++"。 不报错可以不用管

    7 ios申请权限


    image.png
    
    (1)在项目的 Info.plist 添加定位权限申请,根据您的实际业务需求,选择如下方式设置:
        - NSLocationWhenInUseUsageDescription:表示应用在前台的时候可以搜到更新的位置信息;
        - NSLocationAlwaysUsageDescription:表示应用在前台和后台(suspend 或 terminated)都可以获取到更新的位置数据;
        - NSLocationAlwaysAndWhenInUseUsageDescription:申请永久定位权限,以便应用在前台和后台都可以获取位置数据;
    
        (b)如果您需要永久定位的话,请设置如下:
            - 在Info.plist里配置NSLocationWhenInUseUsageDescription,NSLocationAlwaysUsageDescription,NSLocationAlwaysAndWhenInUseUsageDescription三项; 
    

    官方文档 地址 https://lbsyun.baidu.com/index.php?title=ios-locsdk/guide/create-project/manual-create
    到这里就已经完成了配置,接下来我们运行一下,然后点开始定位程序闪退,以下错误是,百度地图里面调用了__NSDictionaryM 的setObject 的值为null。如果正常可以忽略,《已经给百度地图递交过工单了》

    2020-04-07 16:26:47.610285+0800 Runner[84851:1075309] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: poiList)'
    *** First throw call stack:
    (
        0   CoreFoundation                      0x00007fff23c7127e __exceptionPreprocess + 350
        1   libobjc.A.dylib                     0x00007fff513fbb20 objc_exception_throw + 48
        2   CoreFoundation                      0x00007fff23d03ab1 _CFThrowFormattedException + 194
        3   CoreFoundation                      0x00007fff23d0e6a6 -[__NSDictionaryM setObject:forKey:].cold.2 + 38
        4   CoreFoundation                      0x00007fff23cd1d4f -[__NSDictionaryM setObject:forKey:] + 1071
        5   bdmap_location_flutter_plugin       0x000000010f3b945b -[LocationFlutterPlugin BMKLocationManager:didUpdateLocation:orError:] + 6331
        6   bdmap_location_flutter_plugin       0x000000010f3c6f58 __52-[BMKLocationManager returnLastSemanticOnMainThread]_block_invoke + 950
        7   libdispatch.dylib                   0x000000010ffc5dd4 _dispatch_call_block_and_release + 12
        8   libdispatch.dylib                   0x000000010ffc6d48 _dispatch_client_callout + 8
        9   libdispatch.dylib                   0x000000010ffd4de6 _dispatch_main_queue_callback_4CF + 1500
        10  CoreFoundation                      0x00007fff23bd4049 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
        11  CoreFoundation                      0x00007fff23bceca9 __CFRunLoopRun + 2329
        12  CoreFoundation                      0x00007fff23bce066 CFRunLoopRunSpecific + 438
        13  GraphicsServices                    0x00007fff384c0bb0 GSEventRunModal + 65
        14  UIKitCore                           0x00007fff48092d4d UIApplicationMain + 1621
        15  Runner                              0x000000010cdcbbbb main + 75
        16  libdyld.dylib                       0x00007fff5227ec25 start + 1
    )
    libc++abi.dylib: terminating with uncaught exception of type NSException
    (lldb) 
    

    崩溃原因,是__NSDictionaryM调用方法setObject,设置了一个值为null,在ios里面是不允许的。这里我们通过ios的运行时方法交换处理了一下。在工程里添加三个文件即可,这里代码写好了拖入ios 工程即可
    下载地址 链接: https://pan.baidu.com/s/1gOutSNT5zNOtd4A8J4YSMA 提取码: a7u8
    把下载好的文件解压一下拖入ios工程中即可

    image.png
    8.然后我们去百度地图申请 ios key ,跟安卓key。地址 http://lbsyun.baidu.com/apiconsole/center#/home ,选控制台创建应用就好了,
    image.png
    9,按照官方提供的demo我们这里直接把代码复制到自己的工程里,先做下测试
    大功告成
    image.png
    <如果你是跟我一样使用ios模拟器测试的话,想要自定义经纬度的可按一下步骤,选择模拟器点击菜单debug-Location-Costom Locarion>
    image.png
    import 'package:flutter/material.dart';
    import 'dart:async';
    
    import 'package:bdmap_location_flutter_plugin/bdmap_location_flutter_plugin.dart';
    import 'package:bdmap_location_flutter_plugin/flutter_baidu_location.dart';
    import 'package:bdmap_location_flutter_plugin/flutter_baidu_location_android_option.dart';
    import 'package:bdmap_location_flutter_plugin/flutter_baidu_location_ios_option.dart';
    class MapLocation extends StatefulWidget {
      @override
      _MapLocationState createState() => _MapLocationState();
    }
    
    class _MapLocationState extends State<MapLocation> {
      Map<String, Object> _loationResult;
      BaiduLocation _baiduLocation; // 定位结果
    
      StreamSubscription<Map<String, Object>> _locationListener;
    
      LocationFlutterPlugin _locationPlugin = new LocationFlutterPlugin();
    
      @override
      void initState() {
        super.initState();
    
        /// 动态申请定位权限
        _locationPlugin.requestPermission();
    
        /// 设置ios端ak, android端ak可以直接在清单文件中配置
        LocationFlutterPlugin.setApiKey("iOS申请的key换成自己的");
    
        _locationListener = _locationPlugin
            .onResultCallback()
            .listen((Map<String, Object> result) {
          setState(() {
            _loationResult = result;
            try {
              _baiduLocation = BaiduLocation.fromMap(result); // 将原生端返回的定位结果信息存储在定位结果类中
    //          print(_baiduLocation);
            } catch (e) {
              print(e);
            }
          });
        });
    
      }
    
      @override
      void dispose() {
        super.dispose();
        if (null != _locationListener) {
          _locationListener.cancel(); // 停止定位
        }
      }
    
      /// 设置android端和ios端定位参数
      void _setLocOption() {
        /// android 端设置定位参数
        BaiduLocationAndroidOption androidOption = new BaiduLocationAndroidOption();
        androidOption.setCoorType("bd09ll"); // 设置返回的位置坐标系类型
        androidOption.setIsNeedAltitude(true); // 设置是否需要返回海拔高度信息
        androidOption.setIsNeedAddres(true); // 设置是否需要返回地址信息
        androidOption.setIsNeedLocationPoiList(true); // 设置是否需要返回周边poi信息
        androidOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
        androidOption.setIsNeedLocationDescribe(true); // 设置是否需要返回位置描述
        androidOption.setOpenGps(true); // 设置是否需要使用gps
        androidOption.setLocationMode(LocationMode.Hight_Accuracy); // 设置定位模式
        androidOption.setScanspan(1000); // 设置发起定位请求时间间隔
    
        Map androidMap = androidOption.getMap();
    
        /// ios 端设置定位参数
        BaiduLocationIOSOption iosOption = new BaiduLocationIOSOption();
        iosOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
        iosOption.setBMKLocationCoordinateType("BMKLocationCoordinateTypeBMK09LL"); // 设置返回的位置坐标系类型
        iosOption.setActivityType("CLActivityTypeAutomotiveNavigation"); // 设置应用位置类型
        iosOption.setLocationTimeout(10); // 设置位置获取超时时间
        iosOption.setDesiredAccuracy("kCLLocationAccuracyBest");  // 设置预期精度参数
        iosOption.setReGeocodeTimeout(10); // 设置获取地址信息超时时间
        iosOption.setDistanceFilter(100); // 设置定位最小更新距离
        iosOption.setAllowsBackgroundLocationUpdates(true); // 是否允许后台定位
        iosOption.setPauseLocUpdateAutomatically(true); //  定位是否会被系统自动暂停
    
        Map iosMap = iosOption.getMap();
    
        _locationPlugin.prepareLoc(androidMap, iosMap);
      }
    
      /// 启动定位
      void _startLocation() {
        if (null != _locationPlugin) {
          _setLocOption();
          _locationPlugin.startLocation();
        }
      }
    
      /// 停止定位
      void _stopLocation() {
        if (null != _locationPlugin) {
          _locationPlugin.stopLocation();
        }
      }
    
      Container _createButtonContainer() {
        return new Container(
            alignment: Alignment.center,
            child: new Row(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                new RaisedButton(
                  onPressed: _startLocation,
                  child: new Text('开始定位'),
                  color: Colors.blue,
                  textColor: Colors.white,
                ),
                new Container(width: 20.0),
                new RaisedButton(
                  onPressed: _stopLocation,
                  child: new Text('停止定位'),
                  color: Colors.blue,
                  textColor: Colors.white,
                )
              ],
            ));
      }
    
      Widget _resultWidget(key, value) {
        return new Container(
          child: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new Text('$key:' ' $value'),
                ]
            ),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        List<Widget> widgets = new List();
    
        if (_loationResult != null) {
          _loationResult.forEach((key, value) {
            widgets.add(_resultWidget(key, value));
          });
        }
    
        widgets.add(_createButtonContainer());
    
    
        return new MaterialApp(
            home: new Scaffold(
              appBar: new AppBar(
                title: new Text('基础定位'),
              ),
              body: new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: widgets,
              ),
            ));
      }
    }
    
    

    写在在最后

    自己在集成的是也遇到了很多问题,我都在上面列出来希望可以帮到你。
    更新一个问题,有个小伙伴用flutter创建的ios oc项目,集成一直报错误,建议换成ios swfit的
    2020年06月05日17:15:04 解决oc项目报错
    因为你创建的是oc 工程百度插件是用swift写的,需要一个文件来桥接
    在工程里,新建一个swift文件就好了,名字随便起 xcode 会自动帮你桥接,

    2020年08月04日10:58:20 有跟多小伙伴按照流程集成到后面还是提示 #import "BMKLocationkit/BMKLocationComponent.h"没有找到,需要把BMKLocationKit.framework的库放到iOS目录下的Pods文件夹里面,然后在从新add引入 。

    相关文章

      网友评论

        本文标题:flutter 集成百度地图

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