admin
2022-01-12 8327000a0cce5e47226372e0e25c1e6faec497e7
lib/utils/location_util.dart
@@ -1,127 +1,26 @@
import 'dart:async';
import 'dart:convert';
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:flutter/services.dart';
import 'package:locations/api/http.dart';
import 'package:locations/model/map/location_model.dart';
import 'package:locations/model/user/user_info.dart';
import 'package:locations/utils/permission_util.dart';
import 'package:locations/utils/string_util.dart';
import 'package:locations/utils/ui_utils.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);
typedef OnLocationCallback = void Function(
    LocationState state, SimpleLocation? map);
class LocationUtil {
  static LocationFlutterPlugin? _locationFlutterPlugin =
      LocationFlutterPlugin();
  static const messageChannel =
      BasicMessageChannel('LocationUtil', StandardMessageCodec());
  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 {
  static Future startLocation(int scanSpan, OnLocationCallback callback) async {
    final status = await requestLocationPermission();
    if (status.isGranted) {
      print("定位权限申请通过");
@@ -131,42 +30,57 @@
      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));
    dynamic value = await messageChannel.send("");
    if (value != null) {
      try {
        Map<String, dynamic> valueMap = jsonDecode(jsonEncode(value));
        double lat = double.parse(valueMap["lat"]!.toString());
        double lng = double.parse(valueMap["lng"]!.toString());
        String? address;
        String? addressDetail;
        if (valueMap["address"] != null) {
          address = valueMap["address"].toString();
        }
      });
      callback(LocationState.success, result);
      if (scanSpan == 0) {
        stopLocation();
        if (valueMap["addressDetail"] != null) {
          addressDetail = valueMap["addressDetail"].toString();
        }
        if (StringUtil.isNullOrEmpty(address)) {
          Map<String, dynamic>? map = await LocationApiUtil.geoCode(lat, lng);
          if (map!["code"] == 0) {
            String? address = map["data"];
            Global.currentPosition = SimpleLocation(
                latitude: lat,
                longitude: lng,
                address: address,
                addressDetail: addressDetail);
          }
        } else {
          Global.currentPosition = SimpleLocation(
              latitude: lat,
              longitude: lng,
              address: address,
              addressDetail: addressDetail);
        }
        UserUtil.isLogin().then((value) {
          if (value) {
            LocationApiUtil.uploadLocation(Global.currentPosition!);
          }
        });
        callback(LocationState.success, Global.currentPosition!);
      } catch (e) {
        // ToastUtil.toast("位置处理异常:$e");
      }
    });
    _locationFlutterPlugin!
        .prepareLoc(_getAndroidOption(scanSpan), _getIosOption());
    _locationFlutterPlugin!.startLocation();
    return subscription;
    }
  }
  ///请求定位权限
  static Future<PermissionStatus> requestLocationPermission() async {
    final status = await PermissionUtil.openPermission(PermissionUtil.getLocationPermission());
    final status = await PermissionUtil.openPermission(
        PermissionUtil.getLocationPermission());
    return status;
  }
  static stopLocation() {
    if (_locationFlutterPlugin != null) {
      _locationFlutterPlugin!.stopLocation();
    }
  }
}