admin
2021-12-03 f092e392700f68cdbfc545c9801f530d19fd39fa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import 'dart:async';
 
import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart';
import 'package:flutter_bmflocation/bdmap_location_flutter_plugin.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_android_option.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_ios_option.dart';
import 'package:locations/api/http.dart';
import 'package:locations/model/map/location_model.dart';
import 'package:locations/utils/permission_util.dart';
import 'package:locations/utils/user_util.dart';
import 'package:permission_handler/permission_handler.dart';
 
import 'global.dart';
 
typedef OnLocationCallback = void Function(LocationState state, Map? map);
 
class LocationUtil {
  static LocationFlutterPlugin? _locationFlutterPlugin =
      LocationFlutterPlugin();
 
  static Map _getAndroidOption(int scanspan) {
    BaiduLocationAndroidOption androidOption = new BaiduLocationAndroidOption();
    androidOption.setCoorType("bd09ll");
 
    /// 可选,设置返回经纬度坐标类型,默认gcj02
    /// gcj02:国测局坐标;
    /// bd09ll:百度经纬度坐标;
    /// bd09:百度墨卡托坐标;
    /// 海外地区定位,无需设置坐标类型,统一返回wgs84类型坐标
    androidOption.setIsNeedAltitude(true);
 
    /// 可选,设置是否需要返回海拔高度信息,true为需要返回
    androidOption.setIsNeedAddres(false);
 
    /// 可选,设置是否需要返回地址信息,true为需要返回
    androidOption.setIsNeedLocationPoiList(false);
 
    /// 可选,设置是否需要返回周边poi信息,true为需要返回
    androidOption.setIsNeedNewVersionRgc(false);
 
    /// 可选,设置是否需要返回新版本rgc信息,true为需要返回
    androidOption.setIsNeedLocationDescribe(true);
 
    /// 可选,设置是否需要返回位置描述信息,true为需要返回
    androidOption.setOpenGps(true);
 
    /// 可选,设置是否需要使用gps,true为需要使用
    androidOption.setLocationMode(LocationMode.Hight_Accuracy);
 
    /// 可选,设置定位模式,可选的模式有高精度、低功耗、仅设备,默认为高精度模式,可选值如下:
    /// 高精度模式: LocationMode.Hight_Accuracy
    /// 低功耗模式:LocationMode.Battery_Saving
    /// 仅设备(Gps)模式:LocationMode.Device_Sensors
    androidOption.setScanspan(scanspan);
 
    /// 可选,设置发起定位请求的间隔,int类型,单位ms
    /// 如果设置为0,则代表单次定位,即仅定位一次,默认为0
    /// 如果设置非0,需设置1000ms以上才有效
    androidOption.setLocationPurpose(BDLocationPurpose.Sport);
 
    /// 可选,设置场景定位参数,包括签到场景、运动场景、出行场景,可选值如下:
    /// 签到场景: BDLocationPurpose.SignIn
    /// 运动场景: BDLocationPurpose.Transport
    /// 出行场景: BDLocationPurpose.Sport
    return androidOption.getMap();
  }
 
  static Map _getIosOption() {
    BaiduLocationIOSOption iosOption = new BaiduLocationIOSOption();
 
    iosOption.setIsNeedNewVersionRgc(true);
 
    /// 可选,设置是否需要返回新版本rgc信息,true为需要返回
 
    iosOption.setBMKLocationCoordinateType("BMKLocationCoordinateTypeBMK09LL");
 
    ///  可选,设置返回位置的坐标系类型 ,参数为String类型,可选值如下:
    /// "BMKLocationCoordinateTypeBMK09LL" 百度经纬度坐标
    /// "BMKLocationCoordinateTypeBMK09MC" 百度墨卡托坐标
    /// "BMKLocationCoordinateTypeWGS84"  gps坐标
    /// "BMKLocationCoordinateTypeGCJ02" 国测局坐标
 
    iosOption.setActivityType("CLActivityTypeAutomotiveNavigation");
 
    /// 可选,设置应用位置类型,参数为String类型,可选值如下:
    /// "CLActivityTypeOther"
    /// "CLActivityTypeAutomotiveNavigation"
    /// "CLActivityTypeFitness"
    /// "CLActivityTypeOtherNavigation"
 
    iosOption.setDesiredAccuracy("kCLLocationAccuracyBest");
 
    /// 可选,设置期望定位精度,参数为String类型,可选值如下:
    /// "kCLLocationAccuracyBest"
    /// "kCLLocationAccuracyNearestTenMeters"
    /// "kCLLocationAccuracyHundredMeters"
    /// "kCLLocationAccuracyKilometer"
 
    iosOption.setLocationTimeout(10);
 
    /// 可选,设置位置获取超时时间,参数为int类型
 
    iosOption.setReGeocodeTimeout(10);
 
    /// 可选,设置获取rgc信息超时时间,参数为int类型
 
    iosOption.setPauseLocUpdateAutomatically(true);
 
    /// 可选,指定定位是否会被系统自动暂停,参数为bool类型
    /// true表示定位会被系统自动暂停,false表示不会
 
    iosOption.setAllowsBackgroundLocationUpdates(true);
 
    /// 可选,设置是否允许后台定位,参数为bool类型
    /// true表示允许后台定位,false表示不允许后台定位
 
    iosOption.setDistanceFilter(10);
 
    /// 可选,设置定位的最小更新距离,参数为double类型
    return iosOption.getMap();
  }
 
  static Future<StreamSubscription<Map<String, Object>?>?> startLocation(
      int scanSpan, OnLocationCallback callback) async {
    final status = await requestLocationPermission();
    if (status.isGranted) {
      print("定位权限申请通过");
    } else {
      print("定位权限申请不通过");
      callback(LocationState.permission_denied, null);
      return null;
    }
 
    StreamSubscription<Map<String, Object>?> subscription =
        _locationFlutterPlugin!
            .onResultCallback()
            .listen((Map<String, Object>? result) {
      print("定位结果:$result");
      Global.currentPosition = BMFCoordinate.fromMap(result!);
      UserUtil.isLogin().then((value) {
        if (value) {
          LocationApiUtil.uploadLocation(BaiduLocation.fromJson(result));
        }
      });
 
      callback(LocationState.success, result);
      if (scanSpan == 0) {
        stopLocation();
      }
    });
 
    _locationFlutterPlugin!
        .prepareLoc(_getAndroidOption(scanSpan), _getIosOption());
 
    _locationFlutterPlugin!.startLocation();
 
    return subscription;
  }
 
  ///请求定位权限
  static Future<PermissionStatus> requestLocationPermission() async {
    final status = await PermissionUtil.openPermission(Permission.locationAlways);
    return status;
  }
 
  static stopLocation() {
    if (_locationFlutterPlugin != null) {
      _locationFlutterPlugin!.stopLocation();
    }
  }
}
 
enum LocationState { success, permission_denied }