flutter实现调用原生安卓的高德地图导航功能(插件化)

这篇具有很好参考价值的文章主要介绍了flutter实现调用原生安卓的高德地图导航功能(插件化)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

查看了高德地图flutter插件的文档,都没有能支持导航的功能,并且flutter的高德插件支持的功能特别少,没办法,只能使用安卓原生的导航,flutter去调用了,具体实现方式如下:

  1. 创建 Flutter 插件

使用--template=plugin 声明创建的是同时包含了 iOS 和 Android 代码的 plugin;

使用--org 选项指定组织,一般采用反向域名表示法;

使用-i 选项指定 iOS 平台开发语言,objc 或者 swift;

使用-a 选项指定 Android 平台开发语言,java 或者 kotlin。

flutter create --template=plugin --org com.tencent.game -i objc -a java flutter_amap_nav
  1. 项目结构

flutter地图导航,android,flutter,Powered by 金山文档

我们可以看到 Plugin 多出了一些目录,android 目录用于 Android 平台的代码实现,ios 目录用于 iOS 平台的代码实现,example 目录用于该组件的调试。

  1. 在androidStudio下,右键android目录,选择flutter,以安卓工程打开,具体如下:

flutter地图导航,android,flutter,Powered by 金山文档
  1. 此时,我们在打开的这个项目就可以进行远程的安卓开发了,关于安卓导航部分的SDK,高德的官方文档上面有示例,附上官网链接https://lbs.amap.com/api/android-navi-sdk/summary/

高德地图APIkey申请可参考https://lbs.amap.com/api/android-navi-sdk/guide/create-project/get-key,获取调试版本和发布版本的SHA1(在申请key的时候,这两个SHA1可填写一致),需要注意的是包名在AndroidManifest.xml的package获取

获取好Key之后,在AndroidManifest.xml文件中,添加如下权限

<!--允许访问网络,必选权限-->
<uses-permission android:name="android.permission.INTERNET" />

<!--允许获取精确位置,实时导航为必选-->
<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_EXTERNAL_STORAGE" />

<!--用于用户链接蓝牙时,在导航组件页面的蓝牙连接提醒,建立链接后开发者可选用蓝牙通道进行tts播报-->
<uses-permission android:name="android.permission.BLUETOOTH" />

<!--用与导航状态中保持屏幕常亮-->
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<!--允许读设备等信息,用于问题排查-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

并且,需要添加地图定位的服务

  <application>
        <service android:name="com.amap.api.location.APSService"></service>
        <activity
            android:name="com.amap.api.navi.AmapRouteActivity"
            android:theme="@android:style/Theme.NoTitleBar"
            android:configChanges="orientation|keyboardHidden|screenSize|navigation" />


    </application>

在build.gradle文件中添加导航SDK的依赖,需要需要build.gradle在安卓工程中有两个文件,不要写错位置了,我使用的方式是自动获取最新的依赖包,当然也可以采用手动引入jar包的方式,可参考官方文档的安卓工程手动部署https://lbs.amap.com/api/android-navi-sdk/guide/create-project/manual-configuration

implementation 'com.amap.api:navi-3dmap:latest.integration'

flutter地图导航,android,flutter,Powered by 金山文档
flutter地图导航,android,flutter,Powered by 金山文档

接着,我们在app目录下的AndroidManifest.xml添加apiKey

flutter地图导航,android,flutter,Powered by 金山文档

现在, 我们就可以写安卓代码了,在java目录下,新建mapView和MyViewFactory类,在mapView类下面代码实现如下:

package com.example.amap_nav;

import android.content.Context;
import android.view.View;
import android.webkit.WebView;
import android.widget.TextView;

import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Poi;
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.NaviSetting;
import com.amap.api.navi.INaviInfoCallback;
import com.amap.api.navi.model.AMapNaviLocation;

import java.util.Map;

import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.platform.PlatformView;

public class mapView implements PlatformView {

    private final View Nav;
    private  final  AmapNaviParams naviParams;


    public mapView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params){
        Poi start;
        Poi end;
        TextView textView = new TextView(context);
//        隐私合规检查
        NaviSetting.updatePrivacyShow(context, true, true);
        NaviSetting.updatePrivacyAgree(context, true);
        if (params!=null&&!params.isEmpty()&&params.containsKey("start")) {
            String start1 = (String) params.get("start");
            String end1 = (String) params.get("end");
            textView.setText(start1+end1);
            double a  = Double.parseDouble(start1.split(",")[0]) ;
            double b  = Double.parseDouble(start1.split(",")[1]) ;
            double c  = Double.parseDouble(end1.split(",")[0]) ;
            double d  = Double.parseDouble(end1.split(",")[1]) ;
            start = new Poi(null, new LatLng(a,b), null);
            end = new Poi(null, new LatLng(c,d), null);
            // 组件参数配置
            //构建导航组件配置类,没有传入起点,所以起点默认为 “我的位置”
            naviParams = new AmapNaviParams(start,null,end, AmapNaviType.DRIVER, AmapPageType.ROUTE);
            naviParams.setUseInnerVoice(true);
            naviParams.setMultipleRouteNaviMode(true);
            naviParams.setNeedDestroyDriveManagerInstanceWhenNaviExit(true);
            //启动导航组件
            AmapNaviPage.getInstance().showRouteActivity(context.getApplicationContext(), naviParams,new INaviInfoCallback() {

                @Override
                public void onInitNaviFailure() {

                }

                @Override
                public void onGetNavigationText(String s) {

                }

                @Override
                public void onLocationChange(AMapNaviLocation aMapNaviLocation) {

                }

                @Override
                public void onArriveDestination(boolean b) {

                }

                @Override
                public void onStartNavi(int i) {

                }

                @Override
                public void onCalculateRouteSuccess(int[] ints) {

                }

                @Override
                public void onCalculateRouteFailure(int i) {

                }

                @Override
                public void onStopSpeaking() {

                }

                @Override
                public void onReCalculateRoute(int i) {

                }

                @Override
                public void onExitPage(int i) {

                }

                @Override
                public void onStrategyChanged(int i) {

                }

                @Override
                public void onArrivedWayPoint(int i) {

                }

                @Override
                public void onMapTypeChanged(int i) {

                }

                @Override
                public void onNaviDirectionChanged(int i) {

                }

                @Override
                public void onDayAndNightModeChanged(int i) {

                }

                @Override
                public void onBroadcastModeChanged(int i) {

                }

                @Override
                public void onScaleAutoChanged(boolean b) {

                }

                @Override
                public View getCustomMiddleView() {
                   return null;
                }

                @Override
                public View getCustomNaviView() {

                    return null ;
                }

                @Override
                public View getCustomNaviBottomView() {

                    TextView textView1 = new TextView(context);
                    String a = "123123213123123";
                    textView1.setText(a);
                    return textView1 ;
                }

            });




//         拿到flutter传递过来的参数

            this.Nav = textView;

        } else {

            textView.setText(null);
            this.Nav = textView;
            naviParams = null;
        }


    }

    @Override
    public View getView() {
        return Nav;
    }

    @Override
    public void dispose() {

    }

}


在MyViewFactory类下面代码实现如下:

package com.example.amap_nav;

import android.content.Context;

import com.example.amap_nav.mapView;

import java.util.Map;

import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;

public class MyViewFactory extends PlatformViewFactory {

    private final BinaryMessenger messenger;

    public MyViewFactory(BinaryMessenger messenger) {
        super(StandardMessageCodec.INSTANCE);
        this.messenger = messenger;
    }

    @Override
    @SuppressWarnings("unchecked")
    public PlatformView create(Context context, int id, Object o) {
        Map<String, Object> params = (Map<String, Object>) o;
        return new mapView(context, messenger, id, params);
    }
}

接着,我们去flutter自动创建plugin

flutter地图导航,android,flutter,Powered by 金山文档

的代码实现如下:

package com.example.amap_nav;

import android.util.Log;

import androidx.annotation.NonNull;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BasicMessageChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.StringCodec;

import com.example.amap_nav.MyViewFactory;

/** AmapNavPlugin */
public class AmapNavPlugin implements FlutterPlugin, MethodCallHandler {

  private MethodChannel channel;



  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
//    需要注册的视图的唯一标识
    final String key = "karl_info";
//    创建MethodChannel通道,amap_nav与yaml的name是需要对应的
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "amap_nav");

    channel.setMethodCallHandler(this);
//    注册原生view,通过注册视图工厂(viewFactory),需要传入唯一标识和ViewFactory类
    flutterPluginBinding.getPlatformViewRegistry().registerViewFactory(key,new MyViewFactory(flutterPluginBinding.getBinaryMessenger()));



  }


  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {

    if (call.method.equals("getPlatformVersion")) {

      result.success("Android " + android.os.Build.VERSION.RELEASE +call.arguments);
    }
    else if (call.method.equals("startEnd")) {

      result.success("Android " + android.os.Build.VERSION.RELEASE);

    }
    else {
      result.notImplemented();
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }
}

然后在MainActivity.java里面注册一下视图

package com.example.amap_nav_example;

import androidx.annotation.NonNull;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class MainActivity extends FlutterActivity {
    @Override
        public  void  configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
        }
}

到这里,安卓部分的代码已经完成了,然后我们回到flutter目录,在lib目录下添加load.dart文件,代码如下:

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';



class navWidget extends StatelessWidget {
  const navWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    String viewType = 'karl_info'; // 唯一标识符
    var creationParams = {
      'start':'30.501258, 114.414684',
      'end': '30.511258,114.434684'
    };// 视图创建参数,可以被插件用来传递构造函数参数到嵌入式Android视图
    // 视图创建完毕的回调
    PlatformViewCreatedCallback callback = (id) {};
    // 判断设备类型,也可用:defaultTargetPlatform == TargetPlatform.android
    if (Platform.isAndroid) {
      return AndroidView(
          viewType: viewType,
        onPlatformViewCreated: callback,
        creationParams: creationParams,
        //参数的编码方式
        creationParamsCodec: const StandardMessageCodec(),
      );
    } else if (Platform.isIOS) {
      return UiKitView(
          viewType: viewType,
        onPlatformViewCreated: callback,

      );
    } else {
      return Text('您的设备暂不支持此软件');
    }

  }
}

在flutter自动创建lib目录下的dart文件中实现方式如下:


import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';


class AmapNav {
  static const MethodChannel _channel = MethodChannel('amap_nav');

  static Future<String?> get platformVersion async {
    //invokeMethod传参方式
    final String? version = await _channel.invokeMethod('getPlatformVersion',666);
    return version;
  }
  static Future<String?> get startEnd async {

  }
}

大功告成,项目跑起来的页面如下,后续各种导航的功能可参考官网实现定制化开发,github地址https://github.com/shenlan42/flutter_amap_nav文章来源地址https://www.toymoban.com/news/detail-602591.html

flutter地图导航,android,flutter,Powered by 金山文档
flutter地图导航,android,flutter,Powered by 金山文档
flutter地图导航,android,flutter,Powered by 金山文档

到了这里,关于flutter实现调用原生安卓的高德地图导航功能(插件化)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 高德地图实现-微信小程序地图导航

    1、在高德开放平台注册成为开发者 2、申请开发者密钥(key)。 3、下载并解压高德地图微信小程序SDK 注册账号(https://lbs.amap.com/)) 申请小程序应用的 key 应用管理(https://console.amap.com/dev/key/app)) - 我的应用 - 创建新应用 生成的 key 即可用在程序中 下载相关 sdk 文件,导入 amap-

    2024年02月08日
    浏览(48)
  • 基于微信小程序Map标签及高德地图开源方法实现路径导航

            微信小程序自带地图map标签,他是基于canvas画图功能进行的地图渲染,同时依赖微信的getlocation获取经纬度,绘制周边地图。地图上可以标点,画线,查看当地地理信息。但是自带的导航功能模块不能对个人开发者公开。         高德地图提供了基于微信小程

    2024年02月09日
    浏览(35)
  • 高德地图系列(三):vue项目利用高德地图实现地址搜索功能

    目录 第一章 效果图 第二章 源代码 高德地图为我们提供了搜索联想,以及搜索结果标记,该案例已将基础功能打通,后续我们肯定还会对功能有所修改,想实现自己想要的效果,基本上看高德地图文档对着改就好了(跟我们用别的工具一样做即可)  代码描述如下:  注意事

    2024年02月03日
    浏览(39)
  • 微信小程序学习实录5(H5嵌入小程序、map组件、地图调起功能、腾讯百度高德导航页、返回web-view页)

    创建容器 地图家长 在H5页面引入 //res.wx.qq.com/open/js/jweixin-1.6.0.js ,建议使用高版本; 点击返回按钮 调用微信小程序和H5通用API 判断是否在微信小程序环境中 地图调起,再次返回小程序页 获取H5传递参数的方式为: console.log(options) latitude和longitude必须为数字类型,不支持字符

    2024年02月07日
    浏览(63)
  • uniapp - [安卓|苹果]实现App端引入高德地图,详细获取当前用户手机定位、两个地点的路线规划及相关示例代码,uniapp安卓Android平台软件下使用高德地图,获取当前位置信息及规划路线

    在uniapp安卓app端 | 苹果app端开发中,详细完成APP端引入使用高德地图插件,提供可直接复制的示例,例如获取当前定位及取到当前城市位置信息,规划两个位置的路线(规划城市2个点的路线轨迹及在地图上显示)等示例。 新手跟着教程一步步来,轻松实现此功能。 首先,

    2024年02月22日
    浏览(63)
  • 记录--仿贝壳地图画圈找房功能实现(高德地图)

    在最近租房时,看到贝壳找房上线了一个地图画圈找房的功能,感觉很是新奇。接触地图开发也有很长一段时间了,以前大部分都是基于web pc端开发,所以一般遇到这种圈选,绘制多边形圆形都是直接基于官方API直接修改使用的,对于PC端鼠标操作来说,现有的交互用起来已

    2024年02月05日
    浏览(32)
  • Android高德地图定位实现签到打卡功能(全网最详细+收藏)

    前言         本章根据高德地图API,实现打卡签到功能。用到了定位SDK 和地图SDK、覆盖物。打卡范围图形可以支持多种形状,如: 圆形 、 长方形 、 多边形。 核心逻辑:     获取当前定位信息,然后通过Marker绘制小图标进行展示,并在onLocationChanged回调方法中不断重新绘

    2024年02月03日
    浏览(28)
  • vue3使用高德地图实现点击获取经纬度以及搜索功能

     话不多说直接上干活 在此之前你需要有高德地图的 key,这个自己去申请即可 1,首先需要在终端安装 2,准备一个容器 3,在需要使用的页面引入刚才安装的 4, 5,绑定input框 最后附上css代码 ​​​​​​​这个时候就已经可以了

    2024年02月12日
    浏览(36)
  • 安卓中集成高德地图

    高德开放平台 | 高德地图API 高德地图优点: 1、领先的地图渲染技术:性能提升10倍,所占空间降低80%,比传统地图软件节省流量超过90% 2、专业在线导航功能:覆盖全国364个城市、全国道路里程352万公里 3、在线导航功能:最新高德在线导航引擎,全程语音指引提示,完善

    2024年02月07日
    浏览(29)
  • flutter高德地图大头针

    1、效果图 2、pub get #地图定位 amap_flutter_map: ^3.0.0 amap_flutter_location: ^3.0.0 3、上代码

    2024年02月11日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包