/  注册高德地图 (安卓)  /

Android  Studio 创建签名文件

Android 应用签名

Signed APK

Generate Signed Bundle or Apk

 创建密钥 (Create New Key Store)  签署您的应用程序

 创建签名

 密钥

 证书

 创建密钥并存储到制定的路径 

密钥创建内容

创建应用并生成key

注册高德地图开发者账户 Android 如何获取 SHA1 值?

/  获取定位信息  / 

集成高德定位Flutter插件 

打开 pubspec.yaml 文件 添加 amap_flutter_location (高德定位)permission_handler (应用权限)、app_settings (app权限设置) location_service_check (是否开通gps) 插件依赖配置

amap_flutter_location: any # 高德Flutter定位插件
permission_handler: any #应用权限
app_settings: any #app权限设置
location_service_check: any #是否开通GPS

 判断是否开启定位权限

/// 申请定位权限
/// 授予定位权限返回true, 否则返回false
Future<bool> requestLocationPermission() async {
  //获取当前的权限
  var status = await Permission.location.status;
  if (status == PermissionStatus.granted) {
    //已经授权
    return true;
  } else {
    //未授权则发起一次申请
    status = await Permission.location.request();
    if (status == PermissionStatus.granted) {
      return true;
    } else {
      return false;
    }
  }
}

 判断是否开启GPS

...

 bool _isOpenGps = await LocationServiceCheck.checkLocationIsOpen;
    if(!_isOpenGps) {
      logV("定位权限申请通过");
      AppSettings.openLocationSettings();
    }

...

动态申请定位权限

/// 动态申请定位权限
Future<bool> requestPermission() async {
  // 申请权限
  bool hasLocationPermission = await requestLocationPermission();
  if (hasLocationPermission) {
    bool _isOpenGps = await LocationServiceCheck.checkLocationIsOpen;
    if(!_isOpenGps) {
      logV("定位权限申请通过");
      AppSettings.openLocationSettings();
    }
    return _isOpenGps;
  } else {
    logV("定位权限申请不通过");
    // 跳转到系统设置页
    AppSettings.openAppSettings();
  }
  return hasLocationPermission;
}

高德地图初始化 

StreamSubscription<Map<String, Object>>? _locationListener;
AMapFlutterLocation? _locationPlugin = AMapFlutterLocation();
void amapLocaitonInit(IMapLocationResultCallBack? locationResultCallBack) {
  AMapFlutterLocation.updatePrivacyShow(true, true);
  AMapFlutterLocation.updatePrivacyAgree(true);
  AMapFlutterLocation.setApiKey("c9856efd6bae11ff6897cffede9af428", "");

  ///iOS 获取native精度类型
  if (Platform.isIOS) {
    requestAccuracyAuthorization();
  }
  ///注册定位结果监听
  _locationListener = _locationPlugin!
      .onLocationChanged()
      .listen((Map<String, Object>? result) {
    locationResultCallBack!(result);
  });
}

开始定位

///开始定位
void startLocation() async {
  /// 检查是否开启GSP和定位权限
  bool hasLocationPermission = await requestPermission();
  if (hasLocationPermission) {
    _setLocationOption();
    _locationPlugin!.startLocation();
  }
}

停止定位 

为了让定位不一直执行,当获取到定位数据时可以停止定位

///停止定位
void stopLocation() {
  _locationPlugin!.stopLocation();
}

销毁定位 

void amapLocationDispose() {
  ///移除定位监听
  if (null != _locationListener) {
    _locationListener!.cancel();
  }

  ///销毁定位
  if (null != _locationPlugin) {
    _locationPlugin!.destroy();
  }
}

/  定位数据创建MySQL表  / 

高德地图定位获取到的数据转换成Json字符串并用创建的.json文件保存起来,方便使用Navicat Preminum 生成表 。

 

 

 

 

 /  个人位置信息插入、修改  /

创建LocationMapper.xml

里面存放了SQL查询的语句 (插入用户位置信息 、根据userId查询用户位置信息 、修改用户位置信息)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xm.chat.dao.LocationMapper">

    <resultMap type="com.xm.chat.entity.admin.Location" id="BaseResultMap">
        <result property="callbackTime" column="callbackTime"/>
        <result property="locationTime" column="locationTime"/>
        <result property="locationType" column="locationType"/>
        <result property="latitude" column="latitude"/>
        <result property="longitude" column="longitude"/>
        <result property="accuracy" column="accuracy"/>
        <result property="altitude" column="altitude"/>
        <result property="bearing" column="bearing"/>
        <result property="speed" column="speed"/>
        <result property="country" column="country"/>
        <result property="province" column="province"/>
        <result property="city" column="city"/>
        <result property="district" column="district"/>
        <result property="street" column="street"/>
        <result property="streetNumber" column="streetNumber"/>
        <result property="cityCode" column="cityCode"/>
        <result property="adCode" column="adCode"/>
        <result property="address" column="address"/>
        <result property="description" column="description"/>
        <result property="user_id" column="user_id"/>
    </resultMap>

    <!-- 插入用户位置信息 -->
    <insert id="editUserLocation" parameterType="com.xm.chat.entity.admin.Location">
    insert into tb_location(callbackTime,locationTime,locationType,latitude,longitude,accuracy,altitude,
                         bearing,speed,country,province,city,district,street,streetNumber,cityCode,
                         adCode,address,description,user_id
    )values(#{callbackTime},#{locationTime},#{locationType}
    ,#{latitude},#{longitude},#{accuracy},#{altitude},#{bearing},
    #{speed},#{country},#{province},#{city},#{district},#{street},#{streetNumber},#{cityCode},#{adCode}
           ,#{address},#{description},#{user_id})
    </insert>

    <!-- 根据userId查询用户位置信息 -->
    <select id="selectByUserIdCount" parameterType="String" resultMap="BaseResultMap">
        select *
        from tb_location
        where user_id = #{user_id}
    </select>

    <!-- 修改用户位置信息 -->
    <update id="updateByUserIdLocation" parameterType="com.xm.chat.entity.admin.Location">
    update tb_location set callbackTime=#{callbackTime},locationTime=#{locationTime},locationType=#{locationType}
                      ,latitude=#{latitude},longitude=#{longitude},accuracy=#{accuracy},altitude=#{altitude},bearing=#{bearing},
        speed=#{speed},country=#{country},province=#{province},city=#{city},district=#{district},street=#{street},streetNumber=#{streetNumber},
        cityCode=#{cityCode},adCode=#{adCode},address=#{address},description=#{description},user_id=#{user_id}
    where user_id=#{user_id}
    </update>
</mapper>

创建LocationService 并实现

package com.xm.chat.service.admin;

import com.xm.chat.entity.admin.Intro;
import com.xm.chat.entity.admin.Location;

public interface LocationService {

    String editUserLocation(Location location);

    Location selectByUserIdCount(String userId);

    String updateByUserIdIntro(Location location);
}
package com.xm.chat.service.admin.impl;

import com.xm.chat.common.ServiceResultEnum;
import com.xm.chat.dao.LocationMapper;
import com.xm.chat.entity.admin.Location;
import com.xm.chat.service.admin.LocationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class LocationServiceImpl implements LocationService {

    @Autowired
    private LocationMapper locationMapper;

    @Override
    public String editUserLocation(Location location) {
        if (locationMapper.editUserLocation(location) > 0) {
            return ServiceResultEnum.SUCCESS.getResult();
        }
        return ServiceResultEnum.DB_ERROR.getResult();
    }

    @Override
    public Location selectByUserIdCount(String userId) {
        return locationMapper.selectByUserIdCount(userId);
    }

    @Override
    public String updateByUserIdIntro(Location location) {
        if (locationMapper.updateByUserIdLocation(location) > 0) {
            return ServiceResultEnum.SUCCESS.getResult();
        }
        return ServiceResultEnum.DB_ERROR.getResult();
    }
}

 创建 LocationMapper

package com.xm.chat.dao;

import com.xm.chat.entity.admin.Location;

public interface LocationMapper {

    /**
     * 编辑用户位置信息
     * @param location
     * @return
     */
    int editUserLocation(Location location);

    /**
     * 根据userId查询是否存在用户位置信息
     * @param userId
     * @return
     */
    Location selectByUserIdCount(String userId);

    /**
     * 根据userId修改用户位置信息
     * @param location
     * @return
     */
    int updateByUserIdLocation(Location location);
}

 创建LocationController

package com.xm.chat.controller.admin;

import com.xm.chat.common.ServiceResultEnum;
import com.xm.chat.entity.admin.Location;
import com.xm.chat.service.admin.LocationService;
import com.xm.chat.util.JwtUtils;
import com.xm.chat.util.Result;
import com.xm.chat.util.ResultGenerator;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

@Controller
@RequestMapping("/admin")
public class LocationController {

    @Resource
    LocationService locationService;

    ///编辑位置信息
    @RequestMapping(value = "/edit/location", method = RequestMethod.POST)
    @ResponseBody
    public Result editIntro(HttpServletRequest request,
                            @ModelAttribute Location intro) {
        if (Objects.isNull(intro)) {
            return ResultGenerator.genFailResult("参数异常!");
        }
        // 用户ID
        String userId =JwtUtils.getClaimUserId(request);
        intro.setUser_id(userId);
        Location locationResult = locationService.selectByUserIdCount(userId);
        if (locationResult != null) {
            /// 修改位置信息
            String result = locationService.updateByUserIdIntro(intro);
            if (ServiceResultEnum.SUCCESS.getResult().equals(result)) {
                return ResultGenerator.genSuccessResult();
            } else {
                return ResultGenerator.genFailResult(result);
            }
        } else {
            /// 插入位置信息
            String result = locationService.editUserLocation(intro);
            if (ServiceResultEnum.SUCCESS.getResult().equals(result)) {
                return ResultGenerator.genSuccessResult();
            } else {
                return ResultGenerator.genFailResult(result);
            }
        }
    }

}

模拟请求 

/  附近所有人的位置信息  /

创建 NearPerMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xm.chat.dao.NearPerMapper">

    <resultMap type="com.xm.chat.entity.near.NearPer" id="BaseResultMap">
        <result property="intro.id" column="id"/>
        <result property="intro.head" column="head"/>
        <result property="intro.nick_name" column="nick_name"/>
        <result property="intro.city" column="city"/>
        <result property="intro.birthday" column="birthday"/>
        <result property="intro.job" column="job"/>
        <result property="intro.make_fir_pur" column="make_fir_pur"/>
        <result property="intro.expect" column="expect"/>
        <result property="intro.wx_account" column="wx_account"/>
        <result property="intro.is_hide_wx" column="is_hide_wx"/>
        <result property="intro.height" column="height"/>
        <result property="intro.weight" column="weight"/>
        <result property="intro.per_intro" column="per_intro"/>
        <result property="intro.user_id" column="user_id"/>
        <result property="action.id" column="id"/>
        <result property="action.cur_loc" column="cur_loc"/>
        <result property="action.is_face_rec" column="is_face_rec"/>
        <result property="action.las_onl_time" column="las_onl_time"/>
        <result property="action.user_id" column="user_id"/>
        <result property="faceRec.id" column="id"/>
        <result property="faceRec.user_id" column="user_id"/>
        <result property="faceRec.pic" column="pic"/>
        <result property="faceRec.video" column="video"/>
        <result property="location.latitude" column="latitude"/>
        <result property="location.longitude" column="longitude"/>
        <result property="location.city" column="city"/>
        <result property="location.locationTime" column="locationTime"/>
        <result property="location.distance" column="distance"/>


    </resultMap>
    <select id="findNerPerList" parameterType="Map" resultMap="BaseResultMap">

        select *, round( 6378.138 * 2 * asin( sqrt( pow( sin(( #{latitude} * pi() / 180 - latitude * pi() / 180 ) / 2 ),
        2 ) +
        cos( #{latitude} * pi() / 180) * cos(latitude * pi() / 180) * pow( sin(( #{longitude} * pi() / 180 - longitude *
        pi() / 180 ) / 2
        ), 2 ))) * 1000 ) AS distance FROM (select * from tb_intro
        <if test="start!=null and limit!=null">
            limit #{start},#{limit}
        </if>) as tbintro left join tb_action on (tbintro.user_id=tb_action.user_id)
        left join tb_face_rec on (tbintro.user_id=tb_face_rec.user_id)
        left join tb_location on (tbintro.user_id=tb_location.user_id) ORDER BY distance ASC LIMIT 10

    </select>

</mapper>

根据经纬度计算距离排序、分页 

通过当前你所在位置的 经纬度 和其他所有人的 经纬度 进行距离的计算

SELECT *, round( 6378.138 * 2 * asin( sqrt( pow( sin(( 当前你所在位置的纬度 * pi() / 
180 - 其他人所在位置的维度 * pi() / 180 ) / 2 ), 2 ) + cos( 当前你所在位置的纬度 * pi() / 
180) * cos( 其他人所在位置的维度 * pi() / 180) * pow( sin(( 当前你所在位置的经度 * pi() / 
180 - 其他人所在位置的经度 * pi() / 180 ) / 2 ), 2 ))) * 1000 ) AS distance FROM 数据表 
ORDER BY distance ASC LIMIT 10;

创建 NearPerService 并实现

package com.xm.chat.service.near;
import com.xm.chat.util.PageQueryUtil;
import com.xm.chat.util.PageResult;
public interface NearPerService {
    /**
     * 附近 分页
     * @param pageUtil
     * @return
     */
    PageResult getNearPerPage(PageQueryUtil pageUtil);
}
package com.xm.chat.service.near.impl;
import com.xm.chat.dao.NearPerMapper;
import com.xm.chat.entity.near.NearPer;
import com.xm.chat.service.near.NearPerService;
import com.xm.chat.util.PageQueryUtil;
import com.xm.chat.util.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class NearPerServiceImpl implements NearPerService {
    @Autowired
    private NearPerMapper nearPerMapper;
    @Override
    public PageResult getNearPerPage(PageQueryUtil pageUtil) {
        PageResult pageResult;
        List<NearPer> nearPers=new ArrayList<>();
        int totalCount=0;
        try {
             nearPers = nearPerMapper.findNerPerList(pageUtil);

        }catch (Exception e){
            totalCount=0;
        }
        pageResult = new PageResult(nearPers,
                totalCount, pageUtil.getLimit(),
                pageUtil.getPage());
        return pageResult;
    }
}

创建NearPerMapper

package com.xm.chat.dao;

import com.xm.chat.entity.near.NearPer;
import com.xm.chat.util.PageQueryUtil;

import java.util.List;

public interface NearPerMapper {

    List<NearPer> findNerPerList(PageQueryUtil pageUtil);
}

创建 NearController

package com.xm.chat.controller.near;

import com.xm.chat.service.near.NearPerService;
import com.xm.chat.util.PageQueryUtil;
import com.xm.chat.util.Result;
import com.xm.chat.util.ResultGenerator;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.Map;

@Controller
@RequestMapping("/admin")
public class NearController {
    @Resource
    NearPerService nearPerService;

    @RequestMapping(value = "/nearper/list", method = RequestMethod.POST)
    @ResponseBody
    public Result nearPerList(@RequestParam Map<String, Object> params) {
        if (StringUtils.isEmpty(params.get("page")) || StringUtils.isEmpty(params.get("limit"))) {
            return ResultGenerator.genFailResult("参数异常!");
        }
        PageQueryUtil pageUtil = new PageQueryUtil(params);
        return ResultGenerator.genSuccessDataResult(nearPerService.getNearPerPage(pageUtil));
    }
}

 运行SpringBoot工程测试接口

{
    "resultCode": 200,
    "message": "SUCCESS",
    "data": {
        "totalCount": 0,
        "pageSize": 10,
        "totalPage": 0,
        "currPage": 1,
        "list": [
            {
                "intro": {
                    "id": 9,
                    "head": "https://1.15.0.115:8081/upload/user51/type_head/20220827_2135548.png",
                    "nick_name": "昵称4",
                    "city": "常驻城市1",
                    "birthday": "生日1",
                    "job": "职业1",
                    "make_fir_pur": "交友目的1",
                    "expect": "期望对象1",
                    "wx_account": "微信1",
                    "is_hide_wx": "是否隐藏微信1",
                    "height": "身高1",
                    "weight": "体重1",
                    "per_intro": "个人介绍1",
                    "user_id": "4"
                },
                "action": {
                    "id": 9,
                    "cur_loc": null,
                    "las_onl_time": null,
                    "is_face_rec": 0,
                    "user_id": "4"
                },
                "faceRec": {
                    "id": 9,
                    "pic": null,
                    "video": null,
                    "user_id": "4"
                },
                "location": {
                    "callbackTime": null,
                    "locationTime": "locationTime",
                    "locationType": null,
                    "latitude": "31.22352",
                    "longitude": "121.45591",
                    "accuracy": null,
                    "altitude": null,
                    "bearing": null,
                    "speed": null,
                    "country": null,
                    "province": null,
                    "city": "常驻城市1",
                    "district": null,
                    "street": null,
                    "streetNumber": null,
                    "cityCode": null,
                    "adCode": null,
                    "address": null,
                    "description": null,
                    "user_id": null,
                    "distance": "29280.0"
                }
            },
            {
                "intro": {
                    "id": 10,
                    "head": "https://1.15.0.115:8081/upload/user51/type_head/20220827_2135548.png",
                    "nick_name": "昵称4",
                    "city": "常驻城市1",
                    "birthday": "生日1",
                    "job": "职业1",
                    "make_fir_pur": "交友目的1",
                    "expect": "期望对象1",
                    "wx_account": "微信1",
                    "is_hide_wx": "是否隐藏微信1",
                    "height": "身高1",
                    "weight": "体重1",
                    "per_intro": "个人介绍1",
                    "user_id": "7"
                },
                "action": {
                    "id": 10,
                    "cur_loc": null,
                    "las_onl_time": null,
                    "is_face_rec": 0,
                    "user_id": "7"
                },
                "faceRec": {
                    "id": 10,
                    "pic": null,
                    "video": null,
                    "user_id": "7"
                },
                "location": {
                    "callbackTime": null,
                    "locationTime": "locationTime",
                    "locationType": null,
                    "latitude": "31.03241",
                    "longitude": "121.22654",
                    "accuracy": null,
                    "altitude": null,
                    "bearing": null,
                    "speed": null,
                    "country": null,
                    "province": null,
                    "city": "常驻城市1",
                    "district": null,
                    "street": null,
                    "streetNumber": null,
                    "cityCode": null,
                    "adCode": null,
                    "address": null,
                    "description": null,
                    "user_id": null,
                    "distance": "30950.0"
                }
            },
            {
                "intro": {
                    "id": 8,
                    "head": "https://1.15.0.115:8081/upload/user51/type_head/20220827_2135548.png",
                    "nick_name": "昵称3",
                    "city": "常驻城市1",
                    "birthday": "生日1",
                    "job": "职业1",
                    "make_fir_pur": "交友目的1",
                    "expect": "期望对象1",
                    "wx_account": "微信1",
                    "is_hide_wx": "是否隐藏微信1",
                    "height": "身高1",
                    "weight": "体重1",
                    "per_intro": "个人介绍1",
                    "user_id": "3"
                },
                "action": {
                    "id": 8,
                    "cur_loc": null,
                    "las_onl_time": null,
                    "is_face_rec": 0,
                    "user_id": "3"
                },
                "faceRec": {
                    "id": 8,
                    "pic": null,
                    "video": null,
                    "user_id": "3"
                },
                "location": {
                    "callbackTime": null,
                    "locationTime": "locationTime",
                    "locationType": null,
                    "latitude": "36.30744",
                    "longitude": "120.39629",
                    "accuracy": null,
                    "altitude": null,
                    "bearing": null,
                    "speed": null,
                    "country": null,
                    "province": null,
                    "city": "常驻城市1",
                    "district": null,
                    "street": null,
                    "streetNumber": null,
                    "cityCode": null,
                    "adCode": null,
                    "address": null,
                    "description": null,
                    "user_id": null,
                    "distance": "561350.0"
                }
            },
            {
                "intro": {
                    "id": 6,
                    "head": "https://1.15.0.115:8081/upload/user51/type_head/20220827_2135548.png",
                    "nick_name": "昵称1",
                    "city": "常驻城市1",
                    "birthday": "生日1",
                    "job": "职业1",
                    "make_fir_pur": "交友目的1",
                    "expect": "期望对象1",
                    "wx_account": "微信1",
                    "is_hide_wx": "是否隐藏微信1",
                    "height": "身高1",
                    "weight": "体重1",
                    "per_intro": "个人介绍1",
                    "user_id": "1"
                },
                "action": {
                    "id": 6,
                    "cur_loc": null,
                    "las_onl_time": null,
                    "is_face_rec": 0,
                    "user_id": "1"
                },
                "faceRec": {
                    "id": 6,
                    "pic": null,
                    "video": null,
                    "user_id": "1"
                },
                "location": {
                    "callbackTime": null,
                    "locationTime": "locationTime",
                    "locationType": null,
                    "latitude": "40.22077",
                    "longitude": "116.23128",
                    "accuracy": null,
                    "altitude": null,
                    "bearing": null,
                    "speed": null,
                    "country": null,
                    "province": null,
                    "city": "常驻城市1",
                    "district": null,
                    "street": null,
                    "streetNumber": null,
                    "cityCode": null,
                    "adCode": null,
                    "address": null,
                    "description": null,
                    "user_id": null,
                    "distance": "1087401.0"
                }
            },
            {
                "intro": {
                    "id": 7,
                    "head": "https://1.15.0.115:8081/upload/user51/type_head/20220827_2135548.png",
                    "nick_name": "昵称2",
                    "city": "常驻城市1",
                    "birthday": "生日1",
                    "job": "职业1",
                    "make_fir_pur": "交友目的1",
                    "expect": "期望对象1",
                    "wx_account": "微信1",
                    "is_hide_wx": "是否隐藏微信1",
                    "height": "身高1",
                    "weight": "体重1",
                    "per_intro": "个人介绍1",
                    "user_id": "2"
                },
                "action": {
                    "id": 7,
                    "cur_loc": null,
                    "las_onl_time": null,
                    "is_face_rec": 0,
                    "user_id": "2"
                },
                "faceRec": {
                    "id": 7,
                    "pic": null,
                    "video": null,
                    "user_id": "2"
                },
                "location": {
                    "callbackTime": null,
                    "locationTime": "locationTime",
                    "locationType": null,
                    "latitude": "23.15792",
                    "longitude": "113.27324",
                    "accuracy": null,
                    "altitude": null,
                    "bearing": null,
                    "speed": null,
                    "country": null,
                    "province": null,
                    "city": "常驻城市1",
                    "district": null,
                    "street": null,
                    "streetNumber": null,
                    "cityCode": null,
                    "adCode": null,
                    "address": null,
                    "description": null,
                    "user_id": null,
                    "distance": "1196003.0"
                }
            }
        ]
    }
}

/  通过app首页展示位置信息列表  / 

通过Navicat Priminum 创建 tb_location 表并导出 chatdb.sql 文件, 最后部署到云服务器上 . 将SpringBoot 工程编译成jar包部署到云服务器上 . ( 参考 : Flutter 项目实战 注册接口实现https协议访问(三))

创建 MVP 模式 callback 

home_callback.dart

import 'package:flutter_person_course/common/base/model/IModel.dart';
import 'package:flutter_person_course/common/base/presenter/IPresenter.dart';
import 'package:flutter_person_course/common/base/view/IView.dart';

abstract class CHomeModel extends IModel {
  ///
  loadHomeData(Map<String, dynamic> p, SuccessCallback s, FailureCallback f);

  /// 编辑位置信息
  editLocationData(
      Map<String, dynamic> p, SuccessCallback s, FailureCallback f);
}

abstract class CHomePresenter extends IPresenter {
  ///
  loadHomeData(Map<String, dynamic> p);

  /// 编辑位置信息
  editLocationData(Map<String, dynamic> p);
}

abstract class CHomeView extends IView {
  showHomeData(dynamic data);

  showEditLocationData(dynamic data);
}

创建 Model 层 MHome

class MHome extends AbstractModel implements CHomeModel {
  @override
  void dispose() {
    // TODO: implement dispose
    HttpManager().cancel(tag!);
  }

  @override
  loadHomeData(Map<String, dynamic> p, s, f) async{
    return HttpManager().post(
        url: '/nearper/list',
        tag: tag!,
        successCallback: (data) {
          s(data);
        },
        errorCallback: (data) {
          f(data);
        },
        params: p);
  }

  @override
  editLocationData(Map<String, dynamic> p, SuccessCallback s, FailureCallback f) {
    return HttpManager().post(
        url: '/edit/location',
        tag: tag!,
        successCallback: (data) {
          s(data);
        },
        errorCallback: (data) {
          f(data);
        },
        params: p);
  }
}

创建Presenter  PHome

class PHome extends AbstractPresenter<CHomeView, CHomeModel>
    implements CHomePresenter {
  @override
  IModel createModel() {
    return MHome();
  }

  @override
  loadHomeData(Map<String, dynamic> p) {
    view?.startLoading();
    return model?.loadHomeData(p, (data) {
      view?.showLoadSuccess();
      view?.showHomeData(data);
      model?.dispose();
    }, (error) {
      view?.showLoadFailure(error.code!, error.message!);
    });
  }

  @override
  editLocationData(Map<String, dynamic> p) {
    view?.startLoading();
    return model?.editLocationData(p, (data) {
      view?.showLoadSuccess();
      view?.showEditLocationData(data);
      model?.dispose();
    }, (error) {
      view?.showLoadFailure(error.code!, error.message!);
    });
  }
}

 高德地图获取的位置信息插入云服务数据库中

......

late PHome _pHome;

final Map<String, String> _homeMap = <String, String>{};

final GlobalKey<HomeSliverWidgetState> _homeSliverKey = GlobalKey();

@override
void initState() {
    // TODO: implement initState
    super.initState();
    amapLocaitonInit((Map<String, Object>? result) {
      logV("高德地图定位信息: ${json.encode(result)}");
      _pHome.editLocationData(result!);
    });
    _pHome = PHome();
    _pHome.attachView(this);
    _loadHomeData();
}

......
I/flutter (23766): AppInfo  v  高德地图定位信息: {"callbackTime":"2022-08-29 
23:03:12","locationTime":"2022-08-29 
23:03:13","locationType":5,"latitude":31.298391,"longitude":121.192297,"accuracy":2
5.0,"altitude":0.0,"bearing":0.0,"speed":0.0,"country":"中国","province":"上海
市","city":"上海市","district":"嘉定区","street":"于塘路","streetNumber":"498
号","cityCode":"021","adCode":"310114","address":"上海市嘉定区于塘路498号靠近顾八
房","description":"在顾八房附近"}
I/flutter (23766): AppInfo  v  相应数据:{resultCode: 200, message: SUCCESS, data: null}

 查询云服务数据库数据

展示列表数据

@override
  Widget build(BuildContext context) {
    return MediaQuery.removePadding(
      context: context,
      removeTop: true,
      child: GridView.builder(
          padding: EdgeInsets.all(20.w),
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              crossAxisSpacing: 20.w,
              mainAxisSpacing: 20.h,
              childAspectRatio: 0.7),
          itemCount: _homeDatas.length,
          itemBuilder: (BuildContext context, int index) {
            var _homeData = _homeDatas[index];

            /// 获取图片宽度
            double picWidth = MediaQuery.of(context).size.width / 2 - 30.w;
            double picHeight = picWidth;
            return Card(
              elevation: 0.0,
              color: Colors.black.withOpacity(0.03),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Expanded(
                    child: Container(
                      width: picWidth,
                      height: picHeight,
                      color: Colors.green.withOpacity(0.2),
                      padding: EdgeInsets.all(60.w),
                      child: CachedNetworkImage(
                          imageUrl: '${_homeData['intro']['head']}',
                          fit: BoxFit.fitWidth,
                          cacheManager: EsoImageCacheManager(),
                          errorWidget: (context, url, error) {
                            return const Icon(
                              Icons.error,
                            );
                          }),
                    ),
                    flex: 1,
                  ),
                  Padding(
                    child: Text(
                      '\t${_homeData['intro']['nick_name']}\t',
                      style: TextStyle(
                          fontSize: 40.sp,
                          color: Colors.blue.withOpacity(0.7),
                          fontWeight: FontWeight.bold),
                    ),
                    padding: EdgeInsets.all(16.w),
                  ),
                  Container(
                      padding: EdgeInsets.only(
                          left: 20.w, right: 20.w, top: 10.h, bottom: 10.h),
                      margin: EdgeInsets.only(
                          left: 16.w, right: 16.w, bottom: 16.w),
                      child: Text(
                        '${_homeData['location']['distance']} 米',
                        style: TextStyle(
                            fontSize: 40.sp,
                            color: Colors.red.withOpacity(0.6)),
                        textAlign: TextAlign.start,
                      ),
                      alignment: Alignment.centerLeft,
                      decoration: BoxDecoration(
                          color: Colors.black12.withOpacity(0.08),
                          borderRadius:
                              BorderRadius.all(Radius.circular(50.w)))),
                ],
              ),
            );
          }),
    );
  }

 

案例

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐