location_utils.dart 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import 'package:amap_flutter_location/amap_flutter_location.dart';
  2. import 'package:amap_flutter_location/amap_location_option.dart';
  3. import 'package:app_settings/app_settings.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:permission_handler/permission_handler.dart';
  6. import '../router/my_navigator.dart';
  7. import '../widget/button.dart';
  8. class LocationUtils {
  9. LocationUtils._();
  10. ///设置Android和iOS的apikey,建议在weigdet初始化时设置<br>
  11. ///apiKey的申请请参考高德开放平台官网<br>
  12. ///Android端: https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key<br>
  13. ///iOS端: https://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key<br>
  14. ///[androidKey] Android平台的key<br>
  15. ///[iosKey] ios平台的key<br>
  16. static void setApiKey(String androidKey, String iosKey) {
  17. AMapFlutterLocation.setApiKey(androidKey, iosKey);
  18. }
  19. /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作<br>
  20. /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy<br>
  21. /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b><br>
  22. /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
  23. /// [hasContains] 隐私声明中是否包含高德隐私政策说明<br>
  24. /// [hasShow] 隐私权政策是否弹窗展示告知用户<br>
  25. static void updatePrivacyShow(bool hasContains, bool hasShow) {
  26. AMapFlutterLocation.updatePrivacyShow(hasContains, hasShow);
  27. }
  28. /// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作<br>
  29. /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy<br>
  30. /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b><br>
  31. /// [hasAgree] 隐私权政策是否已经取得用户同意<br>
  32. static void updatePrivacyAgree(bool hasAgree) {
  33. AMapFlutterLocation.updatePrivacyAgree(hasAgree);
  34. }
  35. static AMapFlutterLocation? _location;
  36. static AMapFlutterLocation get location => _location ??= AMapFlutterLocation();
  37. /// 设置定位参数
  38. static AMapFlutterLocation setLocationOption(AMapLocationOption option) {
  39. location.setLocationOption(option);
  40. return location;
  41. }
  42. ///开始定位
  43. static AMapFlutterLocation startLocation() {
  44. location.startLocation();
  45. return location;
  46. }
  47. ///停止定位
  48. static AMapFlutterLocation stopLocation() {
  49. location.stopLocation();
  50. return location;
  51. }
  52. ///销毁定位
  53. static void destroy() {
  54. location.destroy();
  55. _location = null;
  56. }
  57. ///定位结果回调
  58. ///
  59. ///定位结果以map的形式透出,其中包含的key已经含义如下:
  60. ///
  61. /// `callbackTime`:回调时间,格式为"yyyy-MM-dd HH:mm:ss"
  62. ///
  63. /// `locationTime`:定位时间, 格式为"yyyy-MM-dd HH:mm:ss"
  64. ///
  65. /// `locationType`: 定位类型, 具体类型可以参考https://lbs.amap.com/api/android-location-sdk/guide/utilities/location-type
  66. ///
  67. /// `latitude`:纬度
  68. ///
  69. /// `longitude`:精度
  70. ///
  71. /// `accuracy`:精确度
  72. ///
  73. /// `altitude`:海拔, android上只有locationType==1时才会有值
  74. ///
  75. /// `bearing`: 角度,android上只有locationType==1时才会有值
  76. ///
  77. /// `speed`:速度, android上只有locationType==1时才会有值
  78. ///
  79. /// `country`: 国家,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  80. ///
  81. /// `province`: 省,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  82. ///
  83. /// `city`: 城市,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  84. ///
  85. /// `district`: 城镇(区),android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  86. ///
  87. /// `street`: 街道,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  88. ///
  89. /// `streetNumber`: 门牌号,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  90. ///
  91. /// `cityCode`: 城市编码,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  92. ///
  93. /// `adCode`: 区域编码, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  94. ///
  95. /// `address`: 地址信息, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  96. ///
  97. /// `description`: 位置语义, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值
  98. ///
  99. /// `errorCode`: 错误码,当定位失败时才会返回对应的错误码, 具体错误请参考:https://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode
  100. ///
  101. /// `errorInfo`: 错误信息, 当定位失败时才会返回
  102. static Stream<Map<String, Object>> onLocationChanged() {
  103. return location.onLocationChanged();
  104. }
  105. /// 检查定位是否可用
  106. /// 1.app定位权限
  107. /// 2.系统定位开关
  108. static Future<bool> checkLocationAvailable() async {
  109. // 检查定位权限
  110. var status = await Permission.location.status;
  111. if (status != PermissionStatus.granted) {
  112. //未授权 申请定位权限
  113. status = await Permission.location.request();
  114. if (status != PermissionStatus.granted) {
  115. // 未授权 提示用户去设置
  116. MyNavigator.showToast('请打开APP的定位权限');
  117. showSettingDialog(
  118. title: '定位权限',
  119. content: '为了APP能使用位置功能,您在系统设置中授权APP的定位权限。',
  120. onTap: openAppSettings,
  121. );
  122. return false;
  123. }
  124. }
  125. // 检查系统定位开关
  126. bool locationEnable = await Permission.location.serviceStatus.isEnabled;
  127. if (!locationEnable) {
  128. showSettingDialog(
  129. title: '定位功能',
  130. content: '为了APP能使用位置功能,您在系统设置中打开定位开关。',
  131. onTap: () => AppSettings.openAppSettings(type: AppSettingsType.location),
  132. );
  133. return false;
  134. }
  135. return true;
  136. }
  137. static void showSettingDialog({String? title, String? content, VoidCallback? onTap}) {
  138. MyNavigator.showDialog(
  139. tag: 'setting',
  140. builder: (_) => AlertDialog(
  141. title: title != null ? Text(title) : null,
  142. content: content != null ? Text(content) : null,
  143. actions: [
  144. MyButton(
  145. '去设置',
  146. alignment: null,
  147. backgroundColor: const Color(0xFFCE615A),
  148. onTap: () {
  149. onTap?.call();
  150. MyNavigator.dismiss(tag: 'setting');
  151. },
  152. ),
  153. MyButton('取消', alignment: null, onTap: () => MyNavigator.dismiss(tag: 'setting')),
  154. ],
  155. ),
  156. );
  157. }
  158. }