Flutter集成高德导航SDK(Android篇)(JAVA语法)

先上flutter doctor:
flutter sdk版本为:3.19.4
在这里插入图片描述

引入依赖:
在app的build.gradle下,添加如下依赖:

    implementation 'com.amap.api:navi-3dmap:10.0.700_3dmap10.0.700'

navi-3dmap里面包含了定位功能,地图功能,所以引入这一个包就行

1.在项目的android-app-src-包名 路径下,新建一个class,起名为:AMapNaviPlugin,
AMapNaviPlugin代码如下:

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.view.View;import androidx.annotation.NonNull;import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Poi;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AmapNaviPage;
import com.amap.api.navi.AmapNaviParams;
import com.amap.api.navi.AmapNaviType;
import com.amap.api.navi.AmapPageType;
import com.amap.api.navi.INaviInfoCallback;
import com.amap.api.navi.NaviSetting;
import com.amap.api.navi.model.AMapNaviLocation;import java.util.HashMap;
import java.util.Map;import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;public class AMapNaviPlugin implements FlutterPlugin, MethodChannel.MethodCallHandler, ActivityAware {private static MethodChannel channel;private static Context mContext = null;//通讯名称,回到手机桌面private static String CHANNEL = "com.kdcf.channel/aMapNavi";private Activity activity;@Overridepublic void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {if (null == mContext) {mContext = binding.getApplicationContext();}initMethodChannel(binding.getBinaryMessenger());}private void initMethodChannel(BinaryMessenger binaryMessenger) {if (null == binaryMessenger) {return;}channel = new MethodChannel(binaryMessenger, CHANNEL);channel.setMethodCallHandler(this);}@Overridepublic void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {channel.setMethodCallHandler(null);channel = null;}@Overridepublic void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {if (mContext == null) {result.error("-1", "context is null", null);}if (call.method.equals(NaviConstant.START_NAVI)) {try {Object arguments = call.arguments;Map<String,Object> map= (Map<String, Object>) arguments;Double endLongitude= (Double) map.get("endLongitude");Double endLatitude= (Double) map.get("endLatitude");String endPlaceName= (String) map.get("endPlaceName");String endPoiId= (String) map.get("endPoiId");Map<String,Object> extraParams= (Map<String, Object>) map.get("extraParams");Log.e("AMapNaviPlugin","endLongitude:"+endLongitude);Log.e("AMapNaviPlugin","endLatitude:"+endLatitude);Log.e("AMapNaviPlugin","endPlaceName:"+endPlaceName);Log.e("AMapNaviPlugin","endPoiId:"+endPoiId);Log.e("AMapNaviPlugin","extraParams参数如下:");for (Map.Entry<String, Object> entry : extraParams.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}startNavi(endLongitude,endLatitude,endPlaceName,endPoiId,extraParams);} catch (Exception e) {Log.e("AMapNaviPlugin","异常:"+e.toString());result.error("ERROR","AMapNaviPlugin onMethodCall startNavi出错:"+e.toString(),null);}result.success(200);}else if (call.method.equals(NaviConstant.AGREE_PRIVACY)) {try {NaviSetting.updatePrivacyShow(mContext, true, true);NaviSetting.updatePrivacyAgree(mContext, true);} catch (Exception e) {Log.e("AMapNaviPlugin",e.toString());result.error("ERROR","AMapNaviPlugin onMethodCall agreePrivacy出错:"+e.toString(),null);}result.success(200);}else if (call.method.equals(NaviConstant.CANCEL_NAVI)) {try {AMapNavi.getInstance(mContext).playTTS("导航已结束",true);//退出导航组件Handler handler = new Handler();handler.postDelayed(new Runnable() {@Overridepublic void run() {// 这里是延时后需要执行的代码//退出导航组件AmapNaviPage.getInstance().exitRouteActivity();}}, 5000);} catch (Exception e) {Log.e("AMapNaviPlugin",e.toString());result.error("ERROR","AMapNaviPlugin onMethodCall CANCEL_NAVI出错:"+e.toString(),null);}result.success(200);}}@Overridepublic void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {activity = binding.getActivity();}@Overridepublic void onDetachedFromActivityForConfigChanges() {}@Overridepublic void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {}@Overridepublic void onDetachedFromActivity() {}void startNavi(Double endLongitude,Double endLatitude,String endPlaceName,String endPoiId,Map<String,Object> extraParams){//起点
//        Poi start = new Poi("北京首都机场", new LatLng(40.080525,116.603039), "B000A28DAE");
//途经点
//        List<Poi> poiList = new ArrayList();
//        poiList.add(new Poi("故宫", new LatLng(39.918058,116.397026), "B000A8UIN8"));
//终点Poi end = new Poi(endPlaceName, new LatLng(endLatitude,endLongitude),endPoiId);
// 组件参数配置AmapNaviParams params = new AmapNaviParams(null, null, end, AmapNaviType.DRIVER, AmapPageType.NAVI);
// 启动组件AmapNaviPage.getInstance().showRouteActivity(mContext.getApplicationContext(), params, new NaviInfoCallback(mContext,channel,extraParams));}
}

新建NaviConstant类,代码如下:

public class NaviConstant {//开始导航,flutter向原生传值public static String START_NAVI="startNavi";//同意隐私政策,flutter向原生传值public static String AGREE_PRIVACY="agreePrivacy";//到达目的地,原生向flutter传值public static String ARRIVE_Destination="arriveDestination";//取消导航public static String CANCEL_NAVI="cancelNavi";
}

新建NaviInfoCallback类,代码如下:

package com.daohe.kdchufadriver.navi;import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.view.View;import com.amap.api.navi.INaviInfoCallback;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.AmapNaviPage;import java.util.HashMap;
import java.util.Map;import io.flutter.plugin.common.MethodChannel;public class NaviInfoCallback implements INaviInfoCallback {Context context;MethodChannel channel;Map<String,Object> extraParams;public NaviInfoCallback(Context context,MethodChannel channel,Map<String,Object> extraParams) {this.context=context;this.channel=channel;this.extraParams=extraParams;}@Overridepublic void onInitNaviFailure() {Log.e("NaviInfoCallback","onInitNaviFailure");}@Overridepublic void onGetNavigationText(String s) {Log.e("onGetNavigationText","onGetNavigationText:"+s);// //模拟到达终点
//        Map<String,Object> result=new HashMap<>();
//        result.put("result",extraParams);
//        channel.invokeMethod(NaviConstant.ARRIVE_Destination,result);
//        //退出导航组件
//        Handler handler = new Handler();
//        handler.postDelayed(new Runnable() {
//            @Override
//            public void run() {
//                // 这里是延时后需要执行的代码
//                //退出导航组件
//                AmapNaviPage.getInstance().exitRouteActivity();
//            }
//        }, 5000);}@Overridepublic void onLocationChange(AMapNaviLocation aMapNaviLocation) {Log.e("onGetNavigationText","onLocationChange");}//isEmulaterNavi - true代表是模拟导航到达目的地,false代表实时导航到达目的地@Overridepublic void onArriveDestination(boolean isEmulaterNavi) {Map<String,Object> result=new HashMap<>();result.put("result",extraParams);channel.invokeMethod(NaviConstant.ARRIVE_Destination,result);//退出导航组件Handler handler = new Handler();handler.postDelayed(new Runnable() {@Overridepublic void run() {// 这里是延时后需要执行的代码//退出导航组件AmapNaviPage.getInstance().exitRouteActivity();}}, 5000);}@Overridepublic void onStartNavi(int i) {Log.e("onGetNavigationText","onStartNavi "+String.valueOf(i));}@Overridepublic void onCalculateRouteSuccess(int[] ints) {Log.e("onGetNavigationText","onCalculateRouteSuccess "+String.valueOf(ints));}@Overridepublic void onCalculateRouteFailure(int i) {Log.e("onGetNavigationText","onCalculateRouteFailure "+String.valueOf(i));}@Overridepublic void onStopSpeaking() {Log.e("onGetNavigationText","onStopSpeaking");}@Overridepublic void onReCalculateRoute(int i) {Log.e("onGetNavigationText","onReCalculateRoute "+String.valueOf(i));}@Overridepublic void onExitPage(int i) {Log.e("onGetNavigationText","onExitPage "+String.valueOf(i));}@Overridepublic void onStrategyChanged(int i) {Log.e("onGetNavigationText","onStrategyChanged "+String.valueOf(i));}@Overridepublic void onArrivedWayPoint(int i) {Log.e("onGetNavigationText","onArrivedWayPoint "+String.valueOf(i));}@Overridepublic void onMapTypeChanged(int i) {Log.e("onGetNavigationText","onMapTypeChanged "+String.valueOf(i));}@Overridepublic void onNaviDirectionChanged(int i) {Log.e("onGetNavigationText","onNaviDirectionChanged "+String.valueOf(i));}@Overridepublic void onDayAndNightModeChanged(int i) {Log.e("onGetNavigationText","onDayAndNightModeChanged "+String.valueOf(i));}@Overridepublic void onBroadcastModeChanged(int i) {Log.e("onGetNavigationText","onBroadcastModeChanged "+String.valueOf(i));}@Overridepublic void onScaleAutoChanged(boolean b) {Log.e("onGetNavigationText","onScaleAutoChanged "+b);}@Overridepublic View getCustomMiddleView() {return null;}@Overridepublic View getCustomNaviView() {return null;}@Overridepublic View getCustomNaviBottomView() {return null;}
}

android端的代码到这里就完了

下面是Flutter端的代码

在Flutter新建dart文件,起名amap_navi_plugin.dart
代码如下:

import 'dart:convert';import 'package:flutter/services.dart';
import 'package:flutter/material.dart';//司机到达目的地附近的回调
typedef OnArriveCallBack=void Function(dynamic params);
//高德导航插件
class AMapNaviPlugin {//开始导航static const START_NAVI="startNavi";//同意隐私政策static const AGREE_PRIVACY="agreePrivacy";//到达目的地给flutter回调static const ARRIVE_Destination="arriveDestination";//取消导航static const CANCEL_NAVI="cancelNavi";//初始化通信管道static const String CHANNEL = "com.kdcf.channel/aMapNavi";static const platform = MethodChannel(CHANNEL);//开始导航//参数目的地经度、纬度、地点名称static Future<void> startAmapNavi(double endLongitude,double endLatitude,String endPlaceName,String poiId,Map extraParams) async {//通知安卓返回,到手机桌面try {Map map=Map();map['endLongitude']=endLongitude;map['endLatitude']=endLatitude;map['endPlaceName']=endPlaceName;map['extraParams']=extraParams;map['endPoiId']=poiId;// map['endLongitude']=103.85741;// map['endLatitude']=36.05407;// map['endPoiId']='';final dynamic result = await platform.invokeMethod(START_NAVI,map);if (result==200) {debugPrint("导航成功");}} on PlatformException catch (e) {debugPrint("通信失败 AMapNaviPlugin startAmapNavi:失败 ${e.toString()}");print(e.toString());}catch(e){debugPrint("导航失败:${e.toString()}");}}static void agreePrivacy() async {//通知安卓返回,到手机桌面try {final int result=await platform.invokeMethod(AGREE_PRIVACY);if (result==200) {debugPrint("同意导航隐私政策成功");}} on PlatformException catch (e) {debugPrint("通信失败 AMapNaviPlugin agreePrivacy:失败 ${e.toString()}");print(e.toString());}catch(e){debugPrint("同意导航隐私政策失败:${e.toString()}");}}//原生往flutter发消息,导航快到目的地的时候static void arriveDestination(OnArriveCallBack onArriveCallBack) async {//通知安卓返回,到手机桌面try {Future<dynamic> handler(MethodCall call) async {debugPrint("flutter收到消息:arriveDestination");switch (call.method) {case ARRIVE_Destination:Map result=call.arguments;debugPrint("ARRIVE_Destination参数:"+jsonEncode(result));onArriveCallBack(result);break;}}platform.setMethodCallHandler((call) => handler(call));} on PlatformException catch (e) {debugPrint("通信失败 AMapNaviPlugin arriveDestination:失败 ${e.toString()}");print(e.toString());}catch(e){debugPrint("arriveDestination失败:${e.toString()}");}}//flutter往原生发消息,取消订单的时候 取消导航static void cancelNavi() async {//通知安卓返回,到手机桌面try {final int result=await platform.invokeMethod(CANCEL_NAVI);if (result==200) {debugPrint("取消导航成功");}} on PlatformException catch (e) {debugPrint("通信失败 AMapNaviPlugin cancelNavi:失败 ${e.toString()}");print(e.toString());}catch(e){debugPrint("取消导航失败:${e.toString()}");}}}

最后,使用方法

AMapNaviPlugin.startAmapNavi(longitude,latitude,destinationTitle,poiId,extraParams);

longitude为终点经度,latitude为终点纬度,destinationTitle为目的地的汉字名称,比如北京XXXX。poiId可以不传,extraParams可以不传。

最后,附上一个运行视频:

Flutter集成高德导航Android端插件

以后还会完成的相关文章如下:

目前本人已完成项目里面以下技术的实现,但是还没时间写博客,工作太忙了,以后会完善。。。待续。。。

1. Flutter集成高德导航SDK(IOS篇)(OC语法)
2. Flutter集成高德导航SDK并且自定义导航UI页面(Android篇)(JAVA语法)
3. Flutter集成高德导航SDK并且自定义导航UI页面(IOS篇)(OC语法)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/866512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

香橙派AIpro开发板评测:部署yolov5模型实现图像和视频中物体的识别

OrangePi AIpro 作为业界首款基于昇腾深度研发的AI开发板&#xff0c;自发布以来就引起了我的极大关注。其配备的8/20TOPS澎湃算力&#xff0c;堪称目前开发板市场中的顶尖性能&#xff0c;实在令人垂涎三尺。如此强大的板子&#xff0c;当然要亲自体验一番。今天非常荣幸地拿到…

边界无限陈佩文:红蓝对抗安全演练常态化的各方分析

虽然常态化演练尚未正式开始&#xff0c;但我们仍然希望对各方的表现进行一些分析和预测&#xff0c;以辅助我们对市场的判断和决策。同时&#xff0c;也希望通过这些初步的见解&#xff0c;抛砖引玉&#xff0c;引发更多有价值的讨论和观点。 “船停在码头是最安全的&#xf…

Hi3861 OpenHarmony嵌入式应用入门--SNTP

sntp&#xff08;Simple Network Time Protocol&#xff09;是一种网络时间协议&#xff0c;它是NTP&#xff08;Network Time Protocol&#xff09;的一个简化版本。 本项目是从LwIP中抽取的SNTP代码&#xff1b; Hi3861 SDK中已经包含了一份预编译的lwip&#xff0c;但没有…

线程间的通信

文章目录 线程间的通讯技术就是通过等待和唤醒机制&#xff0c;来实现多个线程协同操作完成某一项任务&#xff0c;例如经典的生产者和消费者案例。等待唤醒机制其实就是让线程进入等待状态或者让线程从等待状态中唤醒&#xff0c;需要用到两种方法&#xff0c;如下&#xff1a…

红蓝对抗下的内网横向移动渗透技术详解

一、利用Windows计划任务横向移动 Windows计划任务是一个非常实用的功能&#xff0c;可以帮助我们自动完成一些重复性的任务。比如&#xff0c;我们可以设定一个计划任务来自动备份文件、更新软件、执行脚本等,本文主要介绍了如何利用Windows计划任务进行横向渗透。 &#xf…

C#委托事件的实现

1、事件 在C#中事件是一种特殊的委托类型&#xff0c;用于在对象之间提供一种基于观察者模式的通知机制。 1.1、事件的发送方定义了一个委托&#xff0c;委托类型的声明包含了事件的签名&#xff0c;即事件处理器方法的签名。 1.2、事件的订阅者可以通过运算符来注册事件处理器…

Python基础小知识问答系列-过滤列表元素

1. 问题&#xff1a; 如何根据单一条件过滤列表的元素&#xff1f; 如何根据复杂条件过滤列表的元素&#xff1f; 2. 解决方式&#xff1a; 可以使用推导式生成器&#xff0c;进行单一条件的列表元素过滤&#xff0c;尤其是列表内容较多时; 也可以使用filter函数进行列…

Linux Static Keys和jump label机制

文章目录 前言一、asm goto二、API使用2.1 低版本API2.2 高版本API 三、jump label四、源码分析4.1 数据结构4.2 static_key_false4.3 jump_label_init4.4 __jump_label_transform4.5 static_key_slow_inc/dec 五、__jump_table节5.1 内核5.2 内核模块 六、修改内存代码6.1 x86…

24西安电子科技大学数学与统计学院—考研录取情况

24西安电子科技大学—数学与统计学院—考研录取统计 01、数学与统计学院各个方向 02、24数学与统计学院近三年复试分数线对比 数统院24年院线相对于23年院线增加高达30分&#xff0c;确实增长浮动比较高&#xff0c;接近30分的水平&#xff0c;因此大家更需要好好去努力&#x…

GTest和Catch2单元测试学习(附Cmake测试代码库)

kevin_CTest CTest 单元测试学习 Gitee库&#xff1a; https://gitee.com/bigearrabbit/kevin_ctest.git 示例多是从网页文章上摘取的&#xff0c;大部分记录在下面&#xff0c;或者源码内。供学习参考。 CTest 学习Catch2 框架 单个文档的测试架构&#xff0c;使用方便&am…

vue3中svg图标的封装与使用

组件封装&#xff1a; <template><svg :class"svgClass" :style"{ width: size px, height: size px, color: color, verticalAlign:deviationem}" aria-hidden"true"><use :xlink:href"#icon-${name}" /></s…

FreeRTOS的任务间通信

文章目录 4 FreeRTOS任务间通信4.1 队列4.1.1 队列的使用4.1.2 队列的创建&#xff0c;删除&#xff0c;复位4.1.3 队列的发送&#xff0c;接收&#xff0c;查询 4.2 邮箱&#xff08;mailbox&#xff09;4.2.1 任务中读写邮箱4.2.2 中断中读写邮箱 4.3 队列集4.3.1 队列集的创…

Vue打包文件dist放在SpringBoot项目下运行(正确实现全过程)

项目开发中&#xff0c;一般我们都会使用SpringBootVue进行前后端开发。 在部署时&#xff0c;会后端启动一个服务&#xff0c;再启动一个nginx&#xff0c;nginx中配置前端打包文件dist进行项目访问。 实际上&#xff0c;我们也可以把打包好的dist目录放在SpringBoot项目下进…

Os-hackNos

下载地址 https://download.vulnhub.com/hacknos/Os-hackNos-1.ova 环境配置如果出现&#xff0c;扫描不到IP的情况&#xff0c;可以尝试vulnhub靶机检测不到IP地址解决办法_vulnhub靶机扫描不到ip-CSDN博客 信息收集 确定靶机地址&#xff1a; 探测到存活主机192.168.111.…

如何利用AI撰写短文案获客?分享6大平台和3大步骤!

从去年开始&#xff0c;很多大厂都在裁员&#xff0c;原因就是因为AI的火爆&#xff0c;替代了很多机械式的劳动力。以前很多人可以通过机械式的工作来摸鱼&#xff0c;现在AI完成的效率比人工的要高很多倍。 国内好用的AI平台非常多&#xff0c;有时候也可以使用几个AI平台结合…

软件设计之Java入门视频(11)

软件设计之Java入门视频(11) 视频教程来自B站尚硅谷&#xff1a; 尚硅谷Java入门视频教程&#xff0c;宋红康java基础视频 相关文件资料&#xff08;百度网盘&#xff09; 提取密码&#xff1a;8op3 idea 下载可以关注 软件管家 公众号 学习内容&#xff1a; 该视频共分为1-7…

STM32学习历程(day2)

GPIO解释 GPIO(General-purpose input/output) 可以配置为八种输入输出模式 引脚电平 0V-3.3V 部分引脚可容忍5v 输出模式可控制端口输出高低电平 用以驱动LED、控制蜂鸣器、模拟通信协议输出时序 输入模式可读取端口的高低电平或电压&#xff0c;用于读取按键输入、外界…

uniapp自定义富文本现实组件(支持查看和收起)

废话不多说上代码 CollapseText.vue <template><view v-if"descr"><scroll-view class"collapse-text" :style"{maxHeight: computedMaxHeight}"><!-- <slot></slot> --><rich-text :nodes"descr&q…

2-网页请求的原理

网页请求的原理 ​ 网络爬虫请求网页的过程可以理解为用户使用浏览器加载网页的过程&#xff0c;这个过程其实是向Web服务器发送请求的过程&#xff0c;即浏览器向Web服务器发送请求&#xff0c;Web服务器会将响应内容以网页形式返回给浏览器。因此&#xff0c;了解浏览器与We…

Android Studio下载Gradle特别慢,甚至超时,失败。。。解决方法

使用Android studio下载或更新gradle时超级慢怎么办&#xff1f; 切换服务器&#xff0c;立马解决。打开gradle配置文件 修改服务器路径 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-7.3.3-bin.zip 最后&#xff0c;同步&#xff0c;下载&#xff0c;速…