百度地图集成概要
第二篇百度定位以及地理位置反编译功能实现
效果图
一篇我们已经集成了这里就不在写了
首先我们 App 继承 Application 用来初始化
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
initMap();
}
private void initMap() {
SDKInitializer.initialize(this);
}
}
然后就是 main 页面的操作了
initView(); 初始化控件
private void initView() {
// 获取地图控件引用
mMapView = (MapView) findViewById(R.id.mv_main_mapView);
mMapView.showZoomControls(false);
View child = mMapView.getChildAt(1); // 删除图标
if (child != null && (child instanceof ImageView || child instanceof ZoomControls)) {
child.setVisibility(View.INVISIBLE);
}
mFindBtn = ((TextView) findViewById(R.id.tv_main_findBtn));
mFindContent = ((EditText) findViewById(R.id.et_main_findContent));
}
initMap(); 初始化地图
private void initMap() {
baiduMap = mMapView.getMap();
baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL); // 普通地图
// 定位
mLocationClient = new LocationClient(getApplicationContext());
mBdLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(mBdLocationListener); // 注册监听者
initLocation(mLocationClient); // client 设置参数
mLocationClient.start(); // 开启定位
// 地理编译 实例化一个地址编码查询对象
mGeoCoder = GeoCoder.newInstance();
}
setListener(); 设置监听
如果项目需求要监听输入文字查询 下面是监听EditText 输入文字监听详情:http://blog.csdn.net/qq_35352552/article/details/56479983
private void setListener() {
mFindBtn.setOnClickListener(this);
baiduMap.setOnMapClickListener(this); // 地图中心点
}
定位的时候用了一个 MyLocationListener 监听类
里面可以获取到很多数据,百度Api里面有详情,但是这里要4个数据就可以了
class MyLocationListener implements BDLocationListener {
private double dLatitude;
private double dLongitude;
private String sCityStr;
private String sAddStr;
// 当开启定位的时候,走这个方法
@Override
public void onReceiveLocation(BDLocation location) {
if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
dLatitude = location.getLatitude(); // 经度
dLongitude = location.getLongitude(); // 维度
sCityStr = location.getCity(); // 城市
sAddStr = location.getAddrStr(); // 地址
}
LatLng latLng = new LatLng(dLatitude, dLongitude);
setMap(latLng); // 设置中心点 设置Marker
Log.e("定位地址 :", sAddStr);
runOnUiThread(new TimerTask() {
@Override
public void run() {
mFindContent.setText(sAddStr);
mFindContent.setSelection(mFindContent.length());
}
});
}
@Override
public void onConnectHotSpotMessage(String s, int i) {
}
}
地图反编译 根据地理位置获取坐标 or 根据坐标获取地理位置
// 地理编译 实例化一个地址编码查询对象
mGeoCoder = GeoCoder.newInstance();
根据坐标获取地理位置的方法:
// 根据坐标获取地址
private void getAddress(final LatLng latLng) {
ReverseGeoCodeOption option = new ReverseGeoCodeOption();
option.location(latLng);
// 发起反地理编码(经纬度 -> 地址信息)
mGeoCoder.reverseGeoCode(option);
mGeoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
@Override
public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
}
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
if (reverseGeoCodeResult == null || reverseGeoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
// 没有找到检索结果
} else {
// 获取反向地理编码结果
Log.e("获取反向地理编码结果 :", reverseGeoCodeResult.getAddress());
mFindContent.setText(reverseGeoCodeResult.getAddress());
}
}
});
}
根据地理位置获取坐标的方法:
// 根据地址获取坐标
private void getLatLng() {
OnGetGeoCoderResultListener listener = new OnGetGeoCoderResultListener() {
@Override
public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
if (geoCodeResult == null || geoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
// 没有检索到结果
} else {
// 获取地理编码结果
Log.e("获取地理编码结果 :", String.valueOf(geoCodeResult.getLocation()));
setMap(geoCodeResult.getLocation());
}
}
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
}
};
// 设置监听
mGeoCoder.setOnGetGeoCodeResultListener(listener);
// 发起编译 (地址信息 --> 经纬度)
String add = mFindContent.getText().toString();
mGeoCoder.geocode(new GeoCodeOption().city(mBdLocationListener.sCityStr).address(add));
}
在获取坐标时
mGeoCoder.geocode(new GeoCodeOption().city(mBdLocationListener.sCityStr).address(add));
获取了定位时的城市,让用户在输入地址查询时是当地的地理位置
归位问题
用户点着点着不知道去哪里也看不到自己的位置了,这时候就要有个归位功能了貌似百度地图自带吧,这里顺便一提
设置监听:
mHoming.setOnClickListener(this); // 归位监听
然后操作: onClick( View v ) 方法里直接重新定位就好了
case R.id.iv_main_homing:
getLocation(); // 重新定位
break;
下面就是整个main里面的代码
基本和重要的地方都加了注释 不同的话可以在下方评论
因这里只是针对地理位置做的定位和反编译,所以兴趣点查询是没有效果的,比如:商店、酒店等
/**
* 作者:CoolTone
* 描述:百度地图
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener, BaiduMap.OnMapClickListener {
private BaiduMap baiduMap;
private ImageView mBack;
private MapView mMapView;
private TextView mFindBtn; // 搜索按钮
private EditText mFindContent; // 所搜索的内容
private ImageView mHoming; // 归位
private LocationClient mLocationClient; // 定位
private MyLocationListener mBdLocationListener; // 定位监听
private GeoCoder mGeoCoder;
private PoiSearch mPoiSearch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_park);
initView();
initMap();
setListener();
}
private void initMap() {
baiduMap = mMapView.getMap();
baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL); // 普通地图
// 定位
getLocation();
// 地理编译 实例化一个地址编码查询对象
mGeoCoder = GeoCoder.newInstance();
// 创建POI检索实例
mPoiSearch = PoiSearch.newInstance();
}
private void setListener() {
mBack.setOnClickListener(this);
mFindBtn.setOnClickListener(this); // 查找
baiduMap.setOnMapClickListener(this); // 地图中心点
mHoming.setOnClickListener(this); // 归位
}
private void initView() {
mBack = (ImageView) findViewById(R.id.iv_park_back);
// 获取地图控件引用
mMapView = (MapView) findViewById(R.id.mv_main_mapView);
mMapView.showZoomControls(false);
View child = mMapView.getChildAt(1); // 删除图标
if (child != null && (child instanceof ImageView || child instanceof ZoomControls)) {
child.setVisibility(View.INVISIBLE);
}
mFindBtn = ((TextView) findViewById(R.id.tv_main_findBtn));
mFindContent = ((EditText) findViewById(R.id.et_main_findContent));
mHoming = ((ImageView) findViewById(R.id.iv_main_homing));
}
@Override
public void onClick(View view) {
if (view != null) {
switch (view.getId()) {
case R.id.iv_park_back:
JumpUtil.newInstance().finishRightTrans(this);
break;
case R.id.tv_main_findBtn:
getLatLng();
break;
case R.id.iv_main_homing: // 归位
getLocation();
break;
}
}
}
// 定位
private void getLocation() {
mLocationClient = new LocationClient(getApplicationContext());
mBdLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(mBdLocationListener); // 注册监听者
initLocation(mLocationClient); // client 设置参数
mLocationClient.start();
}
@Override // 地图单击事件回调
public void onMapClick(LatLng latLng) {
setMap(latLng); // 设置中心点 设置Marker
getAddress(latLng); // 设置地图
}
@Override // 兴趣检索点击回调
public boolean onMapPoiClick(MapPoi mapPoi) {
return false;
}
// 根据坐标获取地址
private void getAddress(final LatLng latLng) {
ReverseGeoCodeOption option = new ReverseGeoCodeOption();
option.location(latLng);
// 发起反地理编码(经纬度 -> 地址信息)
mGeoCoder.reverseGeoCode(option);
mGeoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
@Override
public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
}
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
if (reverseGeoCodeResult == null || reverseGeoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
// 没有找到检索结果
} else {
// 获取反向地理编码结果
Log.e("获取反向地理编码结果 :", reverseGeoCodeResult.getAddress());
mFindContent.setText(StringUtil.getLaterString(reverseGeoCodeResult.getAddress(), "省"));
mFindContent.setSelection(mFindContent.length());
}
}
});
}
// 根据地址获取坐标
private void getLatLng() {
baiduMap.clear();
OnGetGeoCoderResultListener listener = new OnGetGeoCoderResultListener() {
@Override
public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
if (geoCodeResult == null || geoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
// 没有检索到结果
Toast.makeText(ParkActivity.this, "未检测到该位置,请重新输入!", Toast.LENGTH_SHORT).show();
} else {
// 获取地理编码结果
Log.e("获取地理编码结果 :", String.valueOf(geoCodeResult.getLocation()));
setMap(geoCodeResult.getLocation());
}
}
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
}
};
// 设置监听
mGeoCoder.setOnGetGeoCodeResultListener(listener);
// 发起编译 (地址信息 --> 经纬度)
String add = mFindContent.getText().toString();
mGeoCoder.geocode(new GeoCodeOption().city(mBdLocationListener.sCityStr).address(add));
}
// 定位
class MyLocationListener implements BDLocationListener {
private double dLatitude;
private double dLongitude;
private String sCityStr;
private String sAddStr;
// 当开启定位的时候,走这个方法
@Override
public void onReceiveLocation(BDLocation location) {
if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
dLatitude = location.getLatitude(); // 纬度
dLongitude = location.getLongitude(); // 经度
sCityStr = location.getCity(); // 城市
sAddStr = location.getAddrStr(); // 地址
LatLng latLng = new LatLng(dLatitude, dLongitude);
setMap(latLng); // 设置中心点 设置Marker
runOnUiThread(new TimerTask() {
@Override
public void run() {
mFindContent.setText(sAddStr.isEmpty() ? "" : StringUtil.getLaterString(sAddStr, "省")); // 这里自己的工具类
mFindContent.setSelection(mFindContent.length());
if (sAddStr.isEmpty()) {
ToastUtil.showShortToast("抱歉为获取到信息!"); // Toast工具类
}
mLocationClient.stop();
}
});
}
}
}
// 设置中心点 设置Marker
private void setMap(LatLng latLng) {
if (latLng != null) {
if (baiduMap != null) {
baiduMap.clear();
}
MapStatusUpdate update = MapStatusUpdateFactory.newLatLngZoom(latLng, 17);
if (update != null) {
baiduMap.setMapStatus(update); // 设置中心点
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.latlng); // 添加覆盖物
OverlayOptions options = new MarkerOptions().position(latLng).icon(bitmapDescriptor); // icon(BitmapDescriptor) 覆盖物的显示样式
Marker marker = (Marker) baiduMap.addOverlay(options); // 添加到地图中 并获取返回值 Marker具体的覆盖物
}
}
}
// 定位设置
public void initLocation(LocationClient locationClient) {
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); // 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setCoorType("bd09ll"); // 可选,默认gcj02,设置返回的定位结果坐标系
int span = 0;
option.setScanSpan(span); // 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true); // 可选,设置是否需要地址信息,默认不需要
option.setOpenGps(true); // 可选,默认false,设置是否使用gps
option.setLocationNotify(true); // 可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
option.setIsNeedLocationDescribe(true); // 可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationPoiList(true); // 可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
option.setIgnoreKillProcess(false); // 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
option.SetIgnoreCacheException(false); // 可选,默认false,设置是否收集CRASH信息,默认收集
option.setEnableSimulateGps(false); // 可选,默认false,设置是否需要过滤gps仿真结果,默认需要
locationClient.setLocOption(option); // 设置到咱们的客户端
}
@Override
protected void onResume() {
super.onResume();
mMapView.onResume(); // Activity显示MapView也显示
}
@Override
protected void onPause() {
super.onPause();
mMapView.onPause(); // Activity暂停 MapView暂停
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocationClient.stop(); // 停止定位
mGeoCoder.destroy(); // 释放地理编译实例
mPoiSearch.destroy(); // 释放检索实例
mMapView.onDestroy(); // MapView也进行销毁
}
}
xml布局
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.7">
<com.baidu.mapapi.map.MapView
android:id="@+id/mv_main_mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/iv_main_homing"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:layout_marginTop="15dp"
android:src="@drawable/main_anew_location"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ebebeb"
android:padding="5dp">
<LinearLayout
android:id="@+id/ll_main_findLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#efdba7"
android:orientation="horizontal"
android:padding="1dp">
<EditText
android:id="@+id/et_main_findContent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:maxLines="1"
android:padding="10dp"
android:scrollHorizontally="true"
android:scrollbars="horizontal"
android:textColor="#000"
android:textCursorDrawable="@null"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_main_findBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f5f5f5"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="10dp"
android:text="搜索"
android:textColor="#0090ff"
android:textSize="14sp"/>
</LinearLayout>
<ListView
android:id="@+id/lv_main_listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/ll_main_findLayout"
android:scrollbars="none"/>
</RelativeLayout>
</LinearLayout>