版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38357358/article/details/79290590
项目需求:
- 接入地图
- 定位位置
- 设置百度地图上的各种图标
- 加载方格的问题
接入地图
1.创建应用
接入的是百度地图,首先去百度地图开放平台上添加应用。在http://lbsyun.baidu.com/apiconsole/key/create网址中创建应用,没有百度账号的,先注册百度账号。
在创建应用页面:
应用名称:随意填写;
启用服务:根据需求自行选择;
SHA1:在android studio右侧的Gradle里面,选择项目的Taks中的android中的signingReport,则在run中显示所需的SHA1值和MD5的值。注:若没有SHA1的值,先去给Build菜单里面Generate signing apk
包名:在build.gradle里面,applicationId 为包名,若Manifest.xml中的包名与其不一致,取build.gradle里面的为准。
创建完成后会生成AK值,在权限中需要填写
2.下载百度地图jar包
把下载好的jar包复制到工程的libs中,然后右键选择add as library
在main目录下,创建jniLibs文件夹,将剩下的所有文件全部复制到该文件夹下
在build.gradle中,android里面添加sourSet,这样才能关联到so文件
sourceSets{
main{
jniLibs.srcDir 'libs'
}
}
3.添加权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
//获取设备网络状态,禁用后无法获取网络状态
<uses-permission android:name="android.permission.INTERNET"/>
//网络权限,当禁用后,无法进行检索等相关业务
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
//读取设备硬件信息,统计数据
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
//读取系统信息,包含系统版本等信息,用作统计
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
//获取设备的网络状态,鉴权所需网络代理
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//允许sd卡写权限,需写入地图数据,禁用后无法显示地图
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
//获取统计数据
<uses-permission android:name="android.permission.GET_TASKS" />
//鉴权所需该权限获取进程列表
<uses-permission android:name="android.permission.CAMERA" />
//使用步行AR导航
还需要在application里添加meta_data添加代码
<meta-data android:name="com.baidu.lbsapi.API_KEY"
android:value="VvVpQ7Xukgv5Ko7cK3Cru4p32LoruNqZ"/>
其中name是固定的,value是在百度开发平台创建应用生成的AK值
4.在布局里添加mapView控件
在setContentView方法前面,添加代码
SDKInitializer.initialize(getApplicationContext());
运行即可显示地图
还可以在加上mapView与activity的生命周期绑定
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
//在这里发现一个问题,添加这个方法的话旋转就会有指南针,不添加的话,就不会有指南针???目前还没有找到原因
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
定位
首先在application里面添加服务
//开启定位功能一定要写服务
<service android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote"/>
然后创建一个LocationClient实例,调用registerLocationListner()方法注册定位监听器。获取地理位置之后,会返回一个BDLocation对象,根据这个对象获取定位的信息
private void initLocation() {
LocationClient locationClient = new LocationClient(getApplicationContext());
MyLocationListener myLocationListener = new MyLocationListener();
locationClient.registerLocationListener(myLocationListener);
locationClient.start();
}
public class MyLocationListener implements BDLocationListener{
@Override
public void onReceiveLocation(BDLocation bdLocation) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("获取到的位置的维度:"+ bdLocation.getLatitude());
stringBuilder.append("\n获取到的位置的经度:"+ bdLocation.getLongitude());
//得到获取定位的类型
int locType = bdLocation.getLocType();
if (locType==BDLocation.TypeGpsLocation){
stringBuilder.append("\n获取位置的方式是:GPS");
}else if (locType==BDLocation.TypeNetWorkLocation){
stringBuilder.append("\n获取位置的方式是:网络");
}
//显示地理位置
mtextView.setText(stringBuilder.toString());
}
}
获取精确的地址:
//获取定位结果
bdLocation.getTime(); //获取定位时间
bdLocation.getLocationID(); //获取定位唯一ID,v7.2版本新增,用于排查定位问题
bdLocation.getLocType(); //获取定位类型
bdLocation.getLatitude(); //获取纬度信息
bdLocation.getLongitude(); //获取经度信息
bdLocation.getRadius(); //获取定位精准度
bdLocation.getAddrStr(); //获取地址信息
bdLocation.getCountry(); //获取国家信息
bdLocation.getCountryCode(); //获取国家码
bdLocation.getCity(); //获取城市信息
bdLocation.getCityCode(); //获取城市码
bdLocation.getDistrict(); //获取区县信息
bdLocation.getStreet(); //获取街道信息
bdLocation.getStreetNumber(); //获取街道码(门牌号)
bdLocation.getLocationDescribe(); //获取当前位置描述信息
bdLocation.getPoiList(); //获取当前位置周边POI信息
bdLocation.getBuildingID(); //室内精准定位下,获取楼宇ID
bdLocation.getBuildingName(); //室内精准定位下,获取楼宇名称
bdLocation.getFloor(); //室内精准定位下,获取当前位置所处的楼层信息
地图显示的显然不是我想要的,需要的事直接定位到自己当前的位置,并在地图上显示我的位置。调用MapView的getMap方法获取BaiduMap实例,就可以对地图进行各种各样的操作。因为默认显示的地图的位置是北京,所以我们想移动到自己的当前的位置并缩放大小怎么办?百度SDK中提供了LatLng 类来获取经纬度。它的构造方法接收两个参数,一个纬度,一个经度。再得到纬度和经度之后、我们想设置地图的经纬度和地图,需要用到MapStatus 类通过MapStatus.Builder的方法设置经纬度和地图。最后将设置好的属性装载到BaiduMap里面
为了使用animataMapStatus这个变量,加个布尔类型
if ((locType==BDLocation.TypeNetWorkLocation)||(locType==BDLocation.TypeGpsLocation)){
if (IsFristLocate) {
LatLng latLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
MapStatus.Builder builder = new MapStatus.Builder();
//将位置移到定位的我的位置,zoom设置缩放级别数字越小,代表放大倍数越小,显示范围大。
//参考网址:http://developer.baidu.com/map/android_refer/com/baidu/mapapi/map/MapStatus.Builder.html#zoom(float)
builder.target(latLng).zoom(18.0f);
MapStatus build = builder.build();
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(build);
baidumap.animateMapStatus(mapStatusUpdate);
IsFristLocate = false;
}
//只是完成了移到我的位置。还没有显示我的位置,百度SDK中有个MyLocationData的类,这个类封装了设备当前的地理位置。调用它的Build()方法,生成一个实例。
MyLocationData.Builder databuilder = new MyLocationData.Builder();
databuilder.accuracy(bdLocation.getRadius());
databuilder.direction(100);
databuilder.latitude(bdLocation.getLatitude());
databuilder.longitude(bdLocation.getLongitude());
MyLocationData locationData = databuilder.build();
baidumap.setMyLocationData(locationData);
}
对logo的设置
对地图上的logo设置
MapView mapView = (MapView) findViewById (R.id.mapView);
//可以对mapView设置
mapView.showZoomControls(false); //设置缩放
mapView.showScaleControl(false); //设置比例尺
mapView.removeViewAt(1); //可以把地图上的百度图标移除,0时移除的是地图
//隐藏指南针,在加上onremue方法也是隐藏状态
UiSettings uiSettings = map.getUiSettings();
uiSettings.setCompassEnabled(false);
//自定义显示位置图标
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher);
MyLocationConfiguration myLocationConfiguration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, bitmapDescriptor);
baidumap.setMyLocationConfiguration(myLocationConfiguration);
修改国测局与百度的定位偏差
把上面的MyLocationListener 类改成
public class MyLocationListener implements BDLocationListener{
@Override
public void onReceiveLocation(BDLocation bdLocation) {
if (bdLocation==null|| mapView==null){
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("获取到的位置的维度:"+ bdLocation.getLatitude());
stringBuilder.append("\n获取到的位置的经度:"+ bdLocation.getLongitude());
stringBuilder.append("\n获取到的省份是:" + bdLocation.getProvince());
stringBuilder.append("\n市:"+bdLocation.getCity());
stringBuilder.append("\n区:"+ bdLocation.getDistrict());
stringBuilder.append("\n街道:"+bdLocation.getStreet());
int locType = bdLocation.getLocType();
if (locType==BDLocation.TypeGpsLocation){
stringBuilder.append("\n获取位置的方式是:GPS");
}else if (locType==BDLocation.TypeNetWorkLocation){
stringBuilder.append("\n获取位置的方式是:网络");
}
mtextView.setText(stringBuilder.toString());
if ((locType==BDLocation.TypeNetWorkLocation)||(locType==BDLocation.TypeGpsLocation)){
if (IsFristLocate) {
//将画面移到定位的位置
//此位置为国测局位置,要想准确需要转化为百度地图
// LatLng latLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
LatLng latLng = CoordinateMath.gcj2bd(bdLocation);
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(latLng).zoom(18);//zoom代表放大倍数
MapStatus build = builder.build();
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(build);
baidumap.animateMapStatus(mapStatusUpdate);
IsFristLocate = false;
}
}
//显示定位的位置
MyLocationData.Builder databuilder = new MyLocationData.Builder();
databuilder.accuracy(bdLocation.getRadius());
databuilder.direction(100);
double longtitude = CoordinateMath.gcjLong2bd(bdLocation);
double latitude = CoordinateMath.gcjLat2bd(bdLocation);
databuilder.latitude(latitude);
databuilder.longitude(longtitude);
MyLocationData locationData = databuilder.build();
baidumap.setMyLocationData(locationData);
}
}
自定义CoordinateMath类
public class CoordinateMath {
private final static double PI = 3.14159265358979324;
private final static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
private static LatLng mLatLng;
private static LatLng getLatlng(double lan, double lon) {
if (mLatLng == null) {
mLatLng = new LatLng(lan, lon);
return mLatLng;
}
return mLatLng;
}
/**
* 国测局的坐标转化成百度
*
* @param point
* @return
*/
public static LatLng gcj2bd(BDLocation point) {
double bdlon = gcjLong2bd(point);
double bdlat = gcjLat2bd(point);
LatLng latlng = getLatlng(bdlat, bdlon);
return latlng;
}
/**
* 把国测局经度转化成百度经度
*/
public static double gcjLong2bd(BDLocation point) {
double longitude = point.getLongitude();
double latitude = point.getLatitude();
double x = longitude;
double y = latitude;
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
double bdlon = z * Math.cos(theta) + 0.0065;
double bdlat = z * Math.sin(theta) + 0.006;
return bdlon;
}
/**
* 把国测局纬度转化成百度纬度
*/
public static double gcjLat2bd(BDLocation point) {
double longitude = point.getLongitude();
double latitude = point.getLatitude();
double x = longitude;
double y = latitude;
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
double bdlon = z * Math.cos(theta) + 0.0065;
double bdlat = z * Math.sin(theta) + 0.006;
return bdlat;
}
/**
* 把百度坐标转化为国测局
*
* @param point
* @return
*/
public static LatLng bd2gcj(BDLocation point) {
double bdlon = point.getLongitude();
double bdlat = point.getLatitude();
double x = bdlon - 0.0065;
double y = bdlat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
double gcjLon = z * Math.cos(theta);
double gcjLat = z * Math.sin(theta);
LatLng latlng = getLatlng(gcjLat, gcjLon);
return latlng;
}
}
加载方格问题
原因1:sha1值与包名是否正确,填写的应用名称与strings中的app_name标签是否相符
原因2:复制过来的value值最后,是否有空格