文章目录
- 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);
}
}
}