现在还是初学者,做的APP要求使用百度地图,自定义按钮实现重定位功能,但是总是会重定位到几内亚湾,一开始以为是没有经纬度数值的传入,后来才知道,是自己在申请key值时就出错了
发布版和开发版都要申请,而且都要按照规定和要求,每个项目打包时产生的.jks文件对应的是开发板SHA1值,发布版也类似,具体可以自己百度。
设计截图:(最简单的只需要一个button和一个mapview就够了)
以下为实现重定位的代码:
先在activity_Main.xml中设计相应按钮:
<Button
android:id="@+id/btn_location"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="5dp"
android:background="@drawable/location_n" />
再在activity.java中添加click事件:(调用了setMapCenter()方法)
//点击定位按钮重新定位
findViewById(R.id.btn_location).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setMapCenter(MyApplication.getInstance().getLastKnowLocation());
}
});
setMapCenter()实现定位到当前位置
/*
* 设置地图中心点
*/
private void setMapCenter(BDLocation location) {
LatLng cenpt = new LatLng(location.getLatitude(), location.getLongitude());
//定义地图状态
MapStatus mMapStatus = new MapStatus.Builder()
.target(cenpt)
.zoom(15)
.build();
//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
//改变地图状态
mBaiduMap.setMapStatus(mMapStatusUpdate);
}
前提是要实现定位,配置定位参数,自行搜索或者到官网找demo可以找到,下面是实现定位监听的代码,注意MyApplication.getInstance().setLastKnowLocation(location); 这一句
/*
* 实现定位监听 位置一旦有所改变就会调用这个方法, 可以在这个方法里面获取到定位之后获取到的一系列数据
* 添加当前定位marker
*/
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if (location != null) {
MyApplication.getInstance().setLastKnowLocation(location);
if (isFirstLocation) {
isFirstLocation = false;
setMapCenter(location);
}
MyLocationData locData = new MyLocationData.Builder().accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(location.getLatitude()).longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(ll).zoom(18.0f);
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
}
}
}
MyApplication完整代码如下:
public class MyApplication extends Application {
private static MyApplication app = null;
private static Context mContext;
private BDLocation lastKnowLocation;
public static MyApplication getInstance() {
return app;
}
@Override
public void onCreate() {
super.onCreate();
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
SDKInitializer.initialize(this);
//自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
//包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
SDKInitializer.setCoordType(CoordType.GCJ02);
mContext = getApplicationContext();
app = this;
VolleyUtil.initialize(mContext);
}
public static Context getContext() {
return mContext;
}
public BDLocation getLastKnowLocation() {
return lastKnowLocation;
}
public void setLastKnowLocation(BDLocation lastKnowLocation) {
this.lastKnowLocation = lastKnowLocation;
}
}
MainActivity.java完整代码如下:
public class MainActivity extends BaseActivity {
private MapView mMapView;
private TextView textView;
private Button btn_location;
private boolean isFirstLocation = true;
public LocationClient mLocationClient = null;
private BaiduMap mBaiduMap;
private List<Ship> shipList = new ArrayList<>();
boolean isFirstLoc = true; // 是否首次定位
Marker cMarker = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R .layout.activity_main);
mMapView = (MapView) findViewById(R.id.map);
initMap();
initListener();
}
private void initMap() {
mBaiduMap = mMapView.getMap();
mMapView.showScaleControl(false);
mMapView.showZoomControls(false);
mBaiduMap.getUiSettings().setCompassEnabled(false);
//删除百度地图LoGo
mMapView.removeViewAt(1);
checkPermissions();
}
@PermissionSuccess(requestCode = PermissionUtil.REQ_PERMISSIONS)
private void initLocation() {
mBaiduMap.setMyLocationEnabled(true);
mLocationClient = new LocationClient(getApplicationContext());
initLocationOption();
mLocationClient.registerLocationListener(new MyLocationListener());
mLocationClient.start();
mLocationClient.requestLocation();
}
private void initListener() {
//点击定位按钮重新定位
findViewById(R.id.btn_location).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setMapCenter(MyApplication.getInstance().getLastKnowLocation());
}
});
}
//点击地图(空白处)事件
mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
//隐藏baidu_infowindow
baidu_infowindow.setVisibility(View.GONE);
//重置marker
if (cMarker != null ){
cMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.yuchuan));
}
}
@Override
public boolean onMapPoiClick(MapPoi mapPoi) {
return false;
}
});
}
}
/*
* 配置定位参数
*/
private void initLocationOption() {
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setCoorType("gcj02");//可选,默认gcj02,设置返回的定位结果坐标系
option.setScanSpan(1000);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(false);//可选,设置是否需要地址信息,默认不需要
option.setOpenGps(true);//可选,默认false,设置是否使用gps
option.setLocationNotify(false);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
option.setIsNeedLocationDescribe(false);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationPoiList(false);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
option.SetIgnoreCacheException(true);//可选,默认false,设置是否收集CRASH信息,默认收集
option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
mLocationClient.setLocOption(option);
}
/*
* 实现定位监听 位置一旦有所改变就会调用这个方法, 可以在这个方法里面获取到定位之后获取到的一系列数据
* 添加当前定位marker
*/
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if (location != null) {
MyApplication.getInstance().setLastKnowLocation(location);
if (isFirstLocation) {
isFirstLocation = false;
setMapCenter(location);
}
MyLocationData locData = new MyLocationData.Builder().accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(location.getLatitude()).longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(ll).zoom(18.0f);
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
}
}
}
/*
* 设置地图中心点
*/
private void setMapCenter(BDLocation location) {
LatLng cenpt = new LatLng(location.getLatitude(), location.getLongitude());
//定义地图状态
MapStatus mMapStatus = new MapStatus.Builder()
.target(cenpt)
.zoom(15)
.build();
//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
//改变地图状态
mBaiduMap.setMapStatus(mMapStatusUpdate);
}
/*
* 必须要重写
*/
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}
private void checkPermissions() {
PermissionGen.with(MainActivity.this)
.addRequestCode(PermissionUtil.REQ_PERMISSIONS)
.permissions(PermissionUtil.NeedPermissions).request();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
@PermissionFail(requestCode = PermissionUtil.REQ_PERMISSIONS)
private void doSomething() {
}
}
需要注意的是,安卓6.0以上需要动态申请权限,checkPermissions()方法,就是封装好的,或者低版本在manifest.xml文件中使用也是可以的