flutter 集成百度地图(问题记录)
因为是安卓 苹果 鸿蒙项目,然后当前鸿蒙支持版本是next
所以兼容的版本很有限 记录下边版本都不行
# flutter_baidu_mapapi_map: ^3.9.0 # flutter_baidu_mapapi_base: ^3.9.0 ## flutter_bmflocation: any # flutter_baidu_mapapi_search: ^3.9.0 ## flutter_bmflocation: any # flutter_plugin_android_lifecycle: ^2.0.17 # flutter_baidu_mapapi_map: ^4.1.5 # flutter_baidu_mapapi_map: ^3.9.0 # flutter_baidu_mapapi_search: ^3.9.0 # flutter_baidu_mapapi_utils: ^3.9.0 # flutter_bmflocation: ^3.6.1
我用的版本是
flutter_baidu_mapapi_map: ^3.8.1 flutter_baidu_mapapi_search: ^3.8.1 flutter_baidu_mapapi_utils: ^3.8.1 flutter_bmflocation: ^3.6.0 flutter_baidu_mapapi_base: ^3.8.1
1.首先是需要我们设置Android端AK 我们要先获取 ak
1.根据官网
登录百度帐号
百度帐号是登录所有百度系产品的通行证,登录后还可以在帐户管理页管理/修改您的个人信息,包括修改密码、绑定手机、身份认证等
https://lbsyun.baidu.com/apiconsole/key#/home
点击创建运用 获取 发布版SHA1和 开发版SHA1
其中 : 发布版本的 :执行
cd .android
接着: 控制台输入 :
keytool -list -v -keystore debug.keystore
然后设置相关的密码(密码要记住后面的需要用到)
2.开发版SHA1:通过Keytool 生成 Android 签名文件
是通过这个获取签名以及生成 开发版SHA1 (不过有很多设置签名的 也有以 xxx.jks(jks路径)) 都是可以的,
就是执行命令 :
keytool -genkey -alias com.shen.mvpmagic -keyalg RSA -validity 200000 -keystore E:/mvpmagic.keystore
然后设置密码(这个也要记住)
将 获取到的 SHA1填入开发版SHA1
2.将获取到的 ak 复制,
插件:
flutter_baidu_mapapi_map: ^3.8.1 flutter_baidu_mapapi_search: ^3.8.1 flutter_baidu_mapapi_utils: ^3.8.1 flutter_bmflocation: ^3.6.0 flutter_baidu_mapapi_base: ^3.8.1 permission_handler: ^10.4.5
1. 设置Android端AK
在Android目录清单文件的application节点中设置Android端AK,添加如下代码:
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="开发者申请的AK" />
如果直接这样子运行会出错
遇到的第一个问题就是 构建失败 报错行 android {
这个解决办法就是 将 compileSdkVersion 版本改成 32
遇到的第二个问题就是 No signature of method: .android() is applicable for argument types. Exception in build.gradle (app)
将
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
//useProguard true <-- remove this line //这行去掉
proguardFiles getDefaultProguardFile('proguard-android.txt')
}
debug {
signingConfig signingConfigs.debug
}
}
在build.gradle 同级新建一个文件叫 proguard-rules.pro
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-keep class com.baidu.vi.** {*;}
-dontwarn com.baidu.**
整个 build.gradle 的格式就是
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 33
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "包名"
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
signingConfigs {
debug {
keyAlias '别名'
keyPassword '密码'
storeFile file('./signing/debug.keystore') //所放置的文件 在app下 与src同级
storePassword '与上面相通'
}
release {
keyAlias '别名'
keyPassword '密码'
storeFile file('./signing/mvpmagic.keystore')
storePassword '密码'
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.release
minifyEnabled true // 开启压缩
// useProguard true // 开启混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
之后就是在 AndroidManifest.xml添加权限
<!--允许获取精确位置,精准定位必选--> <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"/>
之后配置就到这里结束了
开始我们的代码
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart'; import 'package:flutter_baidu_mapapi_map/flutter_baidu_mapapi_map.dart'; import 'package:flutter_bmflocation/flutter_bmflocation.dart'; import 'package:permission_handler/permission_handler.dart'; class OnePosition extends StatefulWidget { const OnePosition({Key? key}) : super(key: key); @override State<OnePosition> createState() => _OnePositionState(); } class _OnePositionState extends State<OnePosition> { final LocationFlutterPlugin _myLocPlugin = LocationFlutterPlugin(); Map result = {}; @override void initState() { // TODO: implement initState super.initState(); requestPermission(); /// 设置用户是否同意SDK隐私协议 /// since 3.1.0 开发者必须设置 BMFMapSDK.setAgreePrivacy(true); _myLocPlugin.setAgreePrivacy(true); // 百度地图sdk初始化鉴权 if (Platform.isIOS) { _myLocPlugin.authAK('请在此输入您在开放平台上申请的API_KEY'); BMFMapSDK.setApiKeyAndCoordType( '请在此输入您在开放平台上申请的API_KEY', BMF_COORD_TYPE.BD09LL); } else if (Platform.isAndroid) { // Android 目前不支持接口设置Apikey, // 请在主工程的Manifest文件里设置,详细配置方法请参考官网(https://lbsyun.baidu.com/)demo BMFMapSDK.setCoordType(BMF_COORD_TYPE.BD09LL); } locationAction(); ///接受定位回调 _myLocPlugin.seriesLocationCallback(callback: (BaiduLocation result) { setState(() { print("连续定位会低矮111111"); print(result); // updateUserLocation(result); print(result.getMap()); this.result = result.getMap(); print("大运"); }); }); } void locationAction() async { /// 设置android端和ios端定位参数 /// android 端设置定位参数 /// ios 端设置定位参数 Map iosMap = _initIOSOptions().getMap(); Map androidMap = _initAndroidOptions().getMap(); await _myLocPlugin.prepareLoc(androidMap, iosMap); } // 动态申请定位权限 void requestPermission() async { // 申请权限 bool hasLocationPermission = await requestLocationPermission(); if (hasLocationPermission) { // 权限申请通过 } else {} } /// 申请定位权限 /// 授予定位权限返回true, 否则返回false 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; } } } /// 设置地图参数 BaiduLocationAndroidOption _initAndroidOptions() { BaiduLocationAndroidOption options = BaiduLocationAndroidOption( locationMode: BMFLocationMode.hightAccuracy, isNeedAddress: true, isNeedAltitude: true, isNeedLocationPoiList: true, isNeedNewVersionRgc: true, isNeedLocationDescribe: true, openGps: true, scanspan: 4000, //这里如果设置为 0 就是单次定位 coordType: BMFLocationCoordType.bd09ll); return options; } BaiduLocationIOSOption _initIOSOptions() { BaiduLocationIOSOption options = BaiduLocationIOSOption( coordType: BMFLocationCoordType.bd09ll, desiredAccuracy: BMFDesiredAccuracy.best, allowsBackgroundLocationUpdates: true, pausesLocationUpdatesAutomatically: false); return options; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("定位"), ), body: Stack( children: [ Positioned( top: 0, left: 0, child: InkWell( onTap: () { print("停止经党委"); // _stopLocation(); _myLocPlugin.stopLocation(); setState(() { result = {}; }); }, child: Container( height: 100, width: 100, color: Colors.pink, ), )), Positioned( top: 0, right: 0, child: InkWell( onTap: () { print("开始定位"); _myLocPlugin.startLocation(); }, child: Container( height: 100, width: 100, color: Colors.pink, ), )), Positioned( top: 100, left: 0, right: 0, child: Container( color: Colors.amber[100], child: Text("${result}"), )) ], ), ); } }
之后就成功了
I/flutter (31519): {town: 高新区街道, course: -1.0, speed: 0.0, locationID: -KOp4q22rqC_qqC5o6jNpret-_vrrYa4oKDp5J63n-eDqafUqaqrrKml0YPQo4LQw86f7u3Ku8izx8GNv_O2zem8trmlvrygvrWl5rS74bWhqvfIVDzs9f.., locTime: 2025-03-13 16:35:28, locType: 161, radius: 92.7, latitude: 39.693595, longitude: 118.179512, altitude: null, country: 中国, province: 河北省, city: 唐山市, district: 路北区, street: 科维街, adCode: 130203, cityCode: 265, streetNumber: null, address: 中国河北省唐山市路北区高新区街道科维街, verticalAccuracy: null, horizontalAccuracy: null, locationDetail: 在世纪瑞庭呈润里南区附近, poiList: 世纪瑞庭呈润里南区,房地产;住宅区唐山市路北区荣华西道星河湾小学东侧约110米|呈通里星河湾,房地产唐山市路北区荣华西道与华岩北路交叉路口往西约100米(星河公馆)|庆南道派出所,政府机构;行政单位河北省唐山市路北区高新区呈润里星河湾301号楼旁边|瑾菡超市,购物;超市唐山市路北区建设北路�