小工具知识网

当前位置: 首页 > 行业知识 > Android高德地图定位实现签到打卡功能(全网最详细+收藏)

行业知识

Android高德地图定位实现签到打卡功能(全网最详细+收藏)

2026-11-04 03:11:26 来源:互联网转载

前言

        本章根据高德地图API,实现打卡签到功能。用到了定位SDK 和地图SDK、覆盖物。打卡范围图形可以支持多种形状,如:圆形、长方形、多边形。

核心逻辑:

    获取当前定位信息,然后通过Marker绘制小图标进行展示,并在onLocationChanged回调方法中不断重新绘制当前位置Marker以保持时时最新。在指定打卡签到区域添加围栏,主要使用CircleOptions、PolygonOptions进行绘制,然后判断当前是否在打卡范围内,具体实现如下。

PS:另外提一句,也可以结合+电子围栏进行广播自动触发自动打卡

目录

1、添加高德地图SDK到项目依赖中

2、获取定位权限

3、初始化高德地图:

1、xml布局引入:

2、地图AMap、MapView 相关配置

3、MapView的生命周期设置

4、实现定位功能:

1、初始化定位相关参数配置

2、定位信息的回调 

3、添加当前位置的Marker

5、打卡签到范围绘制

6、判断打卡签到是否在范围内


 效果图:

1、添加高德地图SDK到项目依赖中

     在项目的 build.gradle 文件中,添加以下依赖:

implementation 'com.amap.api:location:6.3.0'implementation 'com.amap.api:navi-3dmap:7.4.0_3dmap7.4.0'

     在项目的 AndroidManifest.xml 文件中,添加如下:

 

2、获取定位权限

     在项目的AndroidManifest.xml文件中,添加以下权限:

  

    在Activity页面中,记得申请动态权限( sdk> 6.0)

3、初始化高德地图:

      1、xml布局引入:

          ps:TextureMapView或MapView都可以,我这里使用的TextureMapView

                                            

    2、地图AMap、MapView 相关配置

    /**     * 初始化 地图基础设置     *     * @param savedInstanceState     */    private void addMapViewSet(Bundle savedInstanceState) {        // 显示地图        mapView.onCreate(savedInstanceState);        if (aMap == null) {            aMap = mapView.getMap();//获取地图对象        }        //设置显示定位按钮 并且可以点击        UiSettings uiSettings = aMap.getUiSettings();        //设置定位监听:activate、deactivate        aMap.setLocationSource(this);        //缩放按钮隐藏(+ - )        uiSettings.setZoomControlsEnabled(false);        // TODO 自定义定位图标, 默认是蓝点        aMap.setMyLocationStyle(addMyLocationStyle());        // TODO 启动定位        aMap.setMyLocationEnabled(true);               //TODO 地址编码,当详细地址为空时使用        initGeocodeQuery();    }    /**     * 添加定位样式 (默认是蓝点)     */    private MyLocationStyle addMyLocationStyle() {        MyLocationStyle locationStyle = new MyLocationStyle();        locationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_seat_empty));        locationStyle.showMyLocation(true);        locationStyle.interval(4000);        locationStyle.strokeColor(Color.argb(0, 0, 0, 0));        locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));        locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//中心位置不旋转        return locationStyle;    }      //当详细地址为空时,经纬度解析地址 (非必要方法)   private void initGeocodeQuery(){        mGeocoderSearch = new GeocodeSearch(this);        mGeocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {            @Override            public void onRegeocodeSearched(RegeocodeResult result, int rCode) {                if(rCode==1000 && result.getRegeocodeAddress()!=null){                    mCurrentDetailedAddress=result.getRegeocodeAddress().getFormatAddress();                }                Log.e("test-z","------逆地理编码地址="+mCurrentDetailedAddress);            }            @Override            public void onGeocodeSearched(GeocodeResult result, int rCode) {            }        });    }

3、MapView的生命周期设置

   @Override    protected void onResume() {        super.onResume();        if (mapView != null)            mapView.onResume();    }    @Override    protected void onPause() {        super.onPause();        if (mapView != null)            mapView.onPause();    }    @Override    protected void onSaveInstanceState(@NonNull Bundle outState) {        super.onSaveInstanceState(outState);        if (mapView != null)            mapView.onSaveInstanceState(outState);    }    @Override    protected void onDestroy() {        if (mapView != null) {            mapView.onDestroy();        }        if (mLocationClient != null) {            mLocationClient.stopLocation();            mLocationClient.onDestroy();            mLocationClient=null;        }        super.onDestroy();    }

4、实现定位功能:

     1、初始化定位相关参数配置

    /**     * 初始化 定位配置     */    private void initLocationConfig() {        try {                //初始化定位                mLocationClient = new AMapLocationClient(getApplicationContext());                //设置定位回调监听                mLocationClient.setLocationListener(this);                //初始化定位参数                mLocationOption = new AMapLocationClientOption();                //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式                mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);                //设置是否返回地址信息(默认返回地址信息)                mLocationOption.setNeedAddress(true);                //设置是否只定位一次,默认为false                mLocationOption.setOnceLocation(false);                mLocationOption.setHttpTimeOut(30000);                //设置是否强制刷新WIFI,默认为强制刷新                mLocationOption.setWifiActiveScan(true);                //设置是否允许模拟位置,默认为false,不允许模拟位置                mLocationOption.setMockEnable(false);                //设置定位间隔,单位毫秒,默认为2000ms                mLocationOption.setInterval(4000);                //给定位客户端对象设置定位参数                mLocationClient.setLocationOption(mLocationOption);                //多次激活,最好调用一次stop,再调用start以保证场景模式生效                //  mLocationClient.stopLocation();               // 开始定位                mLocationClient.startLocation();        }catch (Exception e){           //异常        }    }

2、定位信息的回调 

 AMapLocationListener类中,实现LocationSource接口,并重写onLocationChanged()方法,获取用户位置信息:

    @Override    public void onLocationChanged(AMapLocation amapLocation) {        if (amapLocation != null) {            //定位成功回调信息            if (amapLocation.getErrorCode() == 0) {                mCurrentDetailedAddress = amapLocation.getAddress();                if (isFirstLoc) {                    //设置缩放级别17                    aMap.moveCamera(CameraUpdateFactory.zoomTo(17));                    //中心位置为当前坐标                    aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude())));                    mListener.onLocationChanged(amapLocation);                    //添加电子围栏列表                    drawCompanyFenceList();                    isFirstLoc=false;                }                // 记录当前定位的坐标                mCurrentLatLng = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude());                //添加当前位置的自定义图标                addCurrentMarker(mCurrentLatLng, null, R.mipmap.ic_location_current);                 //详细地址为空时,可通过逆地理编码获取地址                getCurrentAddress();                //重新移动到中心位置                //aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude())));                Log.e("test-z", "----当前位置:"+amapLocation.getLatitude()+","+amapLocation.getLongitude()+" ,"+mCurrentDetailedAddress);            } else {                mCurrentLatLng = null;            }        }    }

注意: 由于是异步解析,部分手机首次获取详细地址可能为空,可通过经纬度解析详细地址,并赋值使用。

//获取当前详细地址,那经纬度去解析  (非必要方法)private void getCurrentAddress(){        if(TextUtils.isEmpty(mCurrentDetailedAddress)){            // Latlng,范围多少米,火系坐标系还是GPS原生坐标系            RegeocodeQuery query = new RegeocodeQuery(new LatLonPoint(mCurrentLatLng.latitude,                    mCurrentLatLng.longitude), 200,GeocodeSearch.AMAP);            //发起请求            mGeocoderSearch.getFromLocationAsyn(query);        }    }

3、添加当前位置的Marker

    /**     * TODO 当前位置的小图标     *     * @param latLng     * @param object     * @param icon  小图标     */    private void addCurrentMarker(LatLng latLng, Object object, int icon) {        MarkerOptions markerOption = new MarkerOptions();        markerOption.position(latLng);        //设置Marker可拖动        markerOption.draggable(false);        markerOption.icon(BitmapDescriptorFactory.fromResource(icon));        // 将Marker设置为贴地显示,可以双指下拉地图查看效果        //设置marker平贴地图效果        markerOption.setFlat(true);        if (mCurrentMarker != null) {            mCurrentMarker.remove();        }        mCurrentMarker = aMap.addMarker(markerOption);        // marker.setObject(object);    }

5、打卡签到范围绘制

     根据不同的图形进行绘制:

      1、如果是圆形,只需要一个中心经纬度、半径,传入 CircleOptions 并在Map图层添加;

      2、如果是多边形,将经纬度列表数据传入 PolygonOptions 并在Map图层添加即可

      3、如果业务的打卡范围定时变化,重新绘制之前,需要先将原来的清除,建议将添加后返回的对象进行存储,方便重新时清除,同时也可以直接使用该对象判断打卡点是否在范围内

    /**     * 类型:圆     *     * @param centers 中心坐标     * @param radius 半径     */    public void drawTypeCircle(List centers, double radius) {        if(centers!=null && centers.size()>0){            LatLng  centerLatLng=new LatLng(centers.get(0).getLatitude(), centers.get(0).getLongitude());            //圆形            CircleOptions circleOptions=new CircleOptions();            //属性信息            circleOptions.center(centerLatLng)                    .center(centerLatLng)                    .radius(radius) //半径范围                    .strokeColor(Color.parseColor("#2c81ec"))                    .strokeWidth(5)                    .fillColor(Color.parseColor("#F772a7df"));            Circle  circle = aMap.addCircle(circleOptions);            //添加记录            mAddFences.add(circle);        }    }        /**     * 类型:多边形     * 提示:坐标需按照 顺时针或逆时针依次添加,否则会重叠     *     * @param points 经纬度集合     */    private void drawTypePolygon(List points) {        if(points!=null && points.size()>0){            List latLngList=new ArrayList();            for(int i=0;i

上一篇:主机用于服务器吗怎么设置?

下一篇:揭秘Android游戏开发秘籍,源码解析与实战指南