承接上文,上文已经实现了按照纬经度进行地点的定位以及不同地图类型的切换,https://blog.csdn.net/qq_41562408/article/details/82802082但是就我们普通用户的需求来说,这远远不够。用户更希望能够直接显示自己的当前位置,而不是通过输入经纬度来定位。在真实情况中不现实。同时对于开发人员来说,开发百度地图不光光只是为了简单的地图显示,肯定希望在地图上进行一定的操作,或添加标记,或导航,或距离查询等。。。。。。
这篇文章主要为实现百度地图开发中的定位当前位置以及在百度地图上添加覆盖物进行展开,希望能够为读者有所帮助,同时希望读者有什么好的建议能够提出来,帮助我的进步。废话不多说,开发开始了。
不知道各位有没有遇到和我一样的情况,明明按照百度开发官方文档进行定位操作一步步走过来 ,就是不能定位到当前位置,近乎崩溃,还好csdn里面大神多,东查查,西找找。还真让我解决了。具体引用太多了,我也不清楚了。也为了方便读者我就不就行各种链接了,直接在本次文章中整理。考虑到功能堆叠界面就需要好好规划了,而且代码也会堆叠容易眼花缭乱不利于交流,所以决定将之前的项目分享出去,网址为:https://download.csdn.net/download/qq_41562408/10683082(文章版)、https://download.csdn.net/download/qq_41562408/10683086(改良版)重新开一个项目,只是为了解决一个个单独的问题,后期笔者会提交一个完整的技术列表项目。欢迎读者交流。
现就针对本次文章中的问题进行解决:①、实时定位;②地图覆盖物;
1、就定位问题对于我来说确实有点麻烦,因为开发文档写的确实太简单,好不容易感觉走下来了,定位失败,确实让人感觉崩溃。还好四处查资料,算是解决了,解决的具体思路还是通过确定当地纬经度确定当前位置。
工程计较复杂,之间上代码,代码上有说明,亲测有效:
package wang.baidumap.com;
import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
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.view.View;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
protected MapView mapView = null;
public BaiduMap baiduMap;
private BroadcastReceiver receiver;
private RadioGroup leixing;
public LocationClient mLocationClient;
private boolean isFirstLocate=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocationClient=new LocationClient(getApplicationContext());
mLocationClient.registerLocationListener(new MyLocationListener());
mapView = (MapView) findViewById(R.id.bmapView);
leixing=(RadioGroup)findViewById(R.id.leixin);
baiduMap=mapView.getMap();//获取地图控制器
registerSDKCheckReceiver();
leixing.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i){
case R.id.putong:baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);baiduMap.setTrafficEnabled(false);baiduMap.setBaiduHeatMapEnabled(false);break;
case R.id.weixin:baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);baiduMap.setTrafficEnabled(false);baiduMap.setBaiduHeatMapEnabled(false);break;
case R.id.kongbai:baiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);baiduMap.setTrafficEnabled(false);baiduMap.setBaiduHeatMapEnabled(false);break;
case R.id.shikuan:baiduMap.setTrafficEnabled(true);baiduMap.setBaiduHeatMapEnabled(false);break;
case R.id.reli:baiduMap.setBaiduHeatMapEnabled(true);baiduMap.setTrafficEnabled(false);break;
}
}
});
baiduMap.setMyLocationEnabled(true);
//positionText= (TextView) findViewById(R.id.position_text_view);
List<String> permissionList=new ArrayList<>();
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED){
permissionList.add(Manifest.permission.READ_PHONE_STATE);
}
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if(!permissionList.isEmpty()){
String[]permissions=permissionList.toArray(new String[permissionList.size()]);
ActivityCompat.requestPermissions(MainActivity.this,permissions,1);
}else{
requestLocation();
}
}
private void requestLocation(){
initLocation();
mLocationClient.start();
}
private void navigateTo(BDLocation location){
if(isFirstLocate){
LatLng ll=new LatLng(location.getLatitude(),location.getLongitude());//LatLng类用于存放经纬度
// 第一个参数是纬度值,第二个参数是精度值。这里输入的是本地位置。
MapStatusUpdate update= MapStatusUpdateFactory.newLatLng(ll);//将LatLng对象传入
baiduMap.animateMapStatus(update);
update=MapStatusUpdateFactory.zoomTo(16f);//百度地图缩放范围,限定在3-19之间,可以去小数点位值
// 值越大,地图显示的信息越精细
baiduMap.animateMapStatus(update);
isFirstLocate=false;//防止多次调用animateMapStatus()方法,以为将地图移动到我们当前位置只需在程序
// 第一次定位的时候调用一次就可以了。
}
MyLocationData.Builder locationBuilder=new MyLocationData.Builder();
locationBuilder.latitude(location.getLatitude());
locationBuilder.longitude(location.getLongitude());
MyLocationData locationData=locationBuilder.build();
baiduMap.setMyLocationData(locationData);//获取我们的当地位置
}
private void initLocation() {
LocationClientOption option=new LocationClientOption();
option.setScanSpan(5000);//表示每5秒更新一下当前位置
option.setIsNeedAddress(true);
option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);
// Hight_Accuracy表示高精确度模式,会在GPS信号正常的情况下优先使用GPS定位,在无法接收GPS信号的时候使用网络定位。
// Battery_Saving表示节电模式,只会使用网络进行定位。
// Device_Sensors表示传感器模式,只会使用GPS进行定位。
mLocationClient.setLocOption(option);
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocationClient.stop();//销毁之前,用stop()来停止定位
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mapView.onDestroy();
unregisterReceiver(receiver);
baiduMap.setMyLocationEnabled(false);
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mapView.onPause();
}
private void registerSDKCheckReceiver(){
receiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
if (SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR.equals(action)){
Toast.makeText(getApplicationContext(),"网络错误",Toast.LENGTH_SHORT).show();
}else if (SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR.equals(action)){
Toast.makeText(getApplicationContext(),"KEY验证失败",Toast.LENGTH_SHORT).show();
}
}
};
IntentFilter filter=new IntentFilter();
//监听网络错误
filter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);
//监听百度地图SDK的key是否正确
filter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);
registerReceiver(receiver,filter);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 1:
if(grantResults.length>0){
for(int result:grantResults){
if(result!=PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,"必须同意所有权限才能使用本程序",Toast.LENGTH_LONG).show();
finish();
return;
}
}
requestLocation();
}else{
Toast.makeText(this,"发生未知错误",Toast.LENGTH_LONG).show();
finish();
}
break;
default:
}//onRequestPermissionsResult()方法中,对权限申请结果进行逻辑判断。这里使用一个循环对每个权限进行判断,
// 如果有任意一个权限被拒绝了,那么就会直接调用finish()方法关闭程序,只有当所有的权限被用户同意了,才会
// 调用requestPermissions()方法开始地理位置定位。
}
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if(location.getLocType()==BDLocation.TypeGpsLocation||location.getLocType()==BDLocation.TypeNetWorkLocation){
navigateTo(location);
}
}
}
}
运行结果如下:
就此定位工具以及实现。
2、 就地图覆盖物
根据开发文档以及我个人的开发理解,对于地图覆盖物,主要是依靠提供的纬经度进行确定位置,并进行属性的添加便可。较为难度就属于标注覆盖物了。为了保持文章的独立性,“高内聚,低耦合嘛”,先偷个懒,下一篇进行讲解。