Android百度地图定位、显示用户当前位置

本文实例为大家分享了Android百度地图定位、显示用户当前位置的工具类,供大家参考,具体内容如下

1、构建定位Option的工具类

import com.baidu.location.LocationClientOption;

/**
 * 建造 LocationClientOption 项
 *
 * @author peter 2018-12-21 10:58
 */
public class LocationClientOptionBuilder {
 private LocationClientOption option;

 public static LocationClientOptionBuilder builder() {
  LocationClientOptionBuilder builder = new LocationClientOptionBuilder();
  builder.option = builder.initOption();
  return builder;
 }

 /**
  * 设置坐标系
  *
  * @return
  * @see CoorType
  */
 public LocationClientOptionBuilder setCoorType() {
  return setCoorType(CoorType.bd09ll);
 }

 public LocationClientOptionBuilder setCoorType(CoorType coorType) {
  this.option.setCoorType(coorType.name());
  return this;
 }

 /**
  * 连续定位
  * 可选,设置发起定位请求的间隔,int类型,单位ms
  * 如果设置为0,则代表单次定位,即仅定位一次,默认为0
  * 如果设置非0,需设置1000ms以上才有效
  *
  * @param time
  * @return
  */
 public LocationClientOptionBuilder setScanSpan(int time) {
  this.option.setScanSpan(time);
  return this;
 }

 public LocationClientOption bulid() {
  return this.option;
 }

 private LocationClientOption initOption() {
  LocationClientOption option = new LocationClientOption();
  //可选,设置定位模式,默认高精度
  //LocationMode.Hight_Accuracy:高精度;
  //LocationMode. Battery_Saving:低功耗;
  //LocationMode. Device_Sensors:仅使用设备;
  option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
  //可选,设置返回经纬度坐标类型,默认GCJ02
  //GCJ02:国测局坐标;
  //BD09ll:百度经纬度坐标;
  //BD09:百度墨卡托坐标;
  //海外地区定位,无需设置坐标类型,统一返回WGS84类型坐标
//  option.setCoorType("bd09ll");

  //可选,设置发起定位请求的间隔,int类型,单位ms
  //如果设置为0,则代表单次定位,即仅定位一次,默认为0
  //如果设置非0,需设置1000ms以上才有效
//  option.setScanSpan(1000);

  //可选,设置是否使用gps,默认false
  //使用高精度和仅用设备两种定位模式的,参数必须设置为true
  option.setOpenGps(true);

  //可选,设置是否当GPS有效时按照1S/1次频率输出GPS结果,默认false
//  option.setLocationNotify(true);
  //可选,定位SDK内部是一个service,并放到了独立进程。
  //设置是否在stop的时候杀死这个进程,默认(建议)不杀死,即setIgnoreKillProcess(true)
//  option.setIgnoreKillProcess(true);

  //可选,设置是否收集Crash信息,默认收集,即参数为false
//  option.SetIgnoreCacheException(false);

  //可选,V7.2版本新增能力
  //如果设置了该接口,首次启动定位时,会先判断当前Wi-Fi是否超出有效期,若超出有效期,会先重新扫描Wi-Fi,然后定位
//  option.setWifiCacheTimeOut(5 * 60 * 1000);
  //可选,设置是否需要过滤GPS仿真结果,默认需要,即参数为false
//  option.setEnableSimulateGps(false);
  return option;
 }

 /**
  * 坐标系
  */
 public enum CoorType {
  gcj02,
  bd09,
  bd09ll
 }
}

2、构建定位的工具类

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;

/**
 * 百度地图定位工具类
 *
 * @author peter 2018-12-21 10:12
 */
public class BMapLocationHelper {

 private static final int LOCATION_SUCCESS = 1;
 static final int LOCATION_FAIL = -1;
 private LocationClient mLocationClient;
 private MyLocationListener myListener = new MyLocationListener();
 private LocationCallBack callBack;

 private BMapLocationHelper(LocationCallBack callBack) {

  this.callBack = callBack;
 }

 public static BMapLocationHelper create(@NonNull Context context, @NonNull LocationClientOption option, @NonNull LocationCallBack callBack) {
  BMapLocationHelper bMapLocationHelper = new BMapLocationHelper(callBack);
  LocationClient client = new LocationClient(context);
  client.setLocOption(option);
  //声明LocationClient类
  client.registerLocationListener(bMapLocationHelper.myListener);
  bMapLocationHelper.mLocationClient = client;
  return bMapLocationHelper;
 }

 /**
  * 开始定位
  */
 public void locStart() {
  mLocationClient.start();
 }

 /**
  * 停止定位
  */
 public void locStop() {
  mLocationClient.stop();
 }

 public void locReStart() {
  mLocationClient.restart();
 }

 public LocationClient getmLocationClient() {
  return mLocationClient;
 }

 /**
  * 地图定位结果监听类
  */
 public class MyLocationListener extends BDAbstractLocationListener {
  private static final String TAG = "MyLocationListener";

  @Override
  public void onReceiveLocation(BDLocation location) {
   if (location == null) return;
   int locType = location.getLocType();
   int status = LOCATION_SUCCESS;
   if (locType != 61 && locType != 161 && locType != 66) status = LOCATION_FAIL;
   String errMsg = getLocationResultMsg(locType);
   callBack.onReceiveLocation(status, location, errMsg);
  }

  @Override
  public void onLocDiagnosticMessage(int i, int i1, String s) {
   Log.i(TAG, "onLocDiagnosticMessage: " + i + "diaType:" + i1);
   callBack.onLocDiagnosticMessage(i, i1, getLocDiagnosticMessage(i, i1));
   super.onLocDiagnosticMessage(i, i1, s);
  }
 }

 /**
  * 回调类
  */
 public abstract static class LocationCallBack {

  /**
   * 定位的结果
   *
   * @param statusCode 状态码,1:定位成功,-1定位失败
   * @param bdLocation 定位成功时返回的定位结果对象
   * @param errMsg  定位失败时的错误信息,成功时则为null
   */
  public abstract void onReceiveLocation(int statusCode, BDLocation bdLocation, String errMsg);

  /**
   * 错误的状态码
   * <a>http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/addition-func/error-code</a>
   * <p>
   * 回调定位诊断信息,开发者可以根据相关信息解决定位遇到的一些问题
   *
   * @param locType   当前定位类型
   * @param diagnosticType 诊断类型(1~9)
   * @param diagnosticMessage 具体的诊断信息释义
   */
  public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {
  }
 }

 /**
  * 错误的状态码
  * <a>http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/addition-func/error-code</a>
  *
  * @param locType 当前定位类型
  * @return String 定位成功或失败的信息
  */
 private String getLocationResultMsg(int locType) {
  switch (locType) {
   case 61:
    return "GPS定位结果,GPS定位成功";
   case 62:
    return "无法获取有效定位依据,定位失败,请检查运营商网络或者WiFi网络是否正常开启,尝试重新请求定位";
   case 63:
    return "网络异常,没有成功向服务器发起请求,请确认当前测试手机网络是否通畅,尝试重新请求定位";
   case 66:
    return "离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果";
   case 67:
    return "离线定位失败";
   case 161:
    return "网络定位结果,网络定位成功";
   case 162:
    return "请求串密文解析失败,一般是由于客户端SO文件加载失败造成,请严格参照开发指南或demo开发,放入对应SO文件";
   case 167:
    return "服务端定位失败,请您检查是否禁用获取位置信息权限,尝试重新请求定位";
   case 505:
    return "AK不存在或者非法,请按照说明文档重新申请AK";
   default:
    return "";
  }
 }

 /**
  * @param locType  当前定位类型
  * @param diagnosticType 诊断类型(1~9)
  * @return String
  */
 private String getLocDiagnosticMessage(int locType, int diagnosticType) {

  switch (locType) {
   case 62:
    switch (diagnosticType) {
     case 4:
      return "定位失败,无法获取任何有效定位依据";
     case 5:
      return "定位失败,无法获取有效定位依据,请检查运营商网络或者Wi-Fi网络是否正常开启,尝试重新请求定位";
     case 6:
      return "定位失败,无法获取有效定位依据,请尝试插入一张sim卡或打开Wi-Fi重试";
     case 7:
      return "定位失败,飞行模式下无法获取有效定位依据,请关闭飞行模式重试";
     case 9:
      return "定位失败,无法获取任何有效定位依据";
    }
   case 67:
    if (diagnosticType == 3) return "定位失败,请您检查您的网络状态";

   case 161:
    switch (diagnosticType) {
     case 1:
      return "定位失败,建议您打开GPS";
     case 2:
      return "定位失败,建议您打开Wi-Fi";
    }
   case 167:
    if (diagnosticType == 8) return "定位失败,请确认您定位的开关打开状态,是否赋予APP定位权限";

   default:
    return "未知错误";
  }
 }
}

3、显示用户当前位置到地图的工具类

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;

import com.baidu.location.BDLocation;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.yikesong.sender.util.ToastUtils;

/**
 * 显示用户当前位置到地图上
 *
 * @author peter 2018-12-21 16:27
 */
public class UserLocation extends BMapLocationHelper.LocationCallBack {
 private Context context;
 private boolean isFirstLoc = true;
 private BaiduMap map;
 private int mCurrentDirection = 0;
 private BMapLocationHelper helper;
 private static final String TAG = "UserLocation";

 public UserLocation(@NonNull Context context, @NonNull BaiduMap map) {
  this.context = context;
  this.map = map;
  init();
 }

 private void init() {
  map.setMapType(BaiduMap.MAP_TYPE_NORMAL);
  //开启定位图层
  map.setMyLocationEnabled(true);
 }

 /**
  * 在地图上显示用户的当前位置
  */
 public void showUserLocationOnMap() {
  if (helper == null) {
   LocationClientOption option = LocationClientOptionBuilder
     .builder()
     .setCoorType()
     .bulid();
   helper = BMapLocationHelper.create(this.context, option, this);
  }
  helper.locStart();
 }

 @Override
 public void onReceiveLocation(int statusCode, BDLocation bdLocation, String errMsg) {
  if (statusCode == BMapLocationHelper.LOCATION_FAIL) {
   ToastUtils.toastInfo(errMsg, context);
   Log.i(TAG, "onReceiveLocation: " + errMsg);
   return;
  }
  MyLocationData locData = new MyLocationData.Builder()
    .accuracy(bdLocation.getRadius())
    // 此处设置开发者获取到的方向信息,顺时针0-360
    .direction(mCurrentDirection).latitude(bdLocation.getLatitude())
    .longitude(bdLocation.getLongitude()).build();
  map.setMyLocationData(locData);
  if (isFirstLoc) {
   isFirstLoc = false;
   LatLng centerPoint = new LatLng(bdLocation.getLatitude(),
     bdLocation.getLongitude());
   MapStatus mapStatus = new MapStatus.Builder()
     .target(centerPoint) //设置中心点
     .zoom(18f)//设置缩放级别
     .build();
   map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(mapStatus));
  }
  if (helper != null) helper.locStop();
 }

 @Override
 public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {
  super.onLocDiagnosticMessage(locType, diagnosticType, diagnosticMessage);
 }

 public BMapLocationHelper getHelper() {
  return helper;
 }

 public BaiduMap getMap() {
  return map;
 }

 public int getmCurrentDirection() {
  return mCurrentDirection;
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android高性能日志写入方案的实现

    前言 公司目前在做一款企业级智能客服系统,对于系统稳定性要求很高,不过难保用户在使用中不会出现问题,而 Android SDK 集成在客户的 APP 中,同时由于 Android 碎片化的问题,对于 SDK 的问题排查就显得尤为困难,因此记录下用户的操作日志就显得极为重要. 初始方案 一开始,SDK 记录日志的方式是直接通过写文件,当有一条日志要写入的时候,首先,打开文件,然后写入日志,最后关闭文件.这样做的问题就在于频繁的IO操作,影响程序的性能,而且 SDK 为了保证消息的及时性,还维护了一

  • Android利用ObjectAnimator实现ArcMenu

    本文介绍利用ObjectAnimator简单地实现ArcMenu,直接使用本文的ArcMenu类即可快捷地实现菜单功能. 最终使用效果: 先看下最终的使用效果: private int[] imageRes = {R.id.img_menu, R.id.img_menu1, R.id.img_menu2, R.id.img_menu3, R.id.img_menu4, R.id.img_menu5}; private ArcMenu arcMenu; ... //初始化,参数为资源图片id ar

  • Android动态修改应用图标与名称的方法实例

    遇到的坑 这里我把做这个功能中遇到的一些问题写在前面,是为了大家能先了解有什么问题存在,遇到这些问题的时候就不慌了,这里我把应用图标和名称先统一使用icon代替进行说明. 1.动态替换icon,只能替换内置的icon,无法从服务器端获取来更新icon: 2.动态替换icon以后,应用内更新的时候必须要切换到原始icon),否则可能导致更新安装失败(AS上表现为adb运行会失败),或者升级后应用图标出现多个甚至应用图标都不显示的情况(这些问题都可以通过下面我推荐的开发规则解决掉,所以这是一个坑点,

  • Android实现百度地图两点画弧线

    本文实例为大家分享了Android实现百度地图两点画弧线的具体代码,供大家参考,具体内容如下 import android.support.annotation.NonNull; import com.baidu.mapapi.map.ArcOptions; import com.baidu.mapapi.map.OverlayOptions; import com.baidu.mapapi.model.LatLng; /** * * http://lbsyun.baidu.com/index.

  • Android中WindowManager与WMS的解析

    最近在改bug的时候发现在windowManager.addView的时候会发生莫名其妙的崩溃,那个崩溃真的是让你心态爆炸,潜心研究了两天window相关的东西,虽然不是很深奥的东西,本人也只是弄清楚了window的添加逻辑,在此分享给大家: 一.悬浮窗的概念 在android中,无论我们的app界面,还是系统桌面,再或者是手机下方的几个虚拟按键和最上方的状态栏,又或者是一个吐司...我们所看到的所有界面,都是由一个个悬浮窗口组成的. 但是这些窗口有不同的级别: 系统的是老大,是最高级别,你没见

  • Android自定义View实现简单炫酷的球体进度球实例代码

    前言 最近一直在研究自定义view,正好项目中有一个根据下载进度来实现球体进度的需求,所以自己写了个进度球,代码非常简单.先看下效果: 效果还是非常不错的. 准备知识 要实现上面的效果我们只要掌握两个知识点就好了,一个是Handler机制,用于发消息刷新我们的进度球,一个是clipDrawable.网上关于Handler的教程很多,这里重点介绍一下clipDrawable,进度球的实现全靠clipDrawable. clipDrawable 如下图所示:ClipDrawable和InsertDr

  • Android获取其他应用中的assets资源

    最近有这样一个需求:A应用在一定条件下出发某个逻辑后,需要从B应用中获取一些资源(assets下的mp4视频.还有drawable下的一些图片用作背景),具体需求就不说啦哈哈,用一张图来表示应该更明白: A和B应用其实是1对多的关系,不同的B应用需要从他们自己的地方获取到资源给A. 一般我们获取app内的资源肯定是要获取到Resource这个类,而Resource是通过Context类的getResource获取到了,所以我们只需要获取到B应用的Context类就可以了. 可是其他App的Con

  • Android自定义View仿腾讯TIM下拉刷新View

    一 概述 自定义 View 是 Android 开发里面的一个大学问.偶然间看到 TIM 邮箱界面的刷新 View 还挺好玩的,于是就自己动手实现了一个,先看看 TIM 里边的效果图: 二 需求分析 看到上面的动图,大概也知道我们需要实现的功能: 根据拖动的进度来移动小球的位置 小球移动过程的动画 三 功能实现 新建一个 RefreshView 类继承自 View ,然后我们再在 RefreshView 里面新建一个内部实体类: Circle 来看一下 Circle类的代码 #Cirlce.ja

  • ObjectAnimator属性动画源码分析篇

    又和大家见面了,这几天一直在忙大创项目,所以没有更新博客,而且我发现看源码这个东西必须写个博客或者笔记啊,这之前一段时机笔者已经看了ValueAnimator和ObjectAnimator的源码了,但是这才过了几天,搞了会别的事情就忘得几乎一干二净了.现在又要重头看一遍很痛苦额-.+. 另外,笔者已经在简书写了关于属性动画的比较系统的详细的文章,之后会陆续在CSDN上重新写的(是重新写,不是复制过去哦,因为第一次写的实在是太烂了-.=) 好了不继续扯皮了,我们看来一下今天想要讲的东西--Obje

  • Android自定义动态壁纸开发(时钟)

    看到有些手机酷炫的动态壁纸,有没有好奇过他们是如何实现的,其实我们自己也可以实现. 先看效果 上图是动态壁纸钟的一个时钟. 我们先来看看 Livewallpaper(即动态墙纸)的实现,Android的动态墙纸并不是GIF图片,而是一个标准的Android应用程序,也就是APK.既然是应用程序,当然意味着天生具有GIF图片不具备的功能--能与用户发生交互,而且动态的背景变化绝不仅仅局限于GIF图片那般只能是固定的几张图片的循环播放.但是我们在这里没有加入与用户交互的动作,只是加入一个时钟(当然时

随机推荐