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.rhkb.cn/news/371419.html

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

相关文章

计数排序的实现

原理 对一个数组进行遍历&#xff0c;再创建一个count数组 每找到一个值则在count数组中对应的位置加一&#xff0c;再在count数组中找到数字上方的count值&#xff0c;count值为几&#xff0c;则打印几次数组中的值. 开空间 相对映射 排序的实现 void CountSort(int* a, i…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【明文导入密钥(C/C++)】

明文导入密钥(C/C) 以明文导入ECC密钥为例。具体的场景介绍及支持的算法规格 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 指定密钥别名keyAlias。 密钥别名的最大长度为64字节。 封装密钥属性集和密钥材料。通过[OH_Huks_I…

读人工智能全传05专家系统

1. 知识就是力量 1.1. 人工智能领域此前存在的问题是过度关注搜索和解决问题这种通用法则 1.2. “弱”方法缺少一个关键的要素&#xff0c;而这一要素才是在所有智能行为中起决定性作用的组成部分&#xff1a;知识 1.3. 一种基于知识的人工智能系统&#xff1a;专家系统开始…

weblogic加入第三方数据库代理驱动jar包(Oracle为例)

做的是国企项目&#xff0c;项目本身业务并不复杂&#xff0c;最复杂的却是服务器部署问题&#xff0c;对方给提供的服务器分内网、外网交换网&#xff0c;应用在交换网&#xff0c;数据库在内网&#xff0c;应用不能直接访问内网数据库&#xff0c;只能通过安全隔离网闸访问内…

Python爬虫与数据可视化:构建完整的数据采集与分析流程

Python爬虫技术概述 Python爬虫是一种自动化的数据采集工具&#xff0c;它可以模拟浏览器行为&#xff0c;访问网页并提取所需信息。Python爬虫的实现通常涉及以下几个步骤&#xff1a; 发送网页请求&#xff1a;使用requests库向目标网站发送HTTP请求。获取网页内容&#xf…

进入防火墙Web管理页面(eNSP USG6000V)和管理员模块

1、进入防火墙Web管理页面 USG系列是华为提供的一款高端防火墙产品&#xff0c;其特点在于提供强大的安全防护能力和灵活的扩展性。 以eNSP中的USG6000为例&#xff1a; MGMT口&#xff08;web管理口&#xff09;&#xff1a;对应设备上的G0/0/0口&#xff0c;上面初始配有一…

张量分解(2)——张量运算(内积、外积、直积、范数)

&#x1f345; 写在前面 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;这里是hyk写算法了吗&#xff0c;一枚致力于学习算法和人工智能领域的小菜鸟。 &#x1f50e;个人主页&#xff1a;主页链接&#xff08;欢迎各位大佬光临指导&#xff09; ⭐️近…

Linux:DHCP服务配置

目录 一、DHCP概述以及DHCP的好处 1.1、概述 1.2、DHCP的好处 二、DHCP的模式与分配方式 2.1、模式 2.2、DHCP的分配方式 三、DHCP工作原理 四、安装DHCP服务 五、DHCP局部配置并且测试 5.1、subnet 网段声明 5.2、客户机预留指定的固定ip地址 一、DHCP概述以及DHCP…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【21】【购物车】

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【21】【购物车】 购物车需求描述购物车数据结构数据Model抽取实现流程&#xff08;参照京东&#xff09;代码实现参考 购物车需求描述 用户可以在登录状态下将商品添加到购物车【用户购物…

归并排序的实现(递归与非递归)

概念 基本思想&#xff1a;归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使…

Java多线程不会?一文解决——

方法一 新建类如MyThread继承Thread类重写run()方法再通过new MyThread类来新建线程通过start方法启动新线程 案例&#xff1a; class MyThread extends Thread {public MyThread(String name) {super(name);}Overridepublic void run() {for(int i0;i<10;i){System.out.…

【qt】TCP 服务端怎么收到信息?

上一节,我已经讲了,TCP的监听,是基于上一节的,不知道的可以看看. 当我们的TCP 服务器 有 客户端请求连接的时候,会发出一个信号newConnection(). 在TCP服务端与客户端的通信中,我们需要使用到套接字 QTcpSocket类. 套接字相当于是网络通信的接口,服务段和客户端都要通过它进行通…

STM32-SPI和W25Q64

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. SPI&#xff08;串行外设接口&#xff09;通信1.1 SPI通信简介1.2 硬件电路1.3 移位示意图1.4 SPI时序基本单元1.5 SPI时序1.5.1 发送指令1.5.2 指定地址写1.5.3 指定地址读 2. W25Q642.1 W25Q64简介2.2 硬件电路2…

MATLAB常用语句总结7

MATLAB总结7&#xff1a;常见错误归纳 本篇专门用于记录一些应试技巧 文章目录 MATLAB总结7&#xff1a;常见错误归纳前言一、一些小定义和小技巧二、蒙塔卡罗求解方法1.函数的定义2.函数引用3.代码量较少的蒙塔卡罗 三、函数引用与多变量四、矩阵引用五、非线性函数&#xff…

二叉树的链式存储

目录 链式存储&#xff1a; 简介&#xff1a; 二叉树链式存储的模拟实现&#xff1a; 节点的定义&#xff1a; ​编辑 链式二叉树的创建&#xff1a; 前序构建&#xff1a; 中序构建&#xff1a; 后续构建&#xff1a; 链式二叉树的销毁&#xff1a; 链式二叉树求节点…

algorithm算法库学习之——不修改序列的操作

algorithm此头文件是算法库的一部分。本篇介绍不修改序列的操作函数。 不修改序列的操作 all_ofany_ofnone_of (C11)(C11)(C11) 检查谓词是否对范围中所有、任一或无元素为 true (函数模板) for_each 应用函数到范围中的元素 (函数模板) for_each_n (C17) 应用一个函数对象到序…

Raw Socket(一)实现TCP三次握手

实验环境&#xff1a; Windows物理机&#xff1a;192.168.1.4 WSL Ubuntu 20.04.6 LTS&#xff1a;172.19.32.196 Windows下的一个http服务器&#xff1a;HFS&#xff0c;大概长这个样子&#xff1a; 客户端就是Ubuntu&#xff0c;服务端就是这个…

【Spring AOP 源码解析前篇】什么是 AOP | 通知类型 | 切点表达式| AOP 如何使用

前言&#xff08;关于源码航行&#xff09; 在准备面试和学习的过程中&#xff0c;我阅读了还算多的源码&#xff0c;比如 JUC、Spring、MyBatis&#xff0c;收获了很多代码的设计思想&#xff0c;也对平时调用的 API 有了更深入的理解&#xff1b;但过多散乱的笔记给我的整理…

PCIe驱动开发(2)— 第一个简单驱动编写和测试

PCIe驱动开发&#xff08;2&#xff09;— 第一个简单驱动编写和测试 一、前言 教程参考&#xff1a;02_实战部分_PCIE设备测试 教程参考&#xff1a;03_PCIe设备驱动源码解析 二、驱动编写 新建hello_pcie.c文件 touch hello_pcie.c然后编写内容如下所示&#xff1a; #i…

数学系C++(六七)

目录 * &指针与地址 void指针 指针可以等于&#xff1a; const 指向常量的指针 const int *px 常指针 int * const px 指向常量的常指针const 类型标识符 * const 指针名 指针加减&#xff1a; 指针恒等式 函数指针【待续】 指针型函数&#xff1a; 指向函数的…