123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- 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初始化时设置<br>
- ///apiKey的申请请参考高德开放平台官网<br>
- ///Android端: https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key<br>
- ///iOS端: https://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key<br>
- ///[androidKey] Android平台的key<br>
- ///[iosKey] ios平台的key<br>
- static void setApiKey(String androidKey, String iosKey) {
- AMapFlutterLocation.setApiKey(androidKey, iosKey);
- }
- /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作<br>
- /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy<br>
- /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b><br>
- /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
- /// [hasContains] 隐私声明中是否包含高德隐私政策说明<br>
- /// [hasShow] 隐私权政策是否弹窗展示告知用户<br>
- static void updatePrivacyShow(bool hasContains, bool hasShow) {
- AMapFlutterLocation.updatePrivacyShow(hasContains, hasShow);
- }
- /// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作<br>
- /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy<br>
- /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b><br>
- /// [hasAgree] 隐私权政策是否已经取得用户同意<br>
- 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<Map<String, Object>> onLocationChanged() {
- // return location.onLocationChanged().asBroadcastStream();
- // }
- static Stream<Map<String, Object>> onLocationChanged() {
- if (_locationChange == null) {
- _locationChange = StreamController.broadcast();
- _locationListener = location.onLocationChanged().listen((event) => _locationChange?.add(event));
- }
- return _locationChange!.stream;
- }
- static StreamController<Map<String, Object>>? _locationChange;
- static StreamSubscription<Map<String, Object>>? _locationListener;
- static void cancelLocationListener() {
- _locationListener?.cancel();
- _locationListener = null;
- _locationChange?.close();
- _locationChange = null;
- }
- /// 检查定位是否可用
- /// 1.app定位权限
- /// 2.系统定位开关
- static Future<bool> 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')),
- ],
- ),
- );
- }
- }
|