flutter3.0项目集成高得地图

news2024/12/24 11:37:26

文章目录

  • 1.创建应用:
    • 注册高得开发平台
  • 安卓端的设置
  • flutter的集成
  • ios端的设置

先看一下代码运行结果
安卓端真机
` 在这里插入图片描述

ios端真机屏幕录屏
在这里插入图片描述
本篇文章demo下载地址
下载后请用xcode修改自己的ios证书真机运行.flutter代码在PG1.dart里面修改
String androidKey = “b3392bb7fe532b0eb0e2a85ec464e804”;
String iosKey = “318e438a3a7e4bec53f45b826b8f7003”;
把这2个变量修改成自己创建应用的key

官方示例demo地址

1.创建应用:

注册高得开发平台

下面链接创建应用

https://console.amap.com/dev/key/app

点击"创建新应用",然后如下图新建

在这里插入图片描述

创建应用后,添加Key

安卓端的设置

打开flutter下面的android目录找到AndroidManifest.xml文件package=“com.tdw.demo98” ,文件中的package 后面要填写的PackageName

在这里插入图片描述

在这里插入图片描述

用android studio打包
Build->Generate Signed Bundle /APK… ->APK->Next
在这里插入图片描述
在这里插入图片描述

Create new…创建一个key,如下图填写路径,密码,别名,公司信息
在这里插入图片描述
注意上面生成的Key store path: /Users/tdw/Documents/demo98 这个路径我们要保存下来,下面要用

之后选择next->release->next 如下图
在这里插入图片描述
在这里插入图片描述
如果打包很慢,可以配置成国内镜像,方法参考我写的这篇文章的1,2 两个步骤是修改国内镜像
flutter安卓模拟器不好使安卓每次打开android studio都下载并且download Importing ‘android“Gradle Project问题

打包完成以后:

下面以mac系统为例:

终端进入到 /Users/你的用户名/.android 目录

下面命令是生成调试版签名

 keytool -list -v -keystore 加上路径

这个路径是上面打包的时候创建生成的Key store path: /Users/tdw/Documents/demo98
组合如下:

keytool -list -v -keystore /Users/tdw/Documents/demo98

然后输入密码,回车,显示下面结果:

tdw@tdwdeMini-m1 .android %  keytool -list -v -keystore /Users/tdw/Documents/demo98
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN

您的密钥库包含 1 个条目

别名: key0
创建日期: 2023年8月7日
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: C=1, ST=1, L=1, O=1, OU=1, CN=1
发布者: C=1, ST=1, L=1, O=1, OU=1, CN=1
序列号: 1
生效时间: Mon Aug 07 15:25:20 CST 2023, 失效时间: Fri Jul 31 15:25:20 CST 2048
证书指纹:
	 SHA1: AF:3D:F8:D2:1A:1E:F1:1C:54:49:68:1B:C0:54:23:BC:33:EC:6A:45
	 SHA256: 11:31:BC:17:75:58:24:31:18:84:68:22:BE:FF:27:24:FF:DC:D5:7E:3C:15:BF:59:C7:D8:4D:16:8B:BF:22:5D
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 1

复制SHA1:后面的字符串:

 AF:3D:F8:D2:1A:1E:F1:1C:54:49:68:1B:C0:54:23:BC:33:EC:6A:45

复制到下面,调试版和发布版的SHA1可以填写一样的
在这里插入图片描述
提交之后可以看到安卓的key添加好了

在这里插入图片描述
这个key复制下来,要放到flutter代码里

flutter的集成

pub.dev的网址
https://pub.dev/packages/amap_flutter_location/install

文件pubspec.yaml添加下面代码:

amap_flutter_location: ^3.0.0

在这里插入图片描述

dart文件包含:

import 'package:amap_flutter_location/amap_flutter_location.dart';

安卓修改文件:
android/app/build.gradle
dependencies{}添加一句: implementation(‘com.amap.api:location:版本号’)
例如:


dependencies {
    implementation('com.amap.api:location:5.6.1')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

在android/app/build.gradle文件中,添加
storeFile 是我们打包用的key文件
keyAlias是刚才打包用的别名
后面是2个密码
如果忘记了,可以点击build->Generate Signed Bundle/APK… 然后查看打包的信息,如下图:
在这里插入图片描述

把下面代码添加到defaultConfig{}大括号后面


    signingConfigs {
        release {//发布版本的签名配置
            storeFile file('demo98')
            keyAlias "Key0"
            storePassword "123456"
            keyPassword "123456"
        }
        debug {//调试版本的签名配置
            storeFile file('demo98')
            keyAlias "Key0"
            storePassword "123456"
            keyPassword "123456"
        }
    }

如下图
在这里插入图片描述

buildTypes{}里面添加debug

        debug {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }

如下图:
在这里插入图片描述

把刚才打包用的keystore文件demo98复制到android/app目录下
在这里插入图片描述

修改文件android/app/src/main/AndroidManifest.xml
添加下面代码到 和 <application之间

  <!--访问网络-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!--定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!--GPS模块-->
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <!--移动网定位-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!--wifi定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <!--读取手机状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!--读取存储卡-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

如图:

在这里插入图片描述
在里面添加定位服务

 <!-- 配置定位服务 -->
       <service android:name="com.amap.api.location.APSService"/>

如下图:
在这里插入图片描述

#flutter调用
注意下面的import ‘package:permission_handler/permission_handler.dart’; 需要在pub.dev里面搜索permission_handler ,并且安装
https://pub.dev/packages/permission_handler
在pubspec.yaml文件中安装第三方插件:

permission_handler: ^10.4.3

用到高德地图的页面包含如下:

 import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:permission_handler/permission_handler.dart';

ios端的设置

下面地址点击创建应用

https://console.amap.com/dev/key/app

然后自己起一个名字
在这里插入图片描述

用xcode打开ios文件夹的Runner.xcworkspace 文件,然后点击左边项目Ranner->Signing & Capabilities->找到Bundle ldentifier后面包名:com.tdw.demo98
在这里插入图片描述
之后点击点击 “添加Key”,复制上面的包名Bundle ldentifier到安全码Bundle ID
服务平台选择iOS平台
key名称自己随便起一个
勾选阅读同意
如下图:
之后在这里插入图片描述
之后点击刚才的生成的应用,可以看到key,这个key留着,要放到flutter代码里
在这里插入图片描述

在xcode中找到Runner下的 info.plist 邮件选择Open As->Source Code 添加下面定位需要的权限

     <key>UIBackgroundModes</key>
     <array>
         <string>location</string>
     </array>
     <key>NSLocationDefaultAccuracyReduced</key>
     <true/>
     <key>NSLocationWhenInUseUsageDescription</key>
     <string>此应用需要访问定位</string>
     <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
     <string>此应用需要访问定位</string>
     <key>allowsBackgroundLocationUpdates</key>
     <string>此应用需要访问后台定位</string>

打开ios文件夹下的 podfile文件
找到最下面的这些代码删除

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
  end
end 

然后复制下面的代码到最下面



post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      flutter_additional_ios_build_settings(target)

      # You can enable the permissions needed here. For example to enable camera
      # permission, just remove the `#` character in front so it looks like this:
      #
      # ## dart: PermissionGroup.camera
      # 'PERMISSION_CAMERA=1'
      #
      #  Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.calendar
        # 'PERMISSION_EVENTS=1',

        ## dart: PermissionGroup.reminders
        # 'PERMISSION_REMINDERS=1',

        ## dart: PermissionGroup.contacts
        # 'PERMISSION_CONTACTS=1',

        ## dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',

        ## dart: PermissionGroup.microphone
        # 'PERMISSION_MICROPHONE=1',

        ## dart: PermissionGroup.speech
        # 'PERMISSION_SPEECH_RECOGNIZER=1',

        ## dart: PermissionGroup.photos
        'PERMISSION_PHOTOS=1',

        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        'PERMISSION_LOCATION=1',

        ## dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1',

        ## dart: PermissionGroup.mediaLibrary
        # 'PERMISSION_MEDIA_LIBRARY=1',

        ## dart: PermissionGroup.sensors
        # 'PERMISSION_SENSORS=1',

        ## dart: PermissionGroup.bluetooth
        # 'PERMISSION_BLUETOOTH=1',

        ## dart: PermissionGroup.appTrackingTransparency
        # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',

        ## dart: PermissionGroup.criticalAlerts
        # 'PERMISSION_CRITICAL_ALERTS=1'
      ]

    end
  end
end

最后要想ios真机运行,需要用xcode打开项目,选择自己的证书,如下图
在这里插入图片描述
下面是flutter代码,PG1.dart,你把他复制到自己的项目中,然后通过main.dart弹出这个页面就行了.

import 'dart:async';
import 'dart:io';
import 'package:demo98/route.dart';
import 'package:flutter/material.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:permission_handler/permission_handler.dart'; //需要在pub.dev里面安装第三方插件:permission_handler

class PG1 extends StatefulWidget {
  const PG1({super.key});

  @override
  State<PG1> createState() => _PG1State();
}

class _PG1State extends State<PG1> {
  late Map<String, Object> _locationResult;
  late StreamSubscription<Map<String, Object>> _locationListener;
  AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();
  String androidKey = "b3392bb7fe532b0eb0e2a85ec464e804";
  String iosKey = "318e438a3a7e4bec53f45b826b8f7003";
  String _latitude = ""; //纬度
  String _longitude = ""; //经度

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    AMapFlutterLocation.updatePrivacyShow(true, true);
    AMapFlutterLocation.updatePrivacyAgree(true);

    /// 动态申请定位权限
    requestPermission();
    //设置key
    AMapFlutterLocation.setApiKey(androidKey, iosKey);

    ///iOS 获取native精度类型
    if (Platform.isIOS) {
      requestAccuracyAuthorization();
    }

    ///注册定位结果监听
    _locationListener = _locationPlugin
        .onLocationChanged()
        .listen((Map<String, Object> result) {
      setState(() {
        _locationResult = result;
        _latitude = result["latitude"].toString();
        _longitude = result["longitude"].toString();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('appbarTitle'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                onPressed: _startLocation,
                child: const Text("开始定位", textAlign: TextAlign.center)),
            ElevatedButton(
                onPressed: _stopLocation,
                child: const Text("停止定位", textAlign: TextAlign.center)),
            Text("纬度_latitude=${_latitude}", textAlign: TextAlign.center),
            Text("经度_longitude=${_longitude}", textAlign: TextAlign.center),
          ],
        ),
      ),
    );
  }

  ///获取iOS native的accuracyAuthorization类型
  void requestAccuracyAuthorization() async {
    AMapAccuracyAuthorization currentAccuracyAuthorization =
        await _locationPlugin.getSystemAccuracyAuthorization();
    if (currentAccuracyAuthorization ==
        AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
      print("精确定位类型");
    } else if (currentAccuracyAuthorization ==
        AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
      print("模糊定位类型");
    } else {
      print("未知定位类型");
    }
  }

  /// 动态申请定位权限
  void requestPermission() async {
    // 申请权限
    bool hasLocationPermission = await requestLocationPermission();
    if (hasLocationPermission) {
      print("定位权限申请通过");
    } else {
      print("定位权限申请不通过");
    }
  }

  /// 申请定位权限
  /// 授予定位权限返回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;
      }
    }
  }

  ///开始定位
  void _startLocation() {
    if (null != _locationPlugin) {
      ///开始定位之前设置定位参数
      _setLocationOption();
      _locationPlugin.startLocation();
    }
  }

  ///停止定位
  void _stopLocation() {
    if (null != _locationPlugin) {
      _locationPlugin.stopLocation();
    }
  }

  ///设置定位参数
  void _setLocationOption() {
    if (null != _locationPlugin) {
      AMapLocationOption locationOption = new AMapLocationOption();

      ///是否单次定位
      locationOption.onceLocation = false;

      ///是否需要返回逆地理信息
      locationOption.needAddress = true;

      ///逆地理信息的语言类型
      locationOption.geoLanguage = GeoLanguage.DEFAULT;

      locationOption.desiredLocationAccuracyAuthorizationMode =
          AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;

      locationOption.fullAccuracyPurposeKey = "AMapLocationScene";

      ///设置Android端连续定位的定位间隔
      locationOption.locationInterval = 2000;

      ///设置Android端的定位模式<br>
      ///可选值:<br>
      ///<li>[AMapLocationMode.Battery_Saving]</li>
      ///<li>[AMapLocationMode.Device_Sensors]</li>
      ///<li>[AMapLocationMode.Hight_Accuracy]</li>
      locationOption.locationMode = AMapLocationMode.Hight_Accuracy;

      ///设置iOS端的定位最小更新距离<br>
      locationOption.distanceFilter = -1;

      ///设置iOS端期望的定位精度
      /// 可选值:<br>
      /// <li>[DesiredAccuracy.Best] 最高精度</li>
      /// <li>[DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度 </li>
      /// <li>[DesiredAccuracy.NearestTenMeters] 10米 </li>
      /// <li>[DesiredAccuracy.Kilometer] 1000米</li>
      /// <li>[DesiredAccuracy.ThreeKilometers] 3000米</li>
      locationOption.desiredAccuracy = DesiredAccuracy.Best;

      ///设置iOS端是否允许系统暂停定位
      locationOption.pausesLocationUpdatesAutomatically = false;

      ///将定位参数设置给定位插件
      _locationPlugin.setLocationOption(locationOption);
    }
  }
}


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

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

相关文章

Mac终端利器:Homebrew + iTerm2 + Oh My Zsh 教程

引言 前段时间调整了一下 iTerm2 的环境&#xff0c;感觉比以前好看多了&#xff0c;并且更加高效&#xff0c;这里做一个记录&#xff0c;希望能给大家一些启发。 工具介绍 brew&#xff1a;Mac OS 下强大的包管理工具。iTerm2&#xff1a;iTerm2是 Mac OS 终端的替代品&am…

实现vuex数据持久化处理

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 前言&#xff1a; 方案一 localStorage 介绍 值 示例 JSON.stringify() 介绍 语法 参数 返…

深入JVM - JIT分层编译技术与日志详解

深入JVM - JIT分层编译技术与日志详解 文章目录 深入JVM - JIT分层编译技术与日志详解1. 背景简介2. JIT 编译器2.1. 客户端版本的编译器: C12.2. 服务端版本的编译器: C22.3. Graal JIT 编译器 3. 分层编译技术(Tiered Compilation)3.1. 汇聚两种编译器的优点3.2. 精准优化(Ac…

人工智能、BIM技术、机器学习在智慧工地的应用

人工智能、BIM技术、机器学习在智慧工地的应用 智慧工地云平台是专为建筑施工领域所打造的一体化信息管理平台。通过大数据、云计算、人工智能、BIM、物联网和移动互联网等高科技技术手段&#xff0c;将施工区域各系统数据汇总&#xff0c;建立可视化数字工地。同时&#xff0…

⌈算法进阶⌋图论::并查集——快速理解到熟练运用

目录 一、原理 1. 初始化Init 2. 查询 find 3. 合并 union 二、代码模板 三、练习 1、 990.等式方程的可满足性 &#xff08;中等&#xff09; 2、 1061. 按字典序排列最小的等效字符串 &#xff08;中等&#xff09; 3、账户合并 &#xff08;较难&am…

QFontDialog

QFontDialog QFont字体类使用QFont类QFontDialog类的静态API简单的使用 QFontDialog类是QDialog的子类, 通过这个类我们可以得到一个进行字体属性设置的对话框窗口, 和前边介绍的对话框类一样, 我们只需要调用这个类的静态成员函数就可以得到想要的窗口了。 QFont字体类 关于…

Android自定义侧滑Item

源码地址&#xff1a;https://github.com/LanSeLianMa/CustomizeView/tree/master/cehuaitem 使用方式一&#xff1a;XML布局中直接使用 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com…

python怎么判断变量的数据类型

在编程的世界里&#xff0c;了解各种数据类型是非常重要的。在Python中&#xff0c;有着丰富的数据类型用于存储和处理不同类型的数据。掌握这些数据类型的定义和作用&#xff0c;我们能够更好地在程序中管理和操作数据&#xff0c;提高代码的效率和可读性。 Python中常见的数据…

使用node搭建服务器,前端自己写接口,将vue或react打包后生成的dist目录在本地运行

使用node.jsexpress或者使用node.jspm2搭建服务器&#xff0c;将vue或react打包后生成的dist目录在本地运行 vue项目打包后生成的dist目录如果直接在本地打开index.html,在浏览器中会报错&#xff0c;无法运行起来。 通常我是放到后端搭建的服务上面去运行&#xff0c;当时前端…

pve和openwrt以及我的电脑中网络的关系和互通组网

情况1 一台主机 有4个口&#xff0c;分别eth0,eth1,eth2,eth3 pve有管理口 这个情况下 &#xff0c;没有openwrt 直接电脑和pve管理口连在一起就能进pve管理界面 情况2 假设pve 的管理口味eth0 openwrt中桥接的是eth0 eth1 eth2 那么电脑连接eth3或者pve管理口设置eth3&#xf…

jmeter创建一个压测项目

1.jemeter新建一个项目&#xff1a; 2.接下来对Thread进行描述&#xff0c;也可以先使用默认的Thread进行操作。 3.添加http请求头的信息。按照如图所示操作 4.在请求头里面添加必要的字段&#xff0c;可以只填必要字段就可以 5.添加Http请求信息&#xff0c;如下图&#xff…

【webpack】动态配置cdn,多模板入口项目搭建

动态配置多模板 按照这个模板创建项目 安装glob,获取目录下的文件名称 封装方法utilsConfig&#xff0c;动态生产 page // pages 多入口配置 const path require("path");// glob 是 webpack 安装时依赖的一个第三方模块&#xff0c;该模块允许你使用 * 等符号, …

图片如何转pdf?几个小妙招了解一下

图片如何转pdf&#xff1f;在日常工作和生活中&#xff0c;我们经常需要将图片转换成PDF格式&#xff0c;以便于我们进行存档、传输或打印。那么&#xff0c;如何快速、方便地将图片转换成PDF呢&#xff1f;这里介绍就为大家介绍几款好用的工具。 我们可以使用【迅捷PDF转换器】…

opencv动态目标检测

文章目录 前言一、效果展示二、实现方法构造形态学操作所需的核:创建背景减除模型:形态学操作:轮廓检测: 三、代码python代码C代码 总结参考文档 前言 很久没更新文章了&#xff0c;这次因为工作场景需要检测动态目标&#xff0c;特此记录一下。 一、效果展示 二、实现方法 基…

简化AD管理减少IT工作负担

管理和保护混合 AD 环境 IT 管理员几乎每天都要创建和管理多个 AD 对象&#xff0c;利用本机AD工具&#xff08;如Active Directory用户和计算机控制台以及PowerShell脚本&#xff09;来执行这些任务并不理想&#xff0c;因为它们必须在多个控制台之间切换才能执行这些任务&am…

【UE4 RTS】02-Camera Movement

前言 本篇实现了CameraPawn的基本移动功能 步骤 1. 打开项目设置&#xff0c;在 引擎——输入 一栏中删除模板自带的操作映射 在轴映射中&#xff0c;删除“TurnRate” 添加如下键值 2. 打开“RTS_PlayerController_BP”&#xff0c;在事件图表中添加如下节点 此时运行游戏就…

MySQL和钉钉单据接口对接

MySQL和钉钉单据接口对接 数据源系统:钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团打造的企业级智能移动办公平台&#xff0c;是数字经济时代的企业组织协同办公和应用开发平台。钉钉将IM即时沟通、钉钉文档、钉闪会、钉盘、Teambition、OA审批、智能人事、钉工牌…

Java后台生成ECharts图片

前言 通过echarts的jar包&#xff0c;Java后台生成一张图片&#xff0c;并把图片插入到word中。关于word插图片的代码在下一章。 需要用到的工具PhantomJS,Echarts-convert.js,jquery.js,echarts.js。 1.PhantomJS 介绍 PhantomJS是一个不需要浏览器的富客户端。 官方介绍&…

PS的一些智能对象是怎么用的?用于包装设计该怎么使用?

大家都对一些效果图不太理解&#xff0c;我现在就献丑给大家讲一下&#xff0c;教程都是网友盛传的&#xff0c;我自己学习并且有所体会。 一般做的非常好的PS效果图都是外国人自己做的&#xff0c;所以大多数效果图都是英文&#xff0c;细心的网友会发现&#xff0c;中文的是一…