android百度地图开发——地图sdk之基础地图
来源:互联网 发布:钓鱼王vb强食剂 编辑:程序博客网 时间:2024/05/17 00:57
上一节我们介绍了百度定位sdk,这一节我们在定位的基础上介绍百度地图sdk。
让地图显示出来
首先把上一节布局文件中添加的textview删掉,然后加入MapView这个控件:
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout 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.example.lbstest.MainActivity"> <com.baidu.mapapi.map.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true"/></android.support.constraint.ConstraintLayout>
毫无疑问这个控件就是显示地图的。
接着我们对Activity做以下修改:
private MapView mMapView; private BaiduMap mBaiduMap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mlocation = new LocationClient(getApplicationContext()); mlocation.registerLocationListener(new MyLocationListener()); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); //初始化方向传感器 myOrientationListener = new MyOrientationListener(this); //获取地图控件引用 mMapView = (MapView) findViewById(R.id.mapView); mBaiduMap = mMapView.getMap(); //申请权限 initPermission(); } @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理 mMapView.onResume(); } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理 mMapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mlocation.stop(); //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理 mMapView.onDestroy(); }
和上一节相比多了SDKInitializer初始化、获取MapView实例和获取BaiduMap的实例(BaiduMap是地图的总控制器,它可以对地图进行各种各样的操作),另外还需要重写onDestroy() 、onPause()、 onResume() 这3个方法对MapView进行管理,以保证资源能够及时释放。到这里地图已经能够显示出来了。
显示当前位置
聪明的你一定发现我们并没有设置坐标,这样是不能显示到我们的位置的, 下面我们让地图显示到我们的位置。
这就需要我们上一节中定位sdk的知识了,首先我们把BDLocationListener做一下修改:
public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation bdLocation) { mCurrentAccracy=bdLocation.getRadius(); mCurrentLantitude=bdLocation.getLatitude(); mCurrentLongitude=bdLocation.getLongitude(); if (bdLocation.getLocType() == BDLocation.TypeGpsLocation || bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) { //设置地图显示 navigateTo(bdLocation); } } @Override public void onConnectHotSpotMessage(String s, int i) { } } private void navigateTo(BDLocation location) { if (isFirstLocate) { //定位坐标 LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll); mBaiduMap.animateMapStatus(update); //设置缩放级别 update = MapStatusUpdateFactory.zoomTo(21f); mBaiduMap.animateMapStatus(update); isFirstLocate = false; } }
上面的代码首先在定位回调的函数中将经纬度信息赋值给全局变量,这是在后面使用的我们暂时不看,然后判断是否定位成功,成功后调用navigateTo()方法,在navigateTo()方法中通过一个boolean全局变量判断是否是第一次定位,然户设置定位坐标,缩放级别(其他的设置属性参照官方文档,这里就不多介绍了),现在地图就已经显示在我们的位置了。
运行效果:
显示定位图标
我们用的地图都会有一个图标显示在我们的位置,下面我们来添加这个图标。
首先要在onCreate()方法中调用BaiduMap的setMyLocationEnabled方法开启此功能:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mlocation = new LocationClient(getApplicationContext()); mlocation.registerLocationListener(new MyLocationListener()); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); //初始化方向传感器 myOrientationListener = new MyOrientationListener(this); //获取地图控件引用 mMapView = (MapView) findViewById(R.id.mapView); mBaiduMap = mMapView.getMap(); mBaiduMap.setMyLocationEnabled(true); //申请权限 initPermission(); }
接着在navigateTo方法中添加MyLocationData的构建逻辑:
private void navigateTo(BDLocation location) { if (isFirstLocate) { //定位坐标 LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll); mBaiduMap.animateMapStatus(update); //设置缩放级别 update = MapStatusUpdateFactory.zoomTo(21f); mBaiduMap.animateMapStatus(update); isFirstLocate = false; } MyLocationData.Builder builder = new MyLocationData.Builder(); builder.accuracy(mCurrentAccracy); builder.latitude(mCurrentLantitude); builder.longitude(mCurrentLongitude); MyLocationData locationData = builder.build(); mBaiduMap.setMyLocationData(locationData); }
这里用到了mCurrentAccracy、mCurrentLantitude、mCurrentLongitude这三个保存了经纬度信息的全局变量,MyLocationConfiguration 的最后一个参数设置图标的样式,传入空为默认图标,当然也可以传入一个BitmapDescriptor设置自定义图标。
最后在onDestroy()方法中关闭此功能:
@Override protected void onDestroy() { super.onDestroy(); mlocation.stop(); //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理 mMapView.onDestroy(); mBaiduMap.setMyLocationEnabled(false); }
到这里显示定位图标就完成了。
运行效果:
定位图标与传感器结合显示方向
虽然当前位置的图标显示出来了,但是对于一些路痴来说(比如我)仍然找不到方向,这就需要显示方向了,显示方向的功能实现需要手机的加速度和地磁场传感器,根据这两个传感器计算出手机的角度,然后将这个角度传给MyLocationData.Builder的builder.direction()方法用于设置方向。下面我们开始实现这一功能。
在往下看之前建议先看一下一篇关于传感器的文章:http://www.2cto.com/kf/201412/359292.html
首先创建一个类MyOrientationListener,所有传感器的操作都封装在这个类中:
public class MyOrientationListener implements SensorEventListener { private Context context; private SensorManager sensorManager; private Sensor accelerometer; // 加速度传感器 private Sensor magnetic; // 地磁场传感器 private float[] accelerometerValues = new float[3]; private float[] magneticFieldValues = new float[3]; private float lastX; private OnOrientationListener onOrientationListener ; public MyOrientationListener(Context context) { this.context = context; } @Override public void onSensorChanged(SensorEvent event) { // 接受方向感应器的类型 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { accelerometerValues = event.values; } if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { magneticFieldValues = event.values; } getOrientation(); } public void getOrientation() { float[] values = new float[3]; float[] R = new float[9]; SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticFieldValues); //将角度信息计算后返回到values中 SensorManager.getOrientation(R, values); values[0] = (float) Math.toDegrees(values[0]); //当方向的改变大于一度时回调监听 if( Math.abs(values[0]- lastX) > 1.0 ) { onOrientationListener.onOrientationChanged(values[0]); } lastX = values[0] ; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } public void start(){ // 获得传感器管理器 sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); if (sensorManager != null) { // 初始化加速度传感器 accelerometer = sensorManager .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 初始化地磁场传感器 magnetic = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); } // 注册 if (accelerometer != null || magnetic!=null) { sensorManager.registerListener(this, accelerometer, Sensor.TYPE_ACCELEROMETER); sensorManager.registerListener(this, magnetic, Sensor.TYPE_MAGNETIC_FIELD); } } public void stop() { sensorManager.unregisterListener(this); } public void setOnOrientationListener(OnOrientationListener onOrientationListener) { this.onOrientationListener = onOrientationListener; } public interface OnOrientationListener{ void onOrientationChanged(float x); }}
如果你看了我推荐的那篇文章上面的代码对你来说就是小菜一碟,注释也写得清楚我就不详细介绍了,使用时只需创建一个实例,然后调用start()方法,在设置监听就可以了,最后别忘了stop()。
我们在我们Activity实现这个类:
首先在oncreat()方法中实例化这个类,并设置监听,把接收的参数赋值给一个全局变量:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mlocation = new LocationClient(getApplicationContext()); mlocation.registerLocationListener(new MyLocationListener()); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); //初始化方向传感器 myOrientationListener = new MyOrientationListener(this); myOrientationListener.setOnOrientationListener(this); //获取地图控件引用 mMapView = (MapView) findViewById(R.id.mapView); mBaiduMap = mMapView.getMap(); mBaiduMap.setMyLocationEnabled(true); //申请权限 initPermission(); }
接着在onResume()方法中调用MyOrientationListener的start()方法:
@Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理 mMapView.onResume(); myOrientationListener.start(); }
然后把navigateTo()方法中对MyLocationData.Builder的配置删掉:
private void navigateTo(BDLocation location) { if (isFirstLocate) { //定位坐标 LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll); mBaiduMap.animateMapStatus(update); //设置缩放级别 update = MapStatusUpdateFactory.zoomTo(21f); mBaiduMap.animateMapStatus(update); isFirstLocate = false; } }
最后在MyOrientationListener的监听方法中添加以下代码:
@Override public void onOrientationChanged(float x) { mXDirection = (int) x; builder = new MyLocationData.Builder(); builder.accuracy(mCurrentAccracy); builder.direction(mXDirection); builder.latitude(mCurrentLantitude); builder.longitude(mCurrentLongitude); MyLocationData locationData = builder.build(); mBaiduMap.setMyLocationData(locationData); // 设置自定义图标 //BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory.fromResource(R.drawable.arrow); MyLocationConfiguration configuration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, null); mBaiduMap.setMyLocationConfiguration(configuration); }
我们对MyLocationData增加了一个设置builder.direction(mXDirection)。最后还要用MyLocationConfiguration对BaiduMap进行配置,MyLocationConfiguration的第一个参数为图标显示模式,有三种模式我就不一一介绍了,有兴趣的同学可以自己试试,或者参考官方文档,第二个参数表示是否显示方向,第三个参数为自定义图标,如果使用默认图标传入空就行了。
最后别忘了在onDestroy()方法中stop方向传感器:
@Override protected void onDestroy() { super.onDestroy(); mlocation.stop(); //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理 mMapView.onDestroy(); mBaiduMap.setMyLocationEnabled(false); }
运行效果:
到这里百度地图sdk的初使用也完成了,下面是完整的代码:
public class MainActivity extends AppCompatActivity implements MyOrientationListener.OnOrientationListener{ private MapView mMapView; private BaiduMap mBaiduMap; private List<String> permissionList; private Boolean isFirstLocate=true; private float mCurrentAccracy; private double mCurrentLantitude; private double mCurrentLongitude; private int mXDirection; public LocationClient mlocation; private MyLocationData.Builder builder; private MyOrientationListener myOrientationListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mlocation = new LocationClient(getApplicationContext()); mlocation.registerLocationListener(new MyLocationListener()); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); //初始化方向传感器 myOrientationListener = new MyOrientationListener(this); myOrientationListener.setOnOrientationListener(this); //获取地图控件引用 mMapView = (MapView) findViewById(R.id.mapView); mBaiduMap = mMapView.getMap(); mBaiduMap.setMyLocationEnabled(true); //申请权限 initPermission(); } private void initPermission() { 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(); } } @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(MainActivity.this, "必须同意所有权限", Toast.LENGTH_LONG).show(); finish(); return; } } //请求定位 requestLocation(); } else { finish(); } break; } } private void requestLocation() { //设置定位属性 initLocation(); //开始定位 mlocation.start(); } private void initLocation() { LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); //设置百度坐标 option.setCoorType("bd09ll"); option.setOpenGps(true); // 打开gps //设置定位延迟 option.setScanSpan(3000); mlocation.setLocOption(option); } @Override public void onOrientationChanged(float x) { mXDirection = (int) x; builder = new MyLocationData.Builder(); builder.accuracy(mCurrentAccracy); builder.direction(mXDirection); builder.latitude(mCurrentLantitude); builder.longitude(mCurrentLongitude); MyLocationData locationData = builder.build(); mBaiduMap.setMyLocationData(locationData); // 设置自定义图标 //BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory.fromResource(R.drawable.arrow); MyLocationConfiguration configuration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, null); mBaiduMap.setMyLocationConfiguration(configuration); } public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation bdLocation) { mCurrentAccracy=bdLocation.getRadius(); mCurrentLantitude=bdLocation.getLatitude(); mCurrentLongitude=bdLocation.getLongitude(); if (bdLocation.getLocType() == BDLocation.TypeGpsLocation || bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) { //设置地图显示 navigateTo(bdLocation); } } @Override public void onConnectHotSpotMessage(String s, int i) { } } private void navigateTo(BDLocation location) { if (isFirstLocate) { //定位坐标 LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll); mBaiduMap.animateMapStatus(update); //设置缩放级别 update = MapStatusUpdateFactory.zoomTo(21f); mBaiduMap.animateMapStatus(update); isFirstLocate = false; } } @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理 mMapView.onResume(); myOrientationListener.start(); } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理 mMapView.onPause(); } @Override protected void onStop() { super.onStop(); myOrientationListener.stop(); } @Override protected void onDestroy() { super.onDestroy(); mlocation.stop(); //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理 mMapView.onDestroy(); mBaiduMap.setMyLocationEnabled(false); }}
public class MyOrientationListener implements SensorEventListener { private Context context; private SensorManager sensorManager; private Sensor accelerometer; // 加速度传感器 private Sensor magnetic; // 地磁场传感器 private float[] accelerometerValues = new float[3]; private float[] magneticFieldValues = new float[3]; private float lastX; private OnOrientationListener onOrientationListener ; public MyOrientationListener(Context context) { this.context = context; } @Override public void onSensorChanged(SensorEvent event) { // 接受方向感应器的类型 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { accelerometerValues = event.values; } if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { magneticFieldValues = event.values; } getOrientation(); } public void getOrientation() { float[] values = new float[3]; float[] R = new float[9]; SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticFieldValues); //将角度信息计算后返回到values中 SensorManager.getOrientation(R, values); values[0] = (float) Math.toDegrees(values[0]); //当方向的改变大于一度时回调监听 if( Math.abs(values[0]- lastX) > 1.0 ) { onOrientationListener.onOrientationChanged(values[0]); } lastX = values[0] ; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } public void start(){ // 获得传感器管理器 sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); if (sensorManager != null) { // 初始化加速度传感器 accelerometer = sensorManager .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 初始化地磁场传感器 magnetic = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); } // 注册 if (accelerometer != null || magnetic!=null) { sensorManager.registerListener(this, accelerometer, Sensor.TYPE_ACCELEROMETER); sensorManager.registerListener(this, magnetic, Sensor.TYPE_MAGNETIC_FIELD); } } public void stop() { sensorManager.unregisterListener(this); } public void setOnOrientationListener(OnOrientationListener onOrientationListener) { this.onOrientationListener = onOrientationListener; } public interface OnOrientationListener{ void onOrientationChanged(float x); }}
- android百度地图开发——地图sdk之基础地图
- android开发游记:百度地图SDK基础地图的使用
- 百度地图android sdk开发之基础错误集合
- Android开发之集成百度地图SDK
- Android中级篇之百度地图SDK v3.5.0-基础地图[图解百度地图基础教程]
- Android百度地图SDK开发
- 百度地图开发之基础地图
- Android 开发百度地图之一基础地图
- Android 百度地图开发之地图初始化
- Android 百度地图开发之地图定位
- android百度地图开发——android studio配置sdk
- 百度地图移动开发——(Android SDK v3.5.0)
- android百度地图开发——定位sdk
- 百度地图Android SDK
- android 百度地图sdk
- 百度地图sdk Android
- 百度地图 android SDK
- [Android]百度地图开发之SDK开发环境搭建
- grunt构建&文件合并与压缩
- bonjour代理获取多个服务的方式
- itchat4j -- 用Java扩展个人微信号的能力
- 事务的传播行为
- C语言的程序结构
- android百度地图开发——地图sdk之基础地图
- Win10/Win7小技巧:教你如何彻底关闭系统进程
- typedef 与define的联系和区别
- Digitalocean VPS centos 7安装图形化界面KDE和VNC实现远程图形化操作
- POJ3624--Charm Bracelet(dp)
- DP新姿势
- sleep 和 wait 区别
- 希尔排序(java实现)
- leetcode题235. Lowest Common Ancestor of a Binary Search Tree