HWLocationUtils.ets 7.9 KB
import { abilityAccessCtrl, bundleManager, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { geoLocationManager } from '@kit.LocationKit';
import { SpConstants } from 'wdConstant/Index';
import { EmitterEventId, EmitterUtils, Logger, PermissionUtils, ResourcesUtils, SPHelper } from 'wdKit/Index';
import { ResponseDTO } from 'wdNetwork/Index';

const TAG = "HWLocationUtils"
/**
 * 系统定位服务实现
 * */
export class HWLocationUtils {
  static LOCATION: Permissions = 'ohos.permission.LOCATION'
  static APPROXIMATELY_LOCATION: Permissions = 'ohos.permission.APPROXIMATELY_LOCATION'

  private static getLocation() {
    let requestInfo: geoLocationManager.LocationRequest = {
      'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
      'scenario': geoLocationManager.LocationRequestScenario.UNSET,
      distanceInterval: 0,
      timeInterval: 60,
      maxAccuracy: 0
    };
    geoLocationManager.on('locationChange', requestInfo, (data) => {
      Logger.debug(TAG, JSON.stringify(data))
    })
  }

  private static getLocationData() {
    return new Promise<Record<string, string | number>>((success, fail) => {
      let requestInfo: geoLocationManager.LocationRequest = {
        'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
        'scenario': geoLocationManager.LocationRequestScenario.DAILY_LIFE_SERVICE,
        distanceInterval: 0,
        timeInterval: 60,
        maxAccuracy: 0
      };
      geoLocationManager.on('locationChange', requestInfo, (data) => {
        Logger.debug(TAG, JSON.stringify(data)) //{"latitude":31.86870096,"longitude":117.3015341,"altitude":0,"accuracy":5000,"speed":0,"timeStamp":1713332445643,"direction":0,"timeSinceBoot":589519570869240,"additions":"","additionSize":0}
        let record: Record<string, string | number> = {};
        record['latitude'] = data.latitude
        record['longitude'] = data.longitude
        success(record)
      })
    })
  }

  //开启定位服务
  static async startLocationService() {
    let grant = await PermissionUtils.checkPermissions(HWLocationUtils.APPROXIMATELY_LOCATION)
    if (grant) {
      HWLocationUtils.getCurrentLocation()
      return
    }
    let context = getContext();
    let per=SPHelper.default.getSync(SpConstants.LOCATION_PERMISSION_REFUSE,false)
    if(!per){
      EmitterUtils.sendEmptyEvent(EmitterEventId.LOCATION)
      SPHelper.default.save(SpConstants.LOCATION_PERMISSION_REFUSE,true)
    }
    let requestGrant = await PermissionUtils.reqPermissionsFromUser([HWLocationUtils.APPROXIMATELY_LOCATION], context);
    Logger.debug('location2 :' + requestGrant)
    if (requestGrant) {
      HWLocationUtils.getCurrentLocation()
    } else {
      // PermissionUtils.openPermissionsInSystemSettings(context)
    }
  }

  private static getCurrentLocation() {
    let requestInfo: geoLocationManager.CurrentLocationRequest = {
      'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
      'scenario': geoLocationManager.LocationRequestScenario.DAILY_LIFE_SERVICE,
      'maxAccuracy': 0
    };
    try {
      geoLocationManager.getCurrentLocation(requestInfo).then((result) => {
        //{"latitude":31.8687047,"longitude":117.30152005,"altitude":0,"accuracy":5000,"speed":0,"timeStamp":1713331875766,"direction":0,"timeSinceBoot":588949694096931,"additions":"","additionSize":0}
        Logger.debugOptimize('location', () => {
          return JSON.stringify(result)
        })
        HWLocationUtils.getReverseGeoCodeRequest(result.latitude, result.longitude)
      })
        .catch((error: number) => {
          Logger.error(TAG, JSON.stringify(error))
        });
    } catch (err) {
      Logger.error(TAG, JSON.stringify(err))
    }
  }

  private static getGeoCodeRequest(description: string) {
    let requestInfo: geoLocationManager.GeoCodeRequest = { 'description': description };
    geoLocationManager.getAddressesFromLocationName(requestInfo, (error, data) => {
      if (data) {
        Logger.debug(TAG, JSON.stringify(data))
      }
      //[{"latitude":31.898204927828598,"longitude":117.29702564819466,"locale":"zh","placeName":"安徽省合肥市瑶海区白龙路与北二环路辅路交叉口南20米","countryCode":"CN","countryName":"中国","administrativeArea":"安徽省","subAdministrativeArea":"合肥市","locality":"合肥市","subLocality":"瑶海区","roadName":"白龙路与北二环路辅路","subRoadName":"20","premises":"20","postalCode":"","phoneNumber":"18756071597","addressUrl":"","descriptionsSize":0,"isFromMock":false}]
    })
  }

  private static getReverseGeoCodeRequest(latitude: number, longitude: number) {
    let requestInfo: geoLocationManager.ReverseGeoCodeRequest = {
      "latitude": latitude,
      "longitude": longitude,
      "maxItems": 2
    };
    geoLocationManager.getAddressesFromLocation(requestInfo, async (error, data) => {
      if (error) {
        Logger.error(TAG, JSON.stringify(error))
      }
      if (data) {
        Logger.debugOptimize(TAG, () => {
          return JSON.stringify(data)
        })
        if (data[0] && data[0].administrativeArea && data[0].subAdministrativeArea) {
          let cityName = data[0].subAdministrativeArea;
          let name = await SPHelper.default.get(SpConstants.LOCATION_CITY_NAME, '') as string
          if (cityName == name) {
            return
          }
          // code=[省份code,城市code]
          let code: string[] = await HWLocationUtils.getCityCode(data[0].administrativeArea, data[0].subAdministrativeArea)
          if (code && code.length >= 2) {
            SPHelper.default.save(SpConstants.LOCATION_CITY_NAME, cityName)
            SPHelper.default.save(SpConstants.LOCATION_PROVINCE_NAME, data[0].administrativeArea)
            SPHelper.default.save(SpConstants.LOCATION_PROVINCE_CODE, code[0])
            SPHelper.default.save(SpConstants.LOCATION_CITY_CODE, code[1])
          }
          if (data[0].descriptions && data[0].descriptions.length > 1) {
            // 保存区县code,9位数字
            let districtCode = data[0].descriptions[1] || ''
            SPHelper.default.save(SpConstants.LOCATION_DISTRICT_CODE, districtCode)
          }
        }
      }
    })
  }

  //取消定位
  static cancelLocation() {
    // geoLocationManager.off('locationChange')
    return new Promise<boolean>((success, fail) => {
      geoLocationManager.off("locationChange", (data) => {
        Logger.debug(TAG, JSON.stringify(data))
        success(true)
      })
    })
  }

  private static async getCityCode(administrativeArea: string, cityName: string) {
    let bean = await ResourcesUtils.getResourcesJson<ResponseDTO<Array<LocalData>>>(getContext(), 'areaList_data.json');
    if (bean) {
      if (bean.code == 0 && bean.data) {
        for (let i = 0; i < bean.data.length; i++) {
          if (bean.data[i].label == administrativeArea) {
            let str:string[] = []
            let provinceCode = bean.data[i].code
            str[0] = provinceCode
            for (let j = 0; j < bean.data[i].children.length; j++) {
              if (bean.data[i].children[j].label == cityName) {
                Logger.debug("huaw" + bean.data[i].children[j].code)
                str[1] = bean.data[i].children[j].code
                return str
              }
            }
          }

        }

      }
    }
    return []
  }

  // 通过省份code获取省份名称
  static async getProvinceName(provinceCode: string) {
    let bean = await ResourcesUtils.getResourcesJson<ResponseDTO<Array<LocalData>>>(getContext(), 'areaList_data.json');
    if (bean) {
      if (bean.code == 0 && bean.data) {
        for (let i = 0; i < bean.data.length; i++) {
          if (bean.data[i].code == provinceCode) {
             return bean.data[i].label
          }
        }
      }
    }
    return ''
  }

}

interface LocalData {
  "code": string,
  "id": string,
  "label": string,
  "children": Array<ChildrenData>
}

interface ChildrenData {
  "code": string,
  "id": string,
  "label": string,
}