由于眾所周知的原因砸抛,國(guó)內(nèi)無(wú)法使用location提供的谷歌定位服務(wù)晋涣,所以只能使用百度地圖或者高德地圖提供的定位服務(wù)伙菊。
所幸雙方都已經(jīng)實(shí)現(xiàn)了對(duì)flutter的支持迫像。百度地圖的api和配置比高德要簡(jiǎn)單那么一丟丟漫玄,不過(guò)包好像很久沒(méi)更新茄蚯,以至于錯(cuò)誤很多。最終還是選了高德地圖來(lái)實(shí)現(xiàn)睦优。
官方文檔地址
https://lbs.amap.com/api/flutter/gettingstarted
1. 獲取高德Key
在控制臺(tái)創(chuàng)建新的應(yīng)用獲取key
創(chuàng)建新應(yīng)用
應(yīng)用名稱自定義渗常,可以隨便寫(xiě)。類型選擇相符的就可以汗盘,這個(gè)不會(huì)嚴(yán)格審查的皱碘。
應(yīng)用下面可以有好幾個(gè)key,key的名稱可以自定義隐孽,平臺(tái)選擇對(duì)應(yīng)的平臺(tái)癌椿。
申請(qǐng)key需要填寫(xiě)debug版本和release版本的keystore
keystore和Keytool是什么
Keytool是一個(gè)Java數(shù)據(jù)證書(shū)的管理工具 健蕊,Keytool將密鑰(key)和證書(shū)(certificates)存在一個(gè)稱為keystore的文件中。 在keystore里踢俄,包含兩種數(shù)據(jù):
密鑰實(shí)體(Key entity)——密鑰(secret key)又或者是私鑰和配對(duì)公鑰(采用非對(duì)稱加密)
可信任的證書(shū)實(shí)體(trusted certificate entries)——只包含公鑰
Keystore可以簡(jiǎn)單理解為一個(gè)存放應(yīng)用簽名的文件缩功。
調(diào)試版安全碼SHA1
我是mac,進(jìn)入當(dāng)前用戶文件夾下的~/.android目錄(windows在c:/user/.android)褪贵,里面有debug.keystore文件掂之,運(yùn)行命令獲取該文件sha1
cd ~/.android
keytool -list -v -keystore debug.keystore
如果keytool不存在則需要安裝jdk。
如果debug.keystore不存在脆丁,則需要使用keytool -genkey命令生成一個(gè)debug.keystore
輸入密鑰口令世舰,默認(rèn)是 android,即可獲得SHA1安全碼
發(fā)布版安全碼SHA1
如果沒(méi)有過(guò)apk還沒(méi)有keystore簽名文件槽卫,則需要生成跟压,
生成keystore簽名文件
keytool -genkey -v -keystore mykey.keystore -alias key -keyalg RSA -keysize 2048 -validity 10000
填寫(xiě)好資料
生成后的文件在mac用戶目錄
命令行直接使用keytool進(jìn)行得到mykey.keystore的sha1,在文件目錄下運(yùn)行
keytool -list -v -keystore mykey.keystore
即可得到發(fā)布版安全碼歼培,apk就用這個(gè)keystore文件進(jìn)行簽名震蒋,這樣就沒(méi)問(wèn)題了。
如果需要把a(bǔ)pk簽名躲庄,具體方法請(qǐng)看:
http://www.reibang.com/p/398d41128b02
PackageName
在 android/app/build.gradle 中獲取包名
提交保存后即可獲得Key查剖。
集成SDK
在 android/build.gradle 文件中,添加mavenCentral()或者 jcenter()
allprojects { repositories { jcenter() // 或者 mavenCentral() } }
在 android/app/build.gradle 中噪窘,配置依賴:
dependencies {
...
implementation 'com.amap.api:location:latest.integration'
}
添加服務(wù)笋庄、聲明定位權(quán)限
Android:
在 android/app/src/main/AndroidManifest.xml 文件中
1、添加服務(wù)
<application android:label="****" android:icon="@mipmap/ic_launcher">
<!-- 配置定位Service -->
<service android:name="com.amap.api.location.APSService"/>
2倔监、聲明權(quán)限
<!--允許訪問(wèn)網(wǎng)絡(luò)直砂,必選權(quán)限-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--允許獲取精確位置,精準(zhǔn)定位必選-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--允許獲取粗略位置浩习,粗略定位必選-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!--允許獲取設(shè)備和運(yùn)營(yíng)商信息静暂,用于問(wèn)題排查和網(wǎng)絡(luò)定位(無(wú)gps情況下的定位),若需網(wǎng)絡(luò)定位功能則必選-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--允許獲取網(wǎng)絡(luò)狀態(tài)谱秽,用于網(wǎng)絡(luò)定位(無(wú)gps情況下的定位)洽蛀,若需網(wǎng)絡(luò)定位功能則必選-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--允許獲取wifi網(wǎng)絡(luò)信息,用于網(wǎng)絡(luò)定位(無(wú)gps情況下的定位)疟赊,若需網(wǎng)絡(luò)定位功能則必選-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允許獲取wifi狀態(tài)改變辱士,用于網(wǎng)絡(luò)定位(無(wú)gps情況下的定位),若需網(wǎng)絡(luò)定位功能則必選-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!--后臺(tái)獲取位置信息听绳,若需后臺(tái)定位則必選-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<!--用于申請(qǐng)調(diào)用A-GPS模塊,衛(wèi)星定位加速-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<!--允許寫(xiě)設(shè)備緩存,用于問(wèn)題排查-->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--允許寫(xiě)入擴(kuò)展存儲(chǔ)异赫,用于寫(xiě)入緩存定位數(shù)據(jù)-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--允許讀設(shè)備等信息椅挣,用于問(wèn)題排查-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
ios:
1头岔、ios/info.plist加入
<key>NSLocationWhenInUseUsageDescription</key>
<string>使用當(dāng)前位置信息</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>實(shí)時(shí)使用當(dāng)前的位置信息</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>實(shí)時(shí)使用當(dāng)前的位置信息</string>
2、ios/Padfile末尾加入
target.build_configurations.each do |config|
# Here are some configurations automatically generated by flutter
# 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
如圖:
引入高德定位Flutter插件
# 高德地圖
amap_flutter_location: ^3.0.0
獲取定位
代碼中填入申請(qǐng)好的高德apikey)
import 'dart:async';
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';
/*
//使用
locationUtil.getCurrentLocation((Map result){
print('接收到result:$result');
}).catchError((err){
Fluttertoast.showToast(msg: err);
});
*/
class LocationUtil {
StreamSubscription<Map<String, Object>>? _locationListener;
final AMapFlutterLocation _locationPlugin = AMapFlutterLocation();
PermissionStatus? status;
LocationUtil(){
AMapFlutterLocation.setApiKey(
"xxxxxx",//androidkey
"xxxxxx"http://ioskey
);
/// 設(shè)置是否已經(jīng)包含高德隱私政策并彈窗展示顯示用戶查看鼠证,如果未包含或者沒(méi)有彈窗展示峡竣,高德定位SDK將不會(huì)工作
///
/// 高德SDK合規(guī)使用方案請(qǐng)參考官網(wǎng)地址:https://lbs.amap.com/news/sdkhgsy
/// <b>必須保證在調(diào)用定位功能之前調(diào)用, 建議首次啟動(dòng)App時(shí)彈出《隱私政策》并取得用戶同意</b>
///
/// 高德SDK合規(guī)使用方案請(qǐng)參考官網(wǎng)地址:https://lbs.amap.com/news/sdkhgsy
///
/// [hasContains] 隱私聲明中是否包含高德隱私政策說(shuō)明
///
/// [hasShow] 隱私權(quán)政策是否彈窗展示告知用戶
AMapFlutterLocation.updatePrivacyShow(true, true);
/// 設(shè)置是否已經(jīng)取得用戶同意量九,如果未取得用戶同意适掰,高德定位SDK將不會(huì)工作
///
/// 高德SDK合規(guī)使用方案請(qǐng)參考官網(wǎng)地址:https://lbs.amap.com/news/sdkhgsy
///
/// <b>必須保證在調(diào)用定位功能之前調(diào)用, 建議首次啟動(dòng)App時(shí)彈出《隱私政策》并取得用戶同意</b>
///
/// [hasAgree] 隱私權(quán)政策是否已經(jīng)取得用戶同意
AMapFlutterLocation.updatePrivacyAgree(true);
}
/// 動(dòng)態(tài)申請(qǐng)定位權(quán)限
Future<bool> _requestPermission() async {
status = await Permission.location.status;
if (status == PermissionStatus.granted) {
return true;
} else {
//未授權(quán)則發(fā)起一次申請(qǐng)
status = await Permission.location.request();
print('status=$status');
if (status == PermissionStatus.granted) {
return true;
} else {
return false;
}
}
}
Future<void> getCurrentLocation(Function(Map result) onLocationChanged,{once=true}) async {
bool isPermitted = await _requestPermission();
print('isPermitted=$isPermitted');
if(!isPermitted){
throw('請(qǐng)?jiān)谑謾C(jī)設(shè)置中開(kāi)啟本app位置權(quán)限');
}
if(isPermitted){
///注冊(cè)定位結(jié)果監(jiān)聽(tīng)
_locationListener = _locationPlugin.onLocationChanged().listen((Map<String, Object> result) {
onLocationChanged(result);
if (result['longitude'] != null) {
//print("當(dāng)前位置:$result");
if(once) _stopLocation();
}
});
_startLocation();
}
}
///設(shè)置定位參數(shù)
void _setLocationOption() {
AMapLocationOption locationOption = AMapLocationOption();
///將定位參數(shù)設(shè)置給定位插件
_locationPlugin.setLocationOption(locationOption);
}
///開(kāi)始定位
void _startLocation() {
_setLocationOption();
_locationPlugin.startLocation();
}
///停止定位
void _stopLocation() {
_locationPlugin.stopLocation();
}
void cancel() {
if (null != _locationListener) {
_locationListener?.cancel(); // 停止定位
}
}
}
錯(cuò)誤
Could not resolve com.amap.api:location:latest.integration.
如果出現(xiàn)這個(gè)錯(cuò)誤,是因?yàn)閎uild的時(shí)候荠列,會(huì)去云端倉(cāng)庫(kù)請(qǐng)求最新的包列表类浪,如果請(qǐng)求不到,則會(huì)無(wú)法build肌似。我們可以指定包费就。
查看最新的包:https://lbs.amap.com/api/android-location-sdk/guide/create-project/android-studio-create-project
編輯android/app/build.gradle
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.amap.api:location:3.3.0'//指定版本高德定位插件,
//implementation 'com.amap.api:location:latest.integration'//最新版高德定位插件
}