import 'dart:async'; import 'package:amap_flutter_location/amap_flutter_location.dart'; import 'package:amap_flutter_location/amap_location_option.dart'; import 'package:app_settings/app_settings.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import '../router/my_navigator.dart'; import '../widget/button.dart'; class LocationUtils { LocationUtils._(); ///设置Android和iOS的apikey,建议在weigdet初始化时设置
///apiKey的申请请参考高德开放平台官网
///Android端: https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key
///iOS端: https://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key
///[androidKey] Android平台的key
///[iosKey] ios平台的key
static void setApiKey(String androidKey, String iosKey) { AMapFlutterLocation.setApiKey(androidKey, iosKey); } /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
/// 必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy /// [hasContains] 隐私声明中是否包含高德隐私政策说明
/// [hasShow] 隐私权政策是否弹窗展示告知用户
static void updatePrivacyShow(bool hasContains, bool hasShow) { AMapFlutterLocation.updatePrivacyShow(hasContains, hasShow); } /// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
/// 必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意
/// [hasAgree] 隐私权政策是否已经取得用户同意
static void updatePrivacyAgree(bool hasAgree) { AMapFlutterLocation.updatePrivacyAgree(hasAgree); } static AMapFlutterLocation? _location; static AMapFlutterLocation get location => _location ??= AMapFlutterLocation(); /// 设置定位参数 static AMapFlutterLocation setLocationOption(AMapLocationOption option) { location.setLocationOption(option); return location; } ///开始定位 static AMapFlutterLocation startLocation() { location.startLocation(); return location; } ///停止定位 static AMapFlutterLocation stopLocation() { location.stopLocation(); return location; } ///销毁定位 static void destroy() { location.destroy(); cancelLocationListener(); _location = null; } ///定位结果回调 /// ///定位结果以map的形式透出,其中包含的key已经含义如下: /// /// `callbackTime`:回调时间,格式为"yyyy-MM-dd HH:mm:ss" /// /// `locationTime`:定位时间, 格式为"yyyy-MM-dd HH:mm:ss" /// /// `locationType`: 定位类型, 具体类型可以参考https://lbs.amap.com/api/android-location-sdk/guide/utilities/location-type /// /// `latitude`:纬度 /// /// `longitude`:精度 /// /// `accuracy`:精确度 /// /// `altitude`:海拔, android上只有locationType==1时才会有值 /// /// `bearing`: 角度,android上只有locationType==1时才会有值 /// /// `speed`:速度, android上只有locationType==1时才会有值 /// /// `country`: 国家,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `province`: 省,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `city`: 城市,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `district`: 城镇(区),android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `street`: 街道,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `streetNumber`: 门牌号,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `cityCode`: 城市编码,android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `adCode`: 区域编码, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `address`: 地址信息, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `description`: 位置语义, android上只有通过[AMapLocationOption.needAddress]为true时才有可能返回值 /// /// `errorCode`: 错误码,当定位失败时才会返回对应的错误码, 具体错误请参考:https://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode /// /// `errorInfo`: 错误信息, 当定位失败时才会返回 // static Stream> onLocationChanged() { // return location.onLocationChanged().asBroadcastStream(); // } static Stream> onLocationChanged() { if (_locationChange == null) { _locationChange = StreamController.broadcast(); _locationListener = location.onLocationChanged().listen((event) => _locationChange?.add(event)); } return _locationChange!.stream; } static StreamController>? _locationChange; static StreamSubscription>? _locationListener; static void cancelLocationListener() { _locationListener?.cancel(); _locationListener = null; _locationChange?.close(); _locationChange = null; } /// 检查定位是否可用 /// 1.app定位权限 /// 2.系统定位开关 static Future checkLocationAvailable() async { // 检查定位权限 var status = await Permission.location.status; if (status != PermissionStatus.granted) { //未授权 申请定位权限 status = await Permission.location.request(); if (status != PermissionStatus.granted) { // 未授权 提示用户去设置 MyNavigator.showToast('请打开APP的定位权限'); showSettingDialog( title: '定位权限', content: '为了APP能使用位置功能,您在系统设置中授权APP的定位权限。', onTap: openAppSettings, ); return false; } } // 检查系统定位开关 bool locationEnable = await Permission.location.serviceStatus.isEnabled; if (!locationEnable) { showSettingDialog( title: '定位功能', content: '为了APP能使用位置功能,您在系统设置中打开定位开关。', onTap: () => AppSettings.openAppSettings(type: AppSettingsType.location), ); return false; } return true; } static void showSettingDialog({String? title, String? content, VoidCallback? onTap}) { MyNavigator.showDialog( tag: 'setting', builder: (_) => AlertDialog( title: title != null ? Text(title) : null, content: content != null ? Text(content) : null, actions: [ MyButton( '去设置', alignment: null, backgroundColor: const Color(0xFFCE615A), onTap: () { onTap?.call(); MyNavigator.dismiss(tag: 'setting'); }, ), MyButton('取消', alignment: null, onTap: () => MyNavigator.dismiss(tag: 'setting')), ], ), ); } }