百度地图是我们日常生活中必不可少的,他能帮助我们找到自己想去的地方,方便出行等等。
下面我就来介绍一下怎样去使用百度地图来实现自定位功能,跟着我的思路往下走。。。。。。
一、打开百度地图的官方网站http://lbsyun.baidu.com/
选中导航栏的开发文档再点开Android定位SDK,再根据官网的流程讲解,一步一步的跟着他的步骤做就可以了。
首先,我们要获取一个密匙来调用百度地图的SDK,其中需要获取安全码
获取安全码:
使用jdk的keytool工具获取sha1指纹,输入keytool -list -v -keystore debug.keystore ,debug.keystore的密钥库口令默认为“android”
操作示例:
打开cmd控制台
C:\Users\willkong>cd .android
C:\Users\willkong.android>keytool -list -v -keystore debug.keystore
输入密钥库口令:
密钥库类型: JKS
密钥库提供方: SUN
您的密钥库包含 1 个条目
别名: androiddebugkey
创建日期: 2016-7-29
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: C=US, O=Android, CN=Android Debug
发布者: C=US, O=Android, CN=Android Debug
序列号: 1
有效期开始日期: Fri Jul 29 23:27:59 CST 2016, 截止日期: Sun Jul 22 23:27:59 CST
2046
证书指纹:
MD5: AB:6B:65:37:46:32:E4:DB:E2:70:23:83:EB:1F:53:A2
SHA1: EE:C2:F3:D1:69:ED:DD:9B:83:2D:BA:FB:82:33:1A:A9:D7:06:54:0E
SHA256: FF:36:EC:EB:96:BB:65:06:C8:C4:91:D0:AD:B9:8B:63:E3:C7:B0:06:C7:
53:6F:8A:0C:4D:1C:FB:B9:9B:1F:28
注意:
运行百度地图的Demo的时候,在key正确的情况下,出现出现230错误,key校验失败的时候,解决方法是:
我们的sha1值是通过keystore文件获取的,而百度地图demo中用的是自己的keystore文件,在百度地图Demo的app文件夹下找到了debug.keystore文件,把这个删除了复制了一份.android 文件夹下的debug.keystore文件,再次build,重新运行,就OK了。
下面就配置我们的开发工程。在Android studio新建一个工程
1、在src的main目录下新建一个jniLibs目录,把从官网下载下来的开发包复制到这个目录下。如下图:
2、添加AK(添加我们申请到的调用密匙)
在Application标签中增加如下代码:
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="开发者申请的AK" >
</meta-data>
3、添加定位权限
使用定位SDK,需在Application标签中声明service组件,每个App拥有自己单独的定位service,代码如下:
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"> </service>
除添加service组件外,使用定位SDK还需添加如下权限:
<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!-- 用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!-- 访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- SD卡读取权限,用户写入离线定位数据-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
这里我们先集合进百度地图sdk
1、添加地图所需权限
<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导航,配置Camera权限
2、在布局activity_main.xml文件中添加地图控件;
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mybaidumap.HelloBaiduMapActivity">
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
</android.support.constraint.ConstraintLayout>
3、在应用程序创建时初始化 SDK引用的Context 全局变量;创建一个MyApplication类继承Application
package com.mybaidumap;
import android.app.Application;
import com.baidu.mapapi.SDKInitializer;
public class MyApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(getApplicationContext());
}
}
4、创建一个应用百度地图的Activity基类BaseActivity
package com.mybaidumap;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
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.model.LatLng;
public abstract class BaseActivity extends Activity{
private static final String TAG = "BaseActivity";
protected LatLng hmPos = new LatLng(40.050513, 116.30361);
protected LatLng czPos = new LatLng(40.065817,116.349902);
/** 天安门坐标 */
protected LatLng tamPos = new LatLng(39.915112,116.403963);
/**卓越世纪中心1号楼坐标*/
protected LatLng zysjzxPos = new LatLng(114.070427,22.537591);
protected MapView mMapView;
protected BaiduMap baiduMap;
//这里加final是为了不让子类覆盖,原因是为了预防这里的一些类还没初始化的时候就被子类调用
@Override
protected final void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.bmapView);
baiduMap = mMapView.getMap();//获取地图控制器
//1、隐藏缩放按钮,比例尺
// mMapView.showScaleControl(false);//隐藏比例按钮,默认是显示的
// mMapView.showZoomControls(false);//隐藏缩放按钮,默认是显示的
//2、获取最小(3)、最大缩放级别(22)
float maxZoomLevel = baiduMap.getMaxZoomLevel();//获取地图最大缩放级别
float minZoomLevel = baiduMap.getMinZoomLevel();//获取地图最小缩放级别
Log.e(TAG,"minZoomLevel ="+minZoomLevel+",maxZoomLevel="+maxZoomLevel);//最小为3,最大为22
//3、设置地图中心为
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(hmPos);
baiduMap.setMapStatus(mapStatusUpdate);
//4、设置地图缩放为15
mapStatusUpdate = MapStatusUpdateFactory.zoomTo(15);
baiduMap.setMapStatus(mapStatusUpdate);
//6.获取地图Ui控制器:隐藏指南针
// UiSettings uiSettings = baiduMap.getUiSettings();
// uiSettings.setCompassEnabled(false);//不显示指南针
init();
}
/**
* 子类实现此方法
*/
public abstract void init();
/**
* 在屏幕中央显示一个Toast
* @param text
*/
public void showToast(CharSequence text){
Utils.showToast(this,text);
}
@Override
protected void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
}
5、创建一个定位Activity类LocationActivity
package com.mybaidumap;
import android.util.Log;
import android.view.KeyEvent;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.Poi;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import java.util.List;
public class LocationActivity extends BaseActivity {
private static final String TAG = "LocationActivity";
public LocationClient mLocationClient = null;
private MyLocationListener myListener = new MyLocationListener();
public class MyLocationListener extends BDAbstractLocationListener{
@Override
public void onReceiveLocation(BDLocation location){
if (location!=null){
MyLocationData.Builder builder = new MyLocationData.Builder();
builder.accuracy(location.getRadius());//设置精度
builder.direction(location.getDirection());//设置方向
builder.latitude(location.getLatitude());//设置纬度
builder.longitude(location.getLongitude());//设置经度
MyLocationData locationData = builder.build();
baiduMap.setMyLocationData(locationData);//把定位数据显示到地图上
}
//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取经纬度相关(常用)的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明
double latitude = location.getLatitude(); //获取纬度信息
double longitude = location.getLongitude(); //获取经度信息
float radius = location.getRadius(); //获取定位精度,默认值为0.0f
String coorType = location.getCoorType();
//获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
int errorCode = location.getLocType();
//获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
Log.e(TAG,"经度="+longitude+",纬度="+latitude+",错误码="+errorCode);
//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取地址相关的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明
String addr = location.getAddrStr(); //获取详细地址信息
String country = location.getCountry(); //获取国家
String province = location.getProvince(); //获取省份
String city = location.getCity(); //获取城市
String district = location.getDistrict(); //获取区县
String street = location.getStreet(); //获取街道信息
Log.e(TAG,"addr:"+addr+",country:"+country
+",province:"+province+",city:"+city
+",district:"+district+",street:"+street);
String locationDescribe = location.getLocationDescribe(); //获取位置描述信息
Log.e(TAG,"位置描述:"+locationDescribe);
List<Poi> poiList = location.getPoiList();
//获取周边POI信息
//POI信息包括POI ID、名称等,具体信息请参照类参考中POI类的相关说明
for (int i=0;i<poiList.size();i++){
Log.e(TAG,"兴趣点:"+poiList.get(i).getName()+"\n");
}
}
}
@Override
public void init() {
mLocationClient = new LocationClient(getApplicationContext());//声明LocationClient类
mLocationClient.registerLocationListener(myListener);//注册监听函数
initLocation();
baiduMap.setMyLocationEnabled(true);//开启定位图层
MyLocationConfiguration.LocationMode mode = MyLocationConfiguration.LocationMode.COMPASS;
setMyLocationConfigeration(mode);
mLocationClient.start();
}
/**
* 设置定位图层的配置
* @param mode
*/
private void setMyLocationConfigeration(MyLocationConfiguration.LocationMode mode) {
boolean enableDirection = true;//设置显示方向
BitmapDescriptor customMarker = BitmapDescriptorFactory.fromResource(R.mipmap.icon_geo);//自定义定位的图标
MyLocationConfiguration locationConfiguration = new MyLocationConfiguration(mode,enableDirection,customMarker);
baiduMap.setMyLocationConfiguration(locationConfiguration);
}
/**
* 初始化定位
*/
private void initLocation() {
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
//可选,设置定位模式,默认高精度
//LocationMode.Hight_Accuracy:高精度;
//LocationMode. Battery_Saving:低功耗;
//LocationMode. Device_Sensors:仅使用设备;
option.setCoorType("bd09ll");
//可选,设置返回经纬度坐标类型,默认gcj02
//gcj02:国测局坐标;
//bd09ll:百度经纬度坐标;
//bd09:百度墨卡托坐标;
//海外地区定位,无需设置坐标类型,统一返回wgs84类型坐标
option.setScanSpan(5000);
//可选,设置发起定位请求的间隔,int类型,单位ms
//如果设置为0,则代表单次定位,即仅定位一次,默认为0
//如果设置非0,需设置1000ms以上才有效
option.setOpenGps(true);
//可选,设置是否使用gps,默认false
//使用高精度和仅用设备两种定位模式的,参数必须设置为true
option.setLocationNotify(true);
//可选,设置是否当GPS有效时按照1S/1次频率输出GPS结果,默认false
option.setIgnoreKillProcess(false);
//可选,定位SDK内部是一个service,并放到了独立进程。
//设置是否在stop的时候杀死这个进程,默认(建议)不杀死,即setIgnoreKillProcess(true)
option.SetIgnoreCacheException(false);
//可选,设置是否收集Crash信息,默认收集,即参数为false
option.setWifiCacheTimeOut(5 * 60 * 1000);
//可选,7.2版本新增能力
//如果设置了该接口,首次启动定位时,会先判断当前WiFi是否超出有效期,若超出有效期,会先重新扫描WiFi,然后定位
option.setEnableSimulateGps(false);
//可选,设置是否需要过滤GPS仿真结果,默认需要,即参数为false
option.setIsNeedAddress(true);
//可选,是否需要地址信息,默认为不需要,即参数为false
//如果开发者需要获得当前点的地址信息,此处必须为true
option.setIsNeedLocationDescribe(true);
//可选,是否需要位置描述信息,默认为不需要,即参数为false
//如果开发者需要获得当前点的位置信息,此处必须为true
option.setIsNeedLocationPoiList(true);
//可选,是否需要周边POI信息,默认为不需要,即参数为false
//如果开发者需要获得周边POI信息,此处必须为true
mLocationClient.setLocOption(option);
//mLocationClient为第二步初始化过的LocationClient对象
//需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
//更多LocationClientOption的配置,请参照类参考中LocationClientOption类的详细说明
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode){
case KeyEvent.KEYCODE_1://罗盘态:显示定位方向圈,保持定位图标在地图中心
setMyLocationConfigeration(MyLocationConfiguration.LocationMode.COMPASS);
break;
case KeyEvent.KEYCODE_2://跟随态:保持定位图标在地图中心
setMyLocationConfigeration(MyLocationConfiguration.LocationMode.FOLLOWING);
break;
case KeyEvent.KEYCODE_3://普通态:更新定位数据时不对地图做任何操作
setMyLocationConfigeration(MyLocationConfiguration.LocationMode.NORMAL);
break;
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onDestroy() {
mLocationClient.stop();
super.onDestroy();
}
}
代码中需要注意的是option.setIsNeedAddress(true);
//可选,是否需要地址信息,默认为不需要,即参数为false
//如果开发者需要获得当前点的地址信息,此处必须为true
这段代码必须设置,这个是开启定位功能。
好了,百度地图的自定位功能基本上就是这些了,是不是很简单呢,确实,你也可以上百度地图的官网的开发者文档中跟着步骤一步一步集成。如果喜欢点波关注谢谢!!!