flutter 高德地圖SDK 接入

本篇為flutter 項(xiàng)目集成高德地圖flutter插件,話不多說,直接上代碼

iOS 端

創(chuàng)建賬號(hào)

創(chuàng)建高德賬號(hào)流程我忘記截圖,也就不放了,十分簡(jiǎn)單,我的 demo 測(cè)試是個(gè)人賬號(hào),手機(jī)號(hào)注冊(cè),然后綁定下支付寶即可,企業(yè)賬號(hào)依據(jù)流程注冊(cè)



iOS 獲取 key 值流程十分簡(jiǎn)單(安卓注冊(cè) key 幺蛾子就多起來了,后面再說)

導(dǎo)入包

iOS 使用 map 和定位不需要在原生端導(dǎo)入,直接在 flutter中 pubspec.yaml中引入即可

# 高德地圖
  amap_flutter_map: ^3.0.0
  # 定位
  amap_flutter_location: ^3.0.0

但是我要注意提醒你們的是,這樣安裝的高德SDK 是包含 IDFA 的,不過說實(shí)話避免使用 idfa真的是太累人了,有太多SDK其實(shí)都用 idfa 了,OpenInstall,友盟,bugly,等等,我的建議是,還不如直接就聲明自己的 APP 使用了 idfa,這玩意兒現(xiàn)在習(xí)慣了我感覺用戶其實(shí)沒啥反感的,因?yàn)閹缀趺總€(gè) APP 都會(huì)彈這個(gè)請(qǐng)求彈窗.


配置權(quán)限

Xcode 打開iOS 下Runner.xcworkspace,右鍵info.plist選擇



把下面的內(nèi)容按自己的需求粘進(jìn)去即可,文案什么的,越詳細(xì)越好,說清楚自己拿這個(gè)權(quán)限想干啥,被拒過的人都懂

    <key>NSCameraUsageDescription</key>
    <string>請(qǐng)點(diǎn)擊“好”以允許訪問古戴。若不允許致燥,你將無(wú)法使用相機(jī)來拍照和視頻</string>
    <key>NSLocalNetworkUsageDescription</key>
    <string>此 APP 不會(huì)連接到您所用網(wǎng)絡(luò)上的設(shè)備琳彩,只會(huì)檢測(cè)與您本地網(wǎng)關(guān)的連通性</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>請(qǐng)點(diǎn)擊“允許”以允許訪問。 若不允許,你所在的城市將無(wú)法出現(xiàn)在你的動(dòng)態(tài)队他、個(gè)人主頁(yè)。</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>請(qǐng)點(diǎn)擊“允許”以允許訪問。 若不允許十绑,你所在的城市將無(wú)法出現(xiàn)在你的動(dòng)態(tài)、個(gè)人主頁(yè)酷勺。</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>請(qǐng)點(diǎn)擊“允許”以允許訪問本橙。 若不允許,你所在的城市將無(wú)法出現(xiàn)在你的動(dòng)態(tài)脆诉、個(gè)人主頁(yè)甚亭。</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>請(qǐng)點(diǎn)擊“好”以允許訪問贷币。若不允許,你將無(wú)法使用麥克風(fēng)錄制發(fā)送語(yǔ)音</string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>請(qǐng)點(diǎn)擊“好”以允許訪問亏狰。若不允許役纹,你將無(wú)法使用無(wú)法使用相冊(cè)照片發(fā)送消息、上傳頭像和發(fā)布動(dòng)態(tài)暇唾。</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>請(qǐng)點(diǎn)擊“好”以允許訪問促脉。若不允許,你將無(wú)法使用無(wú)法使用相冊(cè)照片發(fā)送消息策州、上傳頭像和發(fā)布動(dòng)態(tài)瘸味。</string>
    <key>UILaunchStoryboardName</key>
    <key>NSUserTrackingUsageDescription</key>
    <string>請(qǐng)放心, 愛泡炸無(wú)法獲取你在應(yīng)用內(nèi)的隱私,該權(quán)限僅用于標(biāo)識(shí)設(shè)備以保障服務(wù)安全與提升瀏覽體驗(yàn)</string>

業(yè)務(wù)代碼

業(yè)務(wù)代碼我沒有進(jìn)行封裝,直接在作為測(cè)試 demo 展示,也沒做什么動(dòng)畫的漸變啥的

import 'package:amap_flutter_map/amap_flutter_map.dart';
import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';

import 'package:flutter/material.dart';
import 'package:flutter_psd/common/utils/psdllog.dart';
import 'package:permission_handler/permission_handler.dart';

class GaodeMapPage extends StatefulWidget {
  const GaodeMapPage({Key? key}) : super(key: key);

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

class _GaodeMapPageState extends State<GaodeMapPage> {
  static const AMapApiKey amapApiKeys = AMapApiKey(
      iosKey: '9af9e11da0573c280a514f2f6372df5f',
      androidKey: 'eb909b4ee863e2bd0aa18098b7acc9ba');

  AMapController? mapController;
  AMapFlutterLocation? location;

  PermissionStatus? permissionStatus;
  CameraPosition? currentLocation;

  @override
  void initState() {
    super.initState();
    AMapFlutterLocation.setApiKey(
        "eb909b4ee863e2bd0aa18098b7acc9ba", "9af9e11da0573c280a514f2f6372df5f");
    AMapFlutterLocation.updatePrivacyAgree(true);
    AMapFlutterLocation.updatePrivacyShow(true, true);

    requestPermission();
  }

  Future<void> requestPermission() async {
    final status = await Permission.location.request();
    permissionStatus = status;
    switch (status) {
      case PermissionStatus.denied:
        psdllog("拒絕");
        break;
      case PermissionStatus.granted:
        requestLocation();
        break;
      case PermissionStatus.limited:
        psdllog("限制");
        break;
      default:
        psdllog("其他狀態(tài)");
        requestLocation();
        break;
    }
  }

  void requestLocation() {
    location = AMapFlutterLocation()
      ..setLocationOption(AMapLocationOption())
      ..onLocationChanged().listen((event) {
        psdllog(event);
        double? latitude = double.parse(event['latitude'] as String);
        double? longitude = double.parse(event['longitude'] as String);
        if (latitude != null && longitude != null) {
          setState(() {
            currentLocation = CameraPosition(
              target: LatLng(latitude, longitude),
              zoom: 10,
            );
          });
        }
      })
      ..startLocation();
  }

  @override
  void dispose() {
    location?.destroy();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "高德地圖",
          style: TextStyle(),
        ),
      ),
      body: currentLocation == null
          ? Container()
          : Center(
              child: SizedBox(
              child: AMapWidget(
                apiKey: amapApiKeys,
                // 初始化地圖中心店
                initialCameraPosition: currentLocation!,
                //定位小藍(lán)點(diǎn)
                myLocationStyleOptions: MyLocationStyleOptions(
                  true,
                ),
                // 普通地圖normal,衛(wèi)星地圖satellite,夜間視圖night,導(dǎo)航視圖 navi,公交視圖bus,
                mapType: MapType.normal,
                // 縮放級(jí)別范圍
                minMaxZoomPreference: MinMaxZoomPreference(3, 20),
                // 隱私政策包含高德 必須填寫
                privacyStatement: AMapPrivacyStatement(
                    hasAgree: true, hasContains: true, hasShow: true),
                // 地圖創(chuàng)建成功時(shí)返回AMapController
                onMapCreated: (AMapController controller) {
                  mapController = controller;
                },
              ),
            )),
    );
  }
}

代碼在上面,然后我講一些 iOS權(quán)限錯(cuò)誤還有和Android 通用的高德錯(cuò)誤.

  • 1.iOS雙定位權(quán)限
[MAMapKit] 要在iOS 11及以上版本使用定位服務(wù), 需要在Info.plist中添加NSLocationAlwaysAndWhenInUseUsageDescription和NSLocationWhenInUseUsageDescription字段。

這是兩個(gè)權(quán)限說明必須要全部配置,順便提一嘴,iOS 隱私權(quán)限不管你在哪用,進(jìn)入APP 第一時(shí)間就要彈出,定位權(quán)限沒有這個(gè)要求.

    1. permission_handler報(bào)錯(cuò)
* What went wrong:
Execution failed for task ':permission_handler:compileDebugJavaWithJavac'.


一開始以為是 flutter 版本問題(今天測(cè)試 demo的時(shí)候,看到有人說2.10.0版本的 flutter 有個(gè)系統(tǒng) bug),又看到有篇 stackoverflow 說升級(jí)版本就能解決這個(gè) bug,所以升級(jí)到了2.10.1,然而還是沒有解決.于是就去翻permission_handler的 issue,終于找到了,很幸運(yùn)的是
permission_handler的作者剛剛好在昨天解釋了這個(gè) bug地址戳這

我當(dāng)時(shí)使用的版本是7.* 升級(jí)后我就解決了這個(gè)問題

代碼說明

高德 flutter 文檔地址: 戳這兒
iOSbug少,基本按照文檔來即可,而且由于是中文文檔,看起來一點(diǎn)也不費(fèi)勁,這邊建議先獲取到定位后在展示地圖,這樣,直接能夠顯示到中心的小藍(lán)點(diǎn).

// 隱私政策包含高德 必須填寫
 privacyStatement: AMapPrivacyStatement(hasAgree: true, hasContains: true, hasShow: true),

定位的隱私政策也會(huì)一樣,不然直接拋異常,高德希望你在隱私網(wǎng)址中提到高德地圖的使用,正確合規(guī)的做法是在同意隱私政策的時(shí)候設(shè)置權(quán)限為 true
AMapFlutterLocation..updatePrivacyAgree(true)..updatePrivacyShow(true, true);

原生里的 key優(yōu)先級(jí)小于 Widget 代碼中.

定位中獲取的參數(shù)map 經(jīng)緯度為 string.

{locTime: 2022-02-11 21:51:03, province: 浙江省, callbackTime: 2022-02-11 21:51:03, district: 西湖區(qū), country: 中國(guó), street: ****, speed: -1.0, latitude: 30.287363, city: 杭州市, streetNumber: 177-1號(hào), bearing: -1.0, accuracy: 35.0, adCode: 330106, altitude: 11.046348571777344, locationType: 1, longitude: 120.128650, cityCode: 0571, address: 浙江省杭州市西湖區(qū)*****, description: 浙江省杭州市西湖區(qū)*****}

高德的 flutterAPI 接口提供的確實(shí)很少,甚至感覺有點(diǎn)簡(jiǎn)陋,其實(shí)這東西如果以后有精力的話,可以嘗試自己封裝一下,當(dāng)然安卓端我搞起來確實(shí)難度有點(diǎn)大,主要是要做好公共接口,做好channel 通信,剩下的就是各端的小伙伴去努力實(shí)現(xiàn)了,順便可以練練插件.高德源碼我也看了下,通道目前做的還不是太多,希望后面能豐富起來.


AMapController

效果展示

安卓端

安卓端配置真的是一言難盡,iOS 的過度順利導(dǎo)致我以為安卓端的兼容也十分簡(jiǎn)單,我感覺周五一下午的時(shí)間全用來 碰 bug 上了,下面敘述下我的血淚史
首先嘗試安卓模擬器運(yùn)行項(xiàng)目

  • 運(yùn)行,報(bào)錯(cuò)



    跟著改成31

  • 再運(yùn)行,再報(bào)錯(cuò),kotlin gradle 插件版本有問題



    修改根build.gradle

buildscript {
    ext.kotlin_version = '1.6.10'
    *****
}

運(yùn)行正常,進(jìn)入地圖界面的時(shí)候拋異常

  • java.lang.NoClassDefFoundError: Failed resolution of: Lcom/amap/api/location/AMapLocationClient;

很明顯,連類都找不到,一番查詢后,得知Android 需要手動(dòng)導(dǎo)入 sdk
在官方文檔中,我采用手動(dòng)拖入sdk+so


  • 再運(yùn)行,再報(bào)錯(cuò)errorCode: 10 *******請(qǐng)檢查AndroidManifest.xml文件是否配置了APSService定位服務(wù)
    AndroidManifest.xml增加
       <service android:name="com.amap.api.location.APSService"></service>
  • APSService標(biāo)紅
    網(wǎng)上查詢到app/build.gradle 下增加
dependencies {
//    implementation files('src/libs/AMap3DMap_AMapLocation/AMap3DMap_9.0.0_AMapLocation_5.6.2_20220113.jar')
    implementation('com.amap.api:location:5.2.0')
}

這里我一開始查到是手動(dòng)右鍵將 jar 包增加到library


但是報(bào)了一個(gè)什么錯(cuò)我忘記記錄了
然后我查了下,查到下面的寫法implementation('com.amap.api:location:5.2.0')目前不知道這兩者的區(qū)別
再運(yùn)行,在報(bào)錯(cuò)

  • errorCode: 12, errorInfo: 缺少定位權(quán)限 請(qǐng)到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/查看錯(cuò)誤碼說明,錯(cuò)誤詳細(xì)信息:定位權(quán)限被禁用,請(qǐng)授予應(yīng)用定位權(quán)限#1201#定位權(quán)限被禁用,請(qǐng)授予應(yīng)用定位權(quán)限#1201

  • errorInfo: WIFI信息不足 請(qǐng)到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/查看錯(cuò)誤碼說明,錯(cuò)誤詳細(xì)信息:當(dāng)前基站為偽基站够挂,并且搜到的WIFI數(shù)量不足旁仿,請(qǐng)移動(dòng)到WIFI比較豐富的區(qū)域#0202#當(dāng)前基站為偽基站,并且搜到的WIFI數(shù)量不足孽糖,請(qǐng)移動(dòng)到WIFI比較豐富的區(qū)域#0202}
    這兩個(gè)我后面換安卓真機(jī)運(yùn)行就消失了,應(yīng)該是項(xiàng)目重啟,或者 APP 卸載,或者 flutter clean , gradle clean 等等,上面的其他幾個(gè) bug 我有些有嘗試過清緩存解決,也許沒提到,但是大家心里要有個(gè)印象
    再運(yùn)行,再報(bào)錯(cuò)

  • Flutter multidex handling is disabled. If you wish to let the tool configure multidex, use the --mutidex flag.
    這個(gè)我請(qǐng)了清緩存,重啟下就好了

  • 再運(yùn)行,再報(bào)錯(cuò)



    其實(shí)到這兒,我心理已經(jīng)大概有點(diǎn)底了,項(xiàng)目可以正常運(yùn)行,只是定位無(wú)法提供,這里設(shè)計(jì)到 Android key 的創(chuàng)建,這里的出錯(cuò)應(yīng)該是我沒配好,其實(shí)最開始應(yīng)該要寫下如何創(chuàng)建 Android 的高德 key 的,后面補(bǔ)上,文章先寫到這,明兒再找時(shí)間調(diào)調(diào),然后把文章更新下,應(yīng)該只需要億點(diǎn)點(diǎn)時(shí)間.(主要是 bug 太多,再不寫我就忘記我遇到過哪些 bug 了)


2022-02-12 09:57:09 更新 Android真機(jī)高德地圖定位成功

昨天有個(gè) bug 是鑒權(quán)失敗導(dǎo)致定位失敗
我按照昨天最后高德給出的鑒權(quán)失敗流程一點(diǎn)點(diǎn)嘗試,并沒有解決,我懷疑我獲取的 key 并不是我注冊(cè)的 key,今天嘗試用另外一種方法解決

在創(chuàng)建 debug.storekey 成功后, 創(chuàng)建 key 的方法戳這,我采用高德提供的獲取 key 方式獲取cd ~/.android


然后將該 SHA1更新到高德 key 中
最后鑒權(quán)成功.

再運(yùn)行,成功獲取到坐標(biāo)


然而地圖黑屏了,僅顯示左下角一個(gè) logo, 控制臺(tái)打印報(bào)錯(cuò)



查了很多資料,最后懷疑是 so 文件導(dǎo)入出錯(cuò),高德給了兩種導(dǎo)入方法



在下載 sdk 的時(shí)候,高德附帶了各個(gè)平臺(tái)的 so 文件

我直接使用第一種方法,可能我導(dǎo)入的確實(shí)有點(diǎn)問題,并沒有成功,于是我改成第二種方法




順便提一下,對(duì)于 jar 包的引入,我還是改成了本地 jar 包

這是因?yàn)樵趪L試網(wǎng)上給出的implementation('com.amap.api:location:5.2.0')后,我發(fā)現(xiàn)報(bào)了一個(gè)找不到 MapView 啥的實(shí)現(xiàn)方法,推斷出'com.amap.api:location:5.2.0'只能實(shí)現(xiàn)高德location庫(kù)的方法,我想著還是用本地的 jar 包才對(duì),要不然放那就是白導(dǎo)入了.

運(yùn)行報(bào)錯(cuò)如果發(fā)現(xiàn)



可以嘗試增加


效果展示

最后的最后,安卓真機(jī)地圖的導(dǎo)入才算是結(jié)束了,最后展示下效果吧


PS

這次的安卓高德地圖的配置,感覺基本把能踩的全踩了個(gè)遍,也是因?yàn)樽约簩?duì)安卓系統(tǒng)不太熟,平時(shí)也常用 iOS 真機(jī)或者模擬器測(cè),也基本沒啥問題,昨天也痛定思痛,以后再也不搞 iOS 模擬器了,下了個(gè) momo,以后全部用安卓測(cè)代碼,
順便貼個(gè)momo模擬器 配置

system_profiler SPUSBDataType
復(fù)制ID/Vender ID到/.android/adb_usb.ini
adb kill-server
adb start-server
adb devices
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枯冈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子办悟,更是在濱河造成了極大的恐慌尘奏,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件病蛉,死亡現(xiàn)場(chǎng)離奇詭異罪既,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铡恕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門琢感,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人探熔,你說我怎么就攤上這事驹针。” “怎么了诀艰?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵柬甥,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我其垄,道長(zhǎng)苛蒲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任绿满,我火速辦了婚禮臂外,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己漏健,他們只是感情好嚎货,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蔫浆,像睡著了一般殖属。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓦盛,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天洗显,我揣著相機(jī)與錄音,去河邊找鬼原环。 笑死挠唆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扮念。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼碧库,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼柜与!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嵌灰,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤弄匕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后沽瞭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迁匠,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年驹溃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了城丧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡豌鹤,死狀恐怖亡哄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情布疙,我是刑警寧澤蚊惯,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站灵临,受9級(jí)特大地震影響截型,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜儒溉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一宦焦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦赶诊、人聲如沸笼平。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)寓调。三九已至,卻和暖如春锄码,著一層夾襖步出監(jiān)牢的瞬間夺英,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工滋捶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痛悯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓重窟,卻偏偏與公主長(zhǎng)得像载萌,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巡扇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容