Flutter 混合开发 - 02 百度地图定位功能 android 篇

本节目标

  • 百度地图业务
  • 百度组件初始
  • 编写定位代码 android 篇

环境

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 1.20.1, on Mac OS X 10.15.6 19G73, locale zh-Hans-CN)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.6)
[✓] Android Studio (version 4.0)
[✓] VS Code (version 1.47.3)

视频

https://www.bilibili.com/video/BV1iK411T7LC/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A9J5qIXL-1597306264427)(https://imgkr2.cn-bj.ufileos.com/42ee6b54-fc0c-4f77-884c-1815de241f9e.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=%252FHMu2PKQWS5El5Gw966MuzCbdLM%253D&Expires=1597387242)]

代码

https://github.com/ducafecat/flutter_baidu_plugin_ducafecat/releases/tag/v1.0.2

可以直接用 👇 v1.0.3

https://github.com/ducafecat/flutter_baidu_plugin_ducafecat/releases/tag/v1.0.3

正文

创建组件的几种方式

现成轮子直接用
  • 官方仓库搜索

    https://pub.dev/flutter/packages

    https://pub.flutter-io.cn/flutter/packages

可参考的组件代码
  • 通过仓库,查找 github 代码仓

  • 网站、客服索取代码

参考官方集成文档编写组件
  • 官网文档

http://lbsyun.baidu.com/index.php?title=flutter/loc

组件代码

百度应用管理,创建 AK
  • 应用管理

https://lbsyun.baidu.com/apiconsole/key#/home

  • 查询 SHA1

http://lbsyun.baidu.com/index.php?title=FAQ/SHA1

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey
  • 设置 AK

example/android/app/src/main/AndroidManifest.xml


...

        <!-- 在这里设置android端ak-->
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="aCUtcLDufllGi4nEaKgU8FmBqufFyekh" />

    </application>
</manifest>

设置 Android 权限
  • 文档

http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/create-project/android-studio

  • android/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="tech.ducafecat.flutter_baidu_plugin_ducafecat">
    <!-- 这个权限用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    <!-- 这个权限用于访问GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <!-- 用于读取手机当前的状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <!-- 访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- 读取系统信息,包含系统版本等信息,用作统计-->
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
    <!-- 程序在手机屏幕关闭后后台进程仍然运行-->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <application>
        <!-- 声明service组件 -->
        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" >
        </service>
    </application>
</manifest>
添加 android libs 库文件
  • 目录 android/libs

  • android/build.gradle
...
android {
    compileSdkVersion 28

    sourceSets {
        main {
            jniLibs.srcDir 'libs'
        }
    }

    defaultConfig {
        minSdkVersion 16
    }
    lintOptions {
        disable 'InvalidPackage'
    }
}

dependencies {
    implementation files('libs/BaiduLBS_Android.jar')
}

编写 Flutter 组件代码
  • 目录 lib

  • 地理信息 lib/entity/flutter_baidu_location.dart
/// 百度定位结果类,用于存储各类定位结果信息
class BaiduLocation {
  /// 定位成功时间
  final String locTime;

  /// 定位结果类型
  final int locType;

  /// 半径
  final double radius;

  /// 纬度
  final double latitude;

  /// 经度
  final double longitude;

  /// 海拔
  final double altitude;

  /// 国家
  final String country;

  /// 省份
  final String province;

  /// 城市
  final String city;

  /// 区县
  final String district;

  /// 街道
  final String street;

  /// 地址
  final String address;

  /// 位置语义化描述,例如"在百度大厦附近"
  final String locationDetail;

  /// 周边poi信息,每个poi之间用"|"隔开

  final String poiList;

  /// 定位结果回调时间
  final String callbackTime;

  /// 错误码
  final int errorCode;

  /// 定位失败描述信息
  final String errorInfo;

  BaiduLocation(
      {this.locTime,
      this.locType,
      this.radius,
      this.latitude,
      this.longitude,
      this.altitude,
      this.country,
      this.province,
      this.city,
      this.district,
      this.street,
      this.address,
      this.locationDetail,
      this.poiList,
      this.callbackTime,
      this.errorCode,
      this.errorInfo});

  /// 根据传入的map生成BaiduLocation对象
  factory BaiduLocation.fromMap(dynamic value) {
    return new BaiduLocation(
      locTime: value['locTime'],
      locType: value['locType'],
      radius: value['radius'],
      latitude: value['latitude'],
      longitude: value['longitude'],
      altitude: value['altitude'],
      country: value['country'],
      province: value['province'],
      city: value['city'],
      district: value['district'],
      street: value['street'],
      address: value['address'],
      locationDetail: value['locationDetail'],
      poiList: value['poiList'],
      callbackTime: value['callbackTime'],
      errorCode: value['errorCode'],
      errorInfo: value['errorInfo'],
    );
  }

  /// 获取对本类所有变量赋值后的map键值对
  Map getMap() {
    return {
      "locTime": locTime,
      "locType": locType,
      "radius": radius,
      "latitude": latitude,
      "longitude": longitude,
      "altitude": altitude,
      "country": country,
      "province": province,
      "city": city,
      "district": district,
      "street": street,
      "address": address,
      "locationDescribe": locationDetail,
      "poiList": poiList,
      "callbackTime": callbackTime,
      "errorCode": errorCode,
      "errorInfo": errorInfo,
    };
  }
}

  • android 配置项 lib/entity/flutter_baidu_location_android_option.dart
/// 设置android端定位参数类
class BaiduLocationAndroidOption {
  /// 坐标系类型
  String coorType;

  /// 是否需要返回地址信息
  bool isNeedAddres;

  /// 是否需要返回海拔高度信息
  bool isNeedAltitude;

  /// 是否需要返回周边poi信息
  bool isNeedLocationPoiList;

  /// 是否需要返回新版本rgc信息
  bool isNeedNewVersionRgc;

  /// 是否需要返回位置描述信息
  bool isNeedLocationDescribe;

  /// 是否使用gps
  bool openGps;

  /// 可选,设置发起定位请求的间隔,int类型,单位ms
  /// 如果设置为0,则代表单次定位,即仅定位一次,默认为0
  /// 如果设置非0,需设置1000ms以上才有效
  int scanspan;

  /// 设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
  int locationMode;

  /// 可选,设置场景定位参数,包括签到场景、运动场景、出行场景
  int locationPurpose;

  /// 可选,设置返回经纬度坐标类型,默认GCJ02
  /// GCJ02:国测局坐标;
  /// BD09ll:百度经纬度坐标;
  /// BD09:百度墨卡托坐标;
  /// 海外地区定位,无需设置坐标类型,统一返回WGS84类型坐标
  void setCoorType(String coorType) {
    this.coorType = coorType;
  }

  /// 是否需要返回地址信息
  void setIsNeedAddres(bool isNeedAddres) {
    this.isNeedAddres = isNeedAddres;
  }

  /// 是否需要返回海拔高度信息
  void setIsNeedAltitude(bool isNeedAltitude) {
    this.isNeedAltitude = isNeedAltitude;
  }

  /// 是否需要返回周边poi信息
  void setIsNeedLocationPoiList(bool isNeedLocationPoiList) {
    this.isNeedLocationPoiList = isNeedLocationPoiList;
  }

  /// 是否需要返回位置描述信息
  void setIsNeedLocationDescribe(bool isNeedLocationDescribe) {
    this.isNeedLocationDescribe = isNeedLocationDescribe;
  }

  /// 是否需要返回新版本rgc信息
  void setIsNeedNewVersionRgc(bool isNeedNewVersionRgc) {
    this.isNeedNewVersionRgc = isNeedNewVersionRgc;
  }

  /// 是否使用gps
  void setOpenGps(bool openGps) {
    this.openGps = openGps;
  }

  /// 可选,设置发起定位请求的间隔,int类型,单位ms
  /// 如果设置为0,则代表单次定位,即仅定位一次,默认为0
  /// 如果设置非0,需设置1000ms以上才有效
  void setScanspan(int scanspan) {
    this.scanspan = scanspan;
  }

  /// 设置定位模式,可选的模式有高精度、仅设备、仅网络,默认为高精度模式
  void setLocationMode(LocationMode locationMode) {
    if (locationMode == LocationMode.Hight_Accuracy) {
      this.locationMode = 1;
    } else if (locationMode == LocationMode.Device_Sensors) {
      this.locationMode = 2;
    } else if (locationMode == LocationMode.Battery_Saving) {
      this.locationMode = 3;
    }
  }

  /// 可选,设置场景定位参数,包括签到场景、运动场景、出行场景
  void setLocationPurpose(BDLocationPurpose locationPurpose) {
    if (locationPurpose == BDLocationPurpose.SignIn) {
      this.locationPurpose = 1;
    } else if (locationPurpose == BDLocationPurpose.Transport) {
      this.locationPurpose = 2;
    } else if (locationPurpose == BDLocationPurpose.Sport) {
      this.locationPurpose = 3;
    }
  }

  BaiduLocationAndroidOption(
      {this.coorType,
      this.isNeedAddres,
      this.isNeedAltitude,
      this.isNeedLocationPoiList,
      this.isNeedNewVersionRgc,
      this.openGps,
      this.isNeedLocationDescribe,
      this.scanspan,
      this.locationMode,
      this.locationPurpose});

  /// 根据传入的map生成BaiduLocationAndroidOption对象
  factory BaiduLocationAndroidOption.fromMap(dynamic value) {
    return new BaiduLocationAndroidOption(
      coorType: value['coorType'],
      isNeedAddres: value['isNeedAddres'],
      isNeedAltitude: value['isNeedAltitude'],
      isNeedLocationPoiList: value['isNeedLocationPoiList'],
      isNeedNewVersionRgc: value['isNeedNewVersionRgc'],
      openGps: value['openGps'],
      isNeedLocationDescribe: value[''],
      scanspan: value['scanspan'],
      locationMode: value['locationMode'],
      locationPurpose: value['LocationPurpose'],
    );
  }

  /// 获取对本类所有变量赋值后的map键值对
  Map getMap() {
    return {
      "coorType": coorType,
      "isNeedAddres": isNeedAddres,
      "isNeedAltitude": isNeedAltitude,
      "isNeedLocationPoiList": isNeedLocationPoiList,
      "isNeedNewVersionRgc": isNeedNewVersionRgc,
      "openGps": openGps,
      "isNeedLocationDescribe": isNeedLocationDescribe,
      "scanspan": scanspan,
      "locationMode": locationMode,
    };
  }
}

/// 定位模式枚举类
enum LocationMode {
  /// 高精度模式
  Hight_Accuracy,

  /// 低功耗模式
  Battery_Saving,

  /// 仅设备(Gps)模式
  Device_Sensors
}

/// 场景定位枚举类
enum BDLocationPurpose {
  ///  签到场景
  /// 只进行一次定位返回最接近真实位置的定位结果(定位速度可能会延迟1-3s)
  SignIn,

  /// 出行场景
  /// 高精度连续定位,适用于有户内外切换的场景,卫星定位和网络定位相互切换,卫星定位成功之后网络定位不再返回,卫星信号断开之后一段时间才会返回网络结果
  Sport,

  /// 运动场景
  /// 高精度连续定位,适用于有户内外切换的场景,卫星定位和网络定位相互切换,卫星定位成功之后网络定位不再返回,卫星信号断开之后一段时间才会返回网络结果
  Transport
}

  • ios 配置项 lib/entity/flutter_baidu_location_ios_option.dart
/// 设置ios端定位参数类
class BaiduLocationIOSOption {
  /// 设置位置获取超时时间
  int locationTimeout;

  /// 设置获取地址信息超时时间
  int reGeocodeTimeout;

  /// 设置应用位置类型
  String activityType;

  /// 设置返回位置的坐标系类型
  String BMKLocationCoordinateType;

  /// 设置预期精度参数
  String desiredAccuracy;

  /// 是否需要最新版本rgc数据
  bool isNeedNewVersionRgc;

  /// 指定定位是否会被系统自动暂停
  bool pausesLocationUpdatesAutomatically;

  /// 指定是否允许后台定位
  bool allowsBackgroundLocationUpdates;

  /// 设定定位的最小更新距离
  double distanceFilter;

  /// 指定是否允许后台定位
  /// allowsBackgroundLocationUpdates为true则允许后台定位
  /// allowsBackgroundLocationUpdates为false则不允许后台定位
  void setAllowsBackgroundLocationUpdates(
      bool allowsBackgroundLocationUpdates) {
    this.allowsBackgroundLocationUpdates = allowsBackgroundLocationUpdates;
  }

  /// 指定定位是否会被系统自动暂停
  /// pausesLocationUpdatesAutomatically为true则定位会被系统自动暂停
  /// pausesLocationUpdatesAutomatically为false则定位不会被系统自动暂停
  void setPauseLocUpdateAutomatically(bool pausesLocationUpdatesAutomatically) {
    this.pausesLocationUpdatesAutomatically =
        pausesLocationUpdatesAutomatically;
  }

  /// 设置位置获取超时时间
  void setLocationTimeout(int locationTimeout) {
    this.locationTimeout = locationTimeout;
  }

  /// 设置获取地址信息超时时间
  void setReGeocodeTimeout(int reGeocodeTimeout) {
    this.reGeocodeTimeout = reGeocodeTimeout;
  }

  /// 设置应用位置类型
  /// activityType可选值包括:
  /// "CLActivityTypeOther"
  /// "CLActivityTypeAutomotiveNavigation"
  /// "CLActivityTypeFitness"
  /// "CLActivityTypeOtherNavigation"
  void setActivityType(String activityType) {
    this.activityType = activityType;
  }

  /// 设置返回位置的坐标系类型
  /// BMKLocationCoordinateType可选值包括:
  /// "BMKLocationCoordinateTypeBMK09LL"
  /// "BMKLocationCoordinateTypeBMK09MC"
  /// "BMKLocationCoordinateTypeWGS84"
  /// "BMKLocationCoordinateTypeGCJ02"
  void setBMKLocationCoordinateType(String BMKLocationCoordinateType) {
    this.BMKLocationCoordinateType = BMKLocationCoordinateType;
  }

  /// 设置预期精度参数
  /// desiredAccuracy可选值包括:
  /// "kCLLocationAccuracyBest"
  /// "kCLLocationAccuracyNearestTenMeters"
  /// "kCLLocationAccuracyHundredMeters"
  /// "kCLLocationAccuracyKilometer"
  void setDesiredAccuracy(String desiredAccuracy) {
    this.desiredAccuracy = desiredAccuracy;
  }

  /// 设定定位的最小更新距离
  void setDistanceFilter(double distanceFilter) {
    this.distanceFilter = distanceFilter;
  }

  /// 是否需要最新版本rgc数据
  /// isNeedNewVersionRgc为true则需要返回最新版本rgc数据
  /// isNeedNewVersionRgc为false则不需要返回最新版本rgc数据
  void setIsNeedNewVersionRgc(bool isNeedNewVersionRgc) {
    this.isNeedNewVersionRgc = isNeedNewVersionRgc;
  }

  BaiduLocationIOSOption(
      {this.locationTimeout,
      this.reGeocodeTimeout,
      this.activityType,
      this.BMKLocationCoordinateType,
      this.desiredAccuracy,
      this.isNeedNewVersionRgc,
      this.pausesLocationUpdatesAutomatically,
      this.allowsBackgroundLocationUpdates,
      this.distanceFilter});

  /// 根据传入的map生成BaiduLocationIOSOption对象
  factory BaiduLocationIOSOption.fromMap(dynamic value) {
    return new BaiduLocationIOSOption(
      locationTimeout: value['locationTimeout'],
      reGeocodeTimeout: value['reGeocodeTimeout'],
      activityType: value['activityType'],
      BMKLocationCoordinateType: value['BMKLocationCoordinateType'],
      desiredAccuracy: value['desiredAccuracy'],
      isNeedNewVersionRgc: value['isNeedNewVersionRgc'],
      pausesLocationUpdatesAutomatically:
          value['pausesLocationUpdatesAutomatically'],
      allowsBackgroundLocationUpdates: value['allowsBackgroundLocationUpdates'],
      distanceFilter: value['distanceFilter'],
    );
  }

  /// 获取对本类所有变量赋值后的map键值对
  Map getMap() {
    return {
      "locationTimeout": locationTimeout,
      "reGeocodeTimeout": reGeocodeTimeout,
      "activityType": activityType,
      "BMKLocationCoordinateType": BMKLocationCoordinateType,
      "desiredAccuracy": desiredAccuracy,
      "isNeedNewVersionRgc": isNeedNewVersionRgc,
      "pausesLocationUpdatesAutomatically": pausesLocationUpdatesAutomatically,
      "allowsBackgroundLocationUpdates": allowsBackgroundLocationUpdates,
      "distanceFilter": distanceFilter,
    };
  }
}

  • 接口 lib/flutter_baidu_plugin_ducafecat.dart
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';

class FlutterBaiduPluginDucafecat {
  /// flutter端主动调用原生端方法
  static const Met
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值