苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 11625|回复: 5

[新手开发之旅] 百度地图的集成之定位和变更定位图标

[复制链接]
发表于 2019-1-9 15:30:59 | 显示全部楼层 |阅读模式
本帖最后由 liu 于 2019-1-9 15:30 编辑



Android新手开发之旅目录



平时开发中经常会用到地图来定位,上一篇只是简单的说了下如何集成百度地图  http://www.sufeinet.com/thread-24744-1-1.html


本次在上篇的基础上来简单实现下如何定位和变更定位图标


定位:


1、初始化LocationClient类
[Java] 纯文本查看 复制代码
LocationClient locationClient = new LocationClient(getApplicationContext());

2、配置定位SDK参数
[Java] 纯文本查看 复制代码
        //声明LocationClient类实例并配置定位参数
        LocationClientOption locationOption = new LocationClientOption();
        MyLocationListener myLocationListener = new MyLocationListener();
        //注册监听函数
        locationClient.registerLocationListener(myLocationListener);
        //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
        locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
        locationOption.setCoorType("gcj02");
        //可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
        locationOption.setScanSpan(1000);
        //可选,设置是否需要地址信息,默认不需要
        locationOption.setIsNeedAddress(true);
        //可选,设置是否需要地址描述
        locationOption.setIsNeedLocationDescribe(true);
        //可选,设置是否需要设备方向结果
        locationOption.setNeedDeviceDirect(false);
        //可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
        locationOption.setLocationNotify(true);
        //可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
        locationOption.setIgnoreKillProcess(true);
        //可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
        locationOption.setIsNeedLocationDescribe(true);
        //可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        locationOption.setIsNeedLocationPoiList(true);
        //可选,默认false,设置是否收集CRASH信息,默认收集
        locationOption.SetIgnoreCacheException(false);
        //可选,默认false,设置是否开启Gps定位
        locationOption.setOpenGps(true);
        //可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
        locationOption.setIsNeedAltitude(false);
        //设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者,该模式下开发者无需再关心定位间隔是多少,定位SDK本身发现位置变化就会及时回调给开发者
        locationOption.setOpenAutoNotifyMode();
        //设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者
        locationOption.setOpenAutoNotifyMode(3000, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT);
        //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
        locationClient.setLocOption(locationOption);

3、实现定位回调
[Java] 纯文本查看 复制代码
    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
            //以下只列举部分获取经纬度相关(常用)的结果信息
            //更多结果信息获取说明,请参照类参考中BDLocation类中的说明

            //获取纬度信息
            double latitude = location.getLatitude();
            //获取经度信息
            double longitude = location.getLongitude();
            // String addr = location.getAddrStr();    //获取详细地址信息
            //String country = location.getCountry();    //获取国家
            //String province = location.getProvince();    //获取省份
            //String city = location.getCity();    //获取城市
            //String district = location.getDistrict();    //获取区县
            //String street = location.getStreet();    //获取街道信息
            //float radius = location.getRadius();      //获取定位精度,默认值为0.0f
            //String coorType = location.getCoorType();    //获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
            // int errorCode = location.getLocType();     //获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明

            LatLng ll = new LatLng(latitude,
                    longitude);
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
            MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(18.0f);// 设置地图放大比例
            mapView.setMapStatus(msu);
            // 移动到某经纬度
            mapView.animateMapStatus(update);
        }
    }

4、获取定位地址信息,调用LocationClient的start()方法,发起请求
[Java] 纯文本查看 复制代码
//开始定位
        locationClient.start();


注意:别忘了在AndroidManifest.xml中添加定位权限<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

这样就可以定位到你的当前位置了


定位图标:


上面实现了定位功能,现在添加覆盖物来显示自己的位置
[Java] 纯文本查看 复制代码
  //构建Marker图标  ,这里可以自己替换
            BitmapDescriptor bitmap = BitmapDescriptorFactory
                    .fromResource(R.drawable.pin_red);
            //构建MarkerOption,用于在地图上添加Marker
            OverlayOptions option = new MarkerOptions()
                    .position(ll)    //传入经纬度
                    .icon(bitmap)
                    .zIndex(12)
                    .draggable(true);
            //在地图上添加Marker,并显示
            map.addOverlay(option);


这样就已经将图标加上去了



完整代码:


activity_main.xml;
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.company.baidumap.MainActivity">

    <com.baidu.mapapi.map.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />

</LinearLayout>

MainActivity:
[Java] 纯文本查看 复制代码
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;

public class MainActivity extends AppCompatActivity {
    private MapView mMapVew;
    private BaiduMap mapView;
    private static final int FINE_LOCATION = 100;
    private LocationClient locationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mMapVew = (MapView) findViewById(R.id.map);
        mapView = mMapVew.getMap();
        checkPermission();
    }


    private void checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, FINE_LOCATION);
            } else {
                location();
            }
        } else {
            location();
        }
    }

    private void location() {
        //定位服务的客户端。宿主程序在客户端声明此类,并调用,目前只支持在主线程中启动
        locationClient = new LocationClient(getApplicationContext());
        //声明LocationClient类实例并配置定位参数
        LocationClientOption locationOption = new LocationClientOption();
        MyLocationListener myLocationListener = new MyLocationListener();
        //注册监听函数
        locationClient.registerLocationListener(myLocationListener);
        //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
        locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
        locationOption.setCoorType("gcj02");
        //可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
        locationOption.setScanSpan(1000);
        //可选,设置是否需要地址信息,默认不需要
        locationOption.setIsNeedAddress(true);
        //可选,设置是否需要地址描述
        locationOption.setIsNeedLocationDescribe(true);
        //可选,设置是否需要设备方向结果
        locationOption.setNeedDeviceDirect(false);
        //可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
        locationOption.setLocationNotify(true);
        //可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
        locationOption.setIgnoreKillProcess(true);
        //可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
        locationOption.setIsNeedLocationDescribe(true);
        //可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        locationOption.setIsNeedLocationPoiList(true);
        //可选,默认false,设置是否收集CRASH信息,默认收集
        locationOption.SetIgnoreCacheException(false);
        //可选,默认false,设置是否开启Gps定位
        locationOption.setOpenGps(true);
        //可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
        locationOption.setIsNeedAltitude(false);
        //设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者,该模式下开发者无需再关心定位间隔是多少,定位SDK本身发现位置变化就会及时回调给开发者
        locationOption.setOpenAutoNotifyMode();
        //设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者
        locationOption.setOpenAutoNotifyMode(3000, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT);
        //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
        locationClient.setLocOption(locationOption);
        //开始定位
        locationClient.start();
    }

    /**
     * 实现定位回调
     */
    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
            //以下只列举部分获取经纬度相关(常用)的结果信息
            //更多结果信息获取说明,请参照类参考中BDLocation类中的说明

            //获取纬度信息
            double latitude = location.getLatitude();
            //获取经度信息
            double longitude = location.getLongitude();
            // String addr = location.getAddrStr();    //获取详细地址信息
            //String country = location.getCountry();    //获取国家
            //String province = location.getProvince();    //获取省份
            //String city = location.getCity();    //获取城市
            //String district = location.getDistrict();    //获取区县
            //String street = location.getStreet();    //获取街道信息
            //float radius = location.getRadius();      //获取定位精度,默认值为0.0f
            //String coorType = location.getCoorType();    //获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
            // int errorCode = location.getLocType();     //获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明

            LatLng ll = new LatLng(latitude,
                    longitude);
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
            MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(18.0f);// 设置地图放大比例
            mapView.setMapStatus(msu);

            //构建Marker图标  ,这里可以自己替换
            BitmapDescriptor bitmap = BitmapDescriptorFactory
                    .fromResource(R.drawable.marker);
            //构建MarkerOption,用于在地图上添加Marker
            OverlayOptions option = new MarkerOptions()
                    .position(ll)
                    .icon(bitmap)
                    .zIndex(12)
                    .draggable(true);
            //在地图上添加Marker,并显示
            mapView.addOverlay(option);

            // 移动到某经纬度
            mapView.animateMapStatus(update);
        }
    }

    public void call() {
        //检查权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            //进入到这里代表没有权限.
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                //已经禁止提示了
                Toast.makeText(MainActivity.this, "您已禁止该权限,需要重新开启。", Toast.LENGTH_SHORT).show();
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, FINE_LOCATION);
            }
        } else {
            location();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        // TODO Auto-generated method stub
        switch (requestCode) {
            case FINE_LOCATION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    location();
                } else {
                    call();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        locationClient.stop();
    }
}

MyApplication:
[Java] 纯文本查看 复制代码
import android.app.Application;

import com.baidu.mapapi.CoordType;
import com.baidu.mapapi.SDKInitializer;

/**
 * Created by Administrator on 2019/1/8.
 */

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        //在使用SDK各组件之前初始化context信息,传入ApplicationContext
        SDKInitializer.initialize(this);
        //自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
        //包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
        SDKInitializer.setCoordType(CoordType.BD09LL);
    }
}


marker.png


1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2019-1-9 15:52:25 | 显示全部楼层
强烈支持楼主ing……
发表于 2019-1-9 15:58:47 | 显示全部楼层
我只是路过打酱油的。
发表于 2019-1-9 16:12:30 | 显示全部楼层
强烈支持楼主ing……
发表于 2019-1-9 16:59:41 | 显示全部楼层
真是难得给力的帖子啊。
发表于 2019-1-10 09:06:04 | 显示全部楼层
楼主加油,我们都看好你哦。
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-12-23 14:26

© 2014-2021

快速回复 返回顶部 返回列表