参考链接:
百度地图地图文档 :http://lbsyun.baidu.com/index.php?title=androidsdk
百度地图定位文档:http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/addition-func/error-code
前言:
该篇是对上篇的定位功能进行封装
加入定位成功以后,我的位置标记
精准度标记
批量添加mark
1. 重复两次的SDK导入以及build.gradle文件配置,AndoridManifest.xml文件配置,如果有不懂的,请看前两篇
2. 对定位功能进行封装
import android.content.Context;
import android.graphics.Color;
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.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.CircleOptions;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.Stroke;
import com.baidu.mapapi.model.LatLng;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2018/8/31.
*/
public class LocationUtils {
//单例模式--静态内部类
private static class Inner{
private static LocationUtils instance = new LocationUtils();
}
private LocationUtils(){
}
/**
* 获取定位工具类实例
* @return
*/
public static LocationUtils getInstance(){
return Inner.instance;
}
public interface MylocationListener{
void onReceiveLocation(BDLocation bdLocation);
}
/**
* 开启监听
* @param context
* @param mylocationListener
*/
public void requestLocation(Context context,final MylocationListener mylocationListener){
//声明LocationClent类
final LocationClient locationClient = new LocationClient(context);
//初始化LocationClientOption条件参数
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(false);
//可选,定位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);
//将条件设置进入声明LocationClent实例中
locationClient.setLocOption(option);
//为LocationClent注册监听回调
locationClient.registerLocationListener(new BDAbstractLocationListener() {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
if (mylocationListener!=null){
locationClient.stop();
mylocationListener.onReceiveLocation(bdLocation);
}else{
throw new NullPointerException(LocationUtils.class.getSimpleName()+"没有注册监听");
}
}
});
//开启监听
locationClient.start();
/*
* 当所设的整数值大于等于1000(ms)时,定位SDK内部使用定时定位模式。调用requestLocation()
* 后,每隔设定的时间,定位SDK就会进行一次定位。如果定位SDK根据定位依据发现位置没有发生变化,就不会发起网络请求,
* 返回上一次定位的结果;如果发现位置改变,就进行网络请求进行定位,得到新的定位结果。
* 定时定位时,调用一次requestLocation,会定时监听到定位结果。
*/
locationClient.requestLocation();
}
/**
* 设置中心点,并添加Marker
* @return
*/
public OverlayOptions getMarker(double lat,double lon){
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.mark); //设置marker的点位置
OverlayOptions overlayOptions = new MarkerOptions().icon(bitmapDescriptor).position(new LatLng(lat,lon));
return overlayOptions;
}
/**
* 设置中心圈
*/
public OverlayOptions setCircle(float redius,double lat,double lon){
// 添加圆
LatLng ll = new LatLng(lat, lon);
OverlayOptions ooCircle = new CircleOptions().fillColor(Color.parseColor("#9987CEFF")) //fillColor:设置填充颜色
.center(ll).stroke(new Stroke(5, Color.parseColor("#7EC0EE"))) //center:设置中心坐标 stroke:设置圆角颜色
.radius((int) redius);
return ooCircle;
}
/**
* 添加覆盖物(从服务器获取的对应值的集合)
*/
public List<OverlayOptions> addMarkers(){
//创建OverlayOptions的集合
List<OverlayOptions> options = new ArrayList<OverlayOptions>();
//设置坐标点
LatLng point1 = new LatLng(37.793974,112.591522);
LatLng point2 = new LatLng(37.794102,112.59127);
//构建Marker图标
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.car);
//创建OverlayOptions属性
OverlayOptions option1 = new MarkerOptions()
.position(point1)
.title("饺子")
.icon(bitmap);
OverlayOptions option2 = new MarkerOptions()
.position(point2)
.title("面条")
.icon(bitmap);
//将OverlayOptions添加到list
options.add(option1);
options.add(option2);
//在地图上批量添加
return options;
}
/**
* 设置缩放级别,并且移动到当前定位位置
*/
public MapStatusUpdate setUserMapCenter(double lat,double lon) {
LatLng cenpt = new LatLng(lat,lon);
//定义地图状态
MapStatus mMapStatus = new MapStatus.Builder()
.target(cenpt) //中心坐标
.zoom(19) //缩放级别 取值范围:3 - 19 查看详细取值范围:https://blog.csdn.net/yb305/article/details/61915063
.build();
//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
return mMapStatusUpdate;
}
}
3. Activity中使用
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import java.security.Permission;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private MapView mapView = null;
private BaiduMap baiduMap = null;
private static final int PERMISSION_REQUEST_CODE = 1000;
private String[] permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_PHONE_STATE};
private List<String> unauthorizedPermissions = new ArrayList<>();
private boolean isFarstSetMarker = true; //防止每次定位重新设置Marker
private LocationUtils.MylocationListener listener = new LocationUtils.MylocationListener() {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
if (bdLocation.getLocType()==61){ //GPS定位结果,GPS定位成功
//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取经纬度相关(常用)的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明
double latitude = bdLocation.getLatitude(); //获取纬度信息
double longitude = bdLocation.getLongitude(); //获取经度信息
float radius = bdLocation.getRadius(); //获取定位精度,默认值为0.0f
baiduMap.addOverlay(LocationUtils.getInstance().setCircle(radius,latitude,longitude));
baiduMap.addOverlay( LocationUtils.getInstance().getMarker(latitude,longitude));
baiduMap.addOverlays(LocationUtils.getInstance().addMarkers());
baiduMap.setMapStatus(LocationUtils.getInstance().setUserMapCenter(latitude,longitude));
}else if (bdLocation.getLocType()==161){ //网络定位结果,网络定位成功
//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取经纬度相关(常用)的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明
double latitude = bdLocation.getLatitude(); //获取纬度信息
double longitude = bdLocation.getLongitude(); //获取经度信息
float radius = bdLocation.getRadius(); //获取定位精度,默认值为0.0f
baiduMap.addOverlay(LocationUtils.getInstance().setCircle(radius,latitude,longitude));
baiduMap.addOverlay( LocationUtils.getInstance().getMarker(latitude,longitude));
baiduMap.addOverlays(LocationUtils.getInstance().addMarkers());
baiduMap.setMapStatus(LocationUtils.getInstance().setUserMapCenter(latitude,longitude));
}else{ //定位失败
Log.i(TAG,"定位失败,错误码:"+bdLocation.getLocType()); //拿到错误码对照定位错误的返回码来具体检查自己的那步出现了问题
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initPermission();
}
/**
* 初始化View
*/
private void initView() {
mapView = findViewById(R.id.mapView);
baiduMap = mapView.getMap();
}
/**
* 初始化权限申请
*/
private void initPermission() {
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
checkPhoneHasPermission();
}else{
LocationUtils.getInstance().requestLocation(this,listener);
}
}
/**
* 检查手机权限
*/
private void checkPhoneHasPermission() {
unauthorizedPermissions.clear();
for (int i = 0; i < permissions.length;i++){
if (ContextCompat.checkSelfPermission(this,permissions[i])!= PackageManager.PERMISSION_GRANTED){
unauthorizedPermissions.add(permissions[i]);
}
}
if (unauthorizedPermissions.size()>0){
String[] permission2 = unauthorizedPermissions.toArray(new String[unauthorizedPermissions.size()]);
ActivityCompat.requestPermissions(this,permission2,PERMISSION_REQUEST_CODE);
}else{
LocationUtils.getInstance().requestLocation(this,listener);
}
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
boolean hasPermissionDismiss = false;//有权限没有通过
if (PERMISSION_REQUEST_CODE==requestCode){
for (int i = 0;i < grantResults.length;i++){
if (grantResults[i]==-1){
hasPermissionDismiss = true;
}
}
//如果有权限没有被允许
if (hasPermissionDismiss) {
Toast.makeText(this, "您没有授予权限,请您到系统设置中设置该权限,再重新进行定位", Toast.LENGTH_SHORT).show();;//跳转到系统设置权限页面,或者直接关闭页面,不让他继续访问
}else{
//全部权限通过,可以进行下一步操作。。。
LocationUtils.getInstance().requestLocation(this,listener);
}
}
}
}