最近在学习百度地图的使用,在此记录一下自己的心得。
一、基础地图的加载
1、下载百度地图的Android SDK,在自定义下载选项中,我们可以根据自己项目的实际需要下载相应的SDk。下载好之后,解压会得到一个libs文件,里面有各种.so和一个.jar文件。
2、创建Android项目,把之前得到的libs文件直接复制到项目中,这样百度地图的SDK就算引入成功了。
3、创建密钥Key,创建的方法很简单,只要有百度账号,就可以在百度开放平台上选择创建应用–>应用类型选择Android SDK–>输入SHA1值,该值在Eclipse环境下在Windows-preferences-build就可以找到–>输入包名,在AndroidManifest.XML文件中找到–>然后提交,就会生成一个有效的Key值了。该Key值只能在该应用下有效,准确是该包名下有效。
4、在AndroidManifest.XML文件中配置相关权限,如下:
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<!-- 这个权限用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 这个权限用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 用于读取手机当前的状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 访问网络,网络定位需要上网 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_TASKS" />
以及application中配置key:
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="VBN5ePCG1XGLOzOg8GrRSfddHbjUUVnG" />
5、在xml文件中添加显示地图的控件,如下:
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
6、界面初始化地图,差不多就可以显示最基础的地图了,不过默认显示的是北京天安门的地图
SDKInitializer.initialize(getApplicationContext());
baiduMap = mapView.getMap();
baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
二、定位自己的位置
首先实例化一个LocationClient的类,然后设置定位所需要的参数,如下:
mLocationClient = new LocationClient(getApplicationContext());//建议使用全局上下文
LocationClientOption loption = new LocationClientOption();
loption.setOpenGps(true); //是否使用GPS
loption.setCoorType("bd09ll");//返回的坐标类型
int span=1000;
loption.setScanSpan(span); //设置扫描间隔
mLocationClient.setLocOption(loption);
然后实现BDLocationListener这个接口,当定位消息返回时回调这个接口里面的方法:
public class MyLocationListener implements BDLocationListener{
@Override
public void onReceiveLocation(BDLocation location) {
// TODO Auto-generated method stub
//获取地址
editAddr.setText(location.getAddrStr());
//获取经度
double longtitude=location.getLongitude();
//获取纬纬
double latitude=location.getLatitude();
//此处实现反地理编码
GeoCoder geoCoder = GeoCoder.newInstance();
geoCoder.setOnGetGeoCodeResultListener(geoListener);
geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(new LatLng(latitude, longtitude)));
System.out.println("describe"+location.getLocationDescribe());
System.out.println("addr:"+location.getAddrStr());
System.out.println("street"+location.getStreet());
System.out.println("longtitude:"+longtitude);
System.out.println("latitude:"+latitude);
//把结果设置到BaiDuMap对象中
baiduMap.setMyLocationEnabled(true);
MyLocationData locData = new MyLocationData.Builder()
.latitude(latitude)
.longitude(longtitude)
.accuracy(location.getRadius())
.build();
baiduMap.setMyLocationData(locData);
//此处设置定位时用的标注
BitmapDescriptor marker = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo);
MyLocationConfiguration config = new MyLocationConfiguration(LocationMode.NORMAL, true, marker);
baiduMap.setMyLocationConfigeration(config);
//此处把地图的焦点拉到定位的位置来
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(ll).zoom(18.0f);
baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
}
这样定位就搞定了,感觉百度的定位还是很准确的,误差不大
三、反地理编码
地理编码是指把地址信息–>经纬度信息,反地理编码就是把经纬度信息–>地址信息。之前在位置定位的时候,我发现在回调带过来的参数中,可以获得经纬度信息,但是不能获得地址信息。于是我在返回定位信息的回调函数中使用了反地理编码。实现如下:
首先创建回调接口OnGetGeoCoderResultListener的实现类:
OnGetGeoCoderResultListener geoListener = new OnGetGeoCoderResultListener() {
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult arg0) {
if(arg0==null){
return;
}
//反地理编码结果回调
editAddr.setText(arg0.getAddress());//把它显示在界面上
}
@Override
public void onGetGeoCodeResult(GeoCodeResult arg0) {
//地理编码结果回调
}
};
然后创建负责正反编码的类,设置回调监听,传入带有经纬度的数据对象开始反地理编码:
//此处实现反地理编码
GeoCoder geoCoder = GeoCoder.newInstance();
geoCoder.setOnGetGeoCodeResultListener(geoListener);
//调用方法开始反地理编码
geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(new LatLng(latitude, longtitude)));
下面贴出整个demo的布局文件和MainActivity.java的代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/bg"
tools:context=".MainActivity" >
<RelativeLayout
android:id="@+id/top"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/title_bg" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="20.0dip"
android:text="@string/beginPoint"
android:textColor="@android:color/white"
android:textSize="20.0sp" />
<Button
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginBottom="5.0dip"
android:layout_marginRight="10.0dip"
android:background="@drawable/btn_selector"
android:padding="5.0dip"
android:text="@string/setting"
android:textColor="@android:color/white" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/bottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/bottom_bg" >
<RelativeLayout
android:id="@+id/row1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5.0dip" >
<TextView
android:id="@+id/beginShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="20.0dip"
android:text="@string/begin"
android:textColor="@android:color/black"
android:textSize="18.0sp" />
<EditText
android:id="@+id/input_address"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="5.0dip"
android:layout_marginRight="15.0dip"
android:layout_toRightOf="@id/beginShow"
android:background="@drawable/input_bg"
android:enabled="false"
android:gravity="center"
android:hint="@string/enterBegin"
android:padding="5.0dip" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/row1" >
<Button
android:id="@+id/local"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/local_selector" />
<Button
android:id="@+id/nextStep"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20.0dip"
android:layout_toRightOf="@id/local"
android:background="@drawable/long_button_selector"
android:text="@string/beginCall"
android:textColor="@android:color/white"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@id/bottom"
android:layout_below="@id/top" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/loadText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="正在进行定位,请稍候……"
android:textSize="25.0sp" />
</RelativeLayout>
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:visibility="gone" />
</FrameLayout>
</RelativeLayout>
package com.example.carcaller;
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.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
TextView loadText;
MapView mapView;
EditText editAddr;
BaiduMap baiduMap;
LocationClient mLocationClient=null;
BDLocationListener myListenler=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
SDKInitializer.initialize(getApplicationContext());
mLocationClient = new LocationClient(getApplicationContext());
initLocation();
setContentView(R.layout.activity_main);
init();
baiduMap= mapView.getMap();
baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
myListenler = new MyLocationListener();
mLocationClient.registerLocationListener(myListenler); //注册监听函数
mLocationClient.start();
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mapView.onResume();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mLocationClient.stop();
baiduMap.setMyLocationEnabled(false);
mapView.onDestroy();
}
//初始化LocationClient的参数配置
void initLocation(){
LocationClientOption loption = new LocationClientOption();
loption.setOpenGps(true);
loption.setCoorType("bd09ll");
int span=1000;
loption.setScanSpan(span);
mLocationClient.setLocOption(loption);
}
//初始化控件
void init(){
loadText=(TextView)findViewById(R.id.loadText);
loadText.setVisibility(View.INVISIBLE); //先隐藏掉,按理说应该定位好之后才隐藏
mapView=(MapView)findViewById(R.id.bmapView);
mapView.setVisibility(View.VISIBLE);
editAddr=(EditText)findViewById(R.id.input_address);
}
public class MyLocationListener implements BDLocationListener{
@Override
public void onReceiveLocation(BDLocation location) {
// TODO Auto-generated method stub
//获取地址
editAddr.setText(location.getAddrStr());
//获取经度
double longtitude=location.getLongitude();
//获取纬纬
double latitude=location.getLatitude();
//此处实现反地理编码
GeoCoder geoCoder = GeoCoder.newInstance();
geoCoder.setOnGetGeoCodeResultListener(geoListener);
//调用方法开始反地理编码
geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(new LatLng(latitude, longtitude)));
System.out.println("describe"+location.getLocationDescribe());
System.out.println("addr:"+location.getAddrStr());
System.out.println("street"+location.getStreet());
System.out.println("longtitude:"+longtitude);
System.out.println("latitude:"+latitude);
//把结果设置到BaiDuMap对象中
baiduMap.setMyLocationEnabled(true);
MyLocationData locData = new MyLocationData.Builder()
.latitude(latitude)
.longitude(longtitude)
.accuracy(location.getRadius())
.build();
baiduMap.setMyLocationData(locData);
//此处设置定位时用的标注
BitmapDescriptor marker = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo);
MyLocationConfiguration config = new MyLocationConfiguration(LocationMode.NORMAL, true, marker);
baiduMap.setMyLocationConfigeration(config);
//此处把地图的焦点拉到定位的位置来
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(ll).zoom(18.0f);
baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
}
OnGetGeoCoderResultListener geoListener = new OnGetGeoCoderResultListener() {
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult arg0) {
if(arg0==null){
return;
}
//反地理编码结果回调
editAddr.setText(arg0.getAddress());
}
@Override
public void onGetGeoCodeResult(GeoCodeResult arg0) {
//地理编码结果回调
}
};
}