根据项目的需要今天做一个百度地图得功能: 百度地图API使用详解 1、百度地图状态改变监听,用户拖动地图(可以设置只能在半径范围内活动)可以实时展示经纬度
2、接入全国各省市离线地图,下载离线地图后无网络情况下实时显示位置
3、设置导航路线,从当前位置到目的地调用第三方地图导航
效果图:
下面开始讲一下项目中主要知识点,文章末尾附上demo,便于更多的同学运用
集成百度地图api
使用百度地图api需要申请密钥,如下网址有详细操作步奏
http://lbsyun.baidu.com/index.php?title=androidsdk/guide/key
其中获取sha1值时如果使用的是androidstudio有一个最快的方式请看截图:按照1,2,3步骤即可快速获取sha1值。
1、接下来在application中SDK 各组间之前初始化
// 在使用 SDK 各组间之前初始化 context 信息,传入 ApplicationContext
SDKInitializer.initialize(this);
2、在清单文件中替换成你自己申请的API_KEY,避免地图不显示经纬度问题。
<application
android:name="com.ctao.demo.BaseApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="CgtUAFYmzRU1D1ySVHGwqszUewr5382g" />
</application>
3、 在MainActivity中主要代码:
private void initSettingMapView() {
// 初始化地图
mMapView.showZoomControls(false);
mBaiduMap = mMapView.getMap();
// 开启定位图层
mBaiduMap.setMyLocationEnabled(true);
// 定位初始化
mLocationClient = new LocationClient(this);
mLocationClient.registerLocationListener(new MyBDLocationListner());
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);// 打开gps
option.setCoorType(CoordinateType.BD09LL); // 设置坐标类型
option.setScanSpan(1000);
mLocationClient.setLocOption(option);
mLocationClient.start();
//初始化缩放比例
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);
mBaiduMap.setMapStatus(msu);
mBaiduMap.setOnMapTouchListener(new MyMapTouchListener());
// 初始化当前MapView中心屏幕坐标(物理坐标)
mMapView.post(new Runnable() {
@Override
public void run() {
mCenterPoint = mBaiduMap.getMapStatus().targetScreen;
int x = mCenterPoint.x;
int y = mCenterPoint.y;
ImageView imageview = new ImageView(getApplicationContext());
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_location_chatbox);
imageview.setImageBitmap(bitmap);
imageview.setX(x - bitmap.getWidth() / 2);
imageview.setY(y - bitmap.getHeight());
ViewGroup parent = (ViewGroup) mMapView.getParent();
parent.addView(imageview,new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT));
}
});
//初始化当前地理坐标
mLoactionLatLng = mBaiduMap.getMapStatus().target;
// 地理编码
mGeoCoder = GeoCoder.newInstance();
mGeoCoder.setOnGetGeoCodeResultListener(new MyGetGeoCoderResultListener());
}
该代码主要包含初始化地图,打开定位,设置当前覆盖物,获取地理位置编码
// 定位监听器
private class MyBDLocationListner implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null || mMapView == null){
return;
}
MyLocationData data = new MyLocationData.Builder()//
.accuracy(mRadius)//location.getRadius()
.direction(location.getDirection())
.latitude(location.getLatitude())//
.longitude(location.getLongitude())//
.build();
mBaiduMap.setMyLocationData(data);
mLatitude = location.getLatitude();
mLongtitude = location.getLongitude();
mLoactionLatLng = new LatLng(mLatitude, mLongtitude);
// 是否第一次定位
if (isFirstLoc) {
isFirstLoc = false;
// 实现动画跳转
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);
mBaiduMap.animateMapStatus(u);
mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption()).location(mLoactionLatLng));
}
}
}
该代码定位当前位置得监听器,通过location获取到经纬度,通过
new MyLocationData.Builder()//
.accuracy(mRadius)//location.getRadius()
.direction(location.getDirection())
.latitude(location.getLatitude())//
.longitude(location.getLongitude())//
.build();
可以得出当前半径得范围,demo中设置的radius=500。
// 地图触摸事件监听器
private class MyMapTouchListener implements BaiduMap.OnMapTouchListener {
@Override
public void onTouch(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP ) {
if (mCenterPoint == null) {
return;
}
// 获取当前MapView中心屏幕坐标对应的地理坐标
currentLatLng = mBaiduMap.getProjection().fromScreenLocation(mCenterPoint);
//发起反地理编码检索
mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption()).location(currentLatLng));
double distance = getDistance(mLongtitude, mLatitude, currentLatLng.longitude, currentLatLng.latitude);
Toast.makeText(MainActivity.this,"当前纬度"+ currentLatLng.latitude+"当前经度"+ currentLatLng.longitude,Toast.LENGTH_LONG).show();
if(distance > mRadius){
Toast.makeText(MainActivity.this,"已经超出可选区域范围",Toast.LENGTH_LONG).show();
//设定中心点坐标
LatLng point = new LatLng(mLatitude, mLongtitude);
//定义地图状态
MapStatus mMapStatus = new MapStatus.Builder()
.target(point)
.zoom(17)
.build();
//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
//改变地图状态
mBaiduMap.setMapStatus(mMapStatusUpdate);
}
}
}
}
该代码是通过手指移动地图位置,地图选点获取经纬度,根据之前按设置得半径,如果移动的终点和起点得距离大于500时移动的点直接回到原点处,
点击离线地图时直接跳到百度地图离线页面,下载离线地图使用。
点击导航按钮时,通过移动的位置点为终点,起点为当前点,调用第三方的app(如百度,高德,腾讯) 高德地图:http://lbs.amap.com/api/amap-mobile/guide/android/route 百度地图:http://lbsyun.baidu.com/index.php?title=uri/api/android 腾讯地图:http://lbs.qq.com/uri_v1/guide-route.html 一定要注意打开之前确认下是否安装第三方地图app,具体的写法如果调用百度,高德,腾讯可以参照下面得util工具类
public class Util {
private static final String BAIDU_PACKAGE_NAME = "com.baidu.BaiduMap";
private static final String GAODE_PACKAGE_NAME = "com.autonavi.minimap";
private static final String TENCENT_PACKAGE_NAME = "com.tencent.map";
/**
* 是否安装百度地图
*/
public static boolean haveBaiduMap(Context context) {
return exist(context, BAIDU_PACKAGE_NAME);
}
public static boolean haveGaodeMap(Context context) {
return exist(context, GAODE_PACKAGE_NAME);
}
public static boolean haveTencentMap(Context context) {
return exist(context, TENCENT_PACKAGE_NAME);
}
/**
* 检查手机上是否安装了指定的软件
*
* @param context
* @param packageName:应用包名
* @return true 存在
*/
public static boolean exist(Context context, String packageName) {
//获取packagemanager
final PackageManager packageManager = context.getPackageManager();
//获取所有已安装程序的包信息
List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
//用于存储所有已安装程序的包名
List<String> packageNames = new ArrayList<>();
//从pinfo中将包名字逐一取出,压入pName list中
if (packageInfos != null) {
for (int i = 0; i < packageInfos.size(); i++) {
String packName = packageInfos.get(i).packageName;
packageNames.add(packName);
}
}
//判断packageNames中是否有目标程序的包名,有true,没有false
return packageNames.contains(packageName);
}
/**
* 调用高德地图app,导航
*
* @param context 上下文
* @param destination 目标经纬度
* @param destinationAddress 目标地址
* 高德地图:http://lbs.amap.com/api/amap-mobile/guide/android/route
*/
public static void openGaodeMap(Context context, LatLng destination,
String destinationAddress) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse("amapuri://route/plan/?" +
"dlat=" + destination.latitude +
"&dlon=" + destination.longitude +
"&dname=" + destinationAddress +
"&dev=0" +
"&t=0"));
context.startActivity(intent);
}
/**
* 调用百度地图
*
* @param destination 目的地经纬度
* @param destinationAddress 目的地地址
* 百度参考网址:http://lbsyun.baidu.com/index.php?title=uri/api/android
*/
public static void openBaiduMap(Context context, LatLng destination,
String destinationAddress) {
Intent intent = new Intent();
intent.setData(Uri.parse("baidumap://map/direction?" +
"destination=latlng:" + destination.latitude + "," + destination.longitude +
"|name:" + destinationAddress +
"&mode=driving"));
context.startActivity(intent);
}
/**
* 调用腾讯地图
*
* @param context
* @param destination 目的地经纬度
* @param destinationAddress 目的地地址
* 腾讯地图参考网址:http://lbs.qq.com/uri_v1/guide-route.html
*/
public static void openTentcentMap(Context context, LatLng destination, String destinationAddress) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.setData(Uri.parse("qqmap://map/routeplan?" +
"type=drive" +
"&from=" +
"&fromcoord=" +
"&to=" + destinationAddress +
"&tocoord=" + destination.latitude + "," + destination.longitude +
"&policy=0" +
"&referer=appName"));
context.startActivity(intent);
}
/**
* 打开网页版 导航
* 不填我的位置,则通过浏览器定未当前位置
*
* @param context
* @param myLatLng 起点经纬度
* @param myAddress 起点地址名展示
* @param destination 终点经纬度
* @param destinationAddress 终点地址名展示
*/
public static void openBrowserMap(Context context, LatLng myLatLng, String myAddress, LatLng destination,
String destinationAddress) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.setData(Uri.parse("http://uri.amap.com/navigation?" +
"from=" + myLatLng.longitude + "," + myLatLng.latitude + "," + myAddress +
"to=" + destination.longitude + "," + destination.latitude + "," + destinationAddress +
"&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0"));
context.startActivity(intent);
}
}
到此处,主要代码都已经讲解完了,包含地图定位,离线地图,导航路线等,希望对有需要的同学提供帮助,下面附上完整的代码地址:
有问题可以在下方留言讨论,谢谢大家!