1.实验环境:
Windows系统,Android Studio
2.界面分析:
2.1 地图显示
默认是显示中国北京的天安门广场那里的地图。
2.2 显示定位
注意:因为Android Studio中的手机为虚拟机,所以在定位的时候会定位到谷歌,而不是我们当前所在的地方。
3.功能实现:(本功能参考博客:Android 百度地图SDK 自动定位、标记定位_晨曦-CSDN博客)
3.1. 地图显示:
3.1.1.配置百度地图的AK码
在这里我们需要在我们的AndroidStudio中获取我们的SHA1码以及PackageName:
然后就可以生成我们的AK码:
3.1.2.下载百度地图的SDK
下载解压后的libs文件夹如下:
可以看到有5个文件夹以及一个名为 BaiduLBS_Android.jar的jar包
3.1.3.在Android Studio中配置AK码:
还需要配置百度的定位服务。
3.1.4.在Android Studio中添加相应jar包:
3.1.5.用于显示地图的组件设置:
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
我们只需要在activity_main.xml文件添加该组件即可。
3.1.6.创建一个MapApplication类,继承Application,在onCreate方法中完成SDK的初始化
public class MapApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
SDKInitializer.initialize(this);
SDKInitializer.setCoordType(CoordType.BD09LL);
}
}
我们在上述AK码的配置中已经在AndroidManifest.xml中声明该application了。
3.1.7.在MainActivity中配置相关方法:
public class MainActivity extends Activity {
private MapView mMapView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.bmapView);
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
}
然后就可以运行程序查看显示的地图了。
3.2. 显示定位:
3.2.1.用于视图初始化的initView方法:
private void initView() {
// 地图初始化
mMapView = (MapView) findViewById(R.id.bmapView);
//回到当前定位
ibLocation = (ImageButton) findViewById(R.id.ib_location);
mMapView.showScaleControl(true); // 设置比例尺是否可见(true 可见/false不可见)
//mMapView.showZoomControls(false); // 设置缩放控件是否可见(true 可见/false不可见)
mMapView.removeViewAt(1);// 删除百度地图Logo
mBaiduMap = mMapView.getMap();
mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
final String info = (String) marker.getExtraInfo().get("info");
Toast.makeText(MainActivity.this, info, Toast.LENGTH_SHORT).show();
return true;
}
});
}
3.2.2.修改onDestroy方法:
@Override
protected void onDestroy() {
super.onDestroy();
// 退出时销毁定位
mLocClient.stop();
// 关闭定位图层
mBaiduMap.setMyLocationEnabled(false);
// 在activity执行onDestroy时必须调用mMapView.onDestroy()
mMapView.onDestroy();
}
3.2.3.定义一个用于实现回到原地的imageButton:
<ImageButton
android:visibility="gone"
android:id="@+id/ib_location"
android:layout_margin="8dp"
android:onClick="resetLocation"
android:layout_alignParentBottom="true"
android:background="@drawable/icon_location"
android:layout_width="40dp"
android:layout_height="40dp"/>
当我们点击该button后,蓝点会回到我们当前所在的地点。
3.2.4.定义点击地图的方法:
private void mapOnClick() {
// 设置marker图标
bitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon_marka);
mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
@Override
public void onMapPoiClick(MapPoi mapPoi) {
}
//此方法就是点击地图监听
@Override
public void onMapClick(LatLng latLng) {
//获取经纬度
markerLatitude = latLng.latitude;
markerLongitude = latLng.longitude;
//先清除图层
mBaiduMap.clear();
// 定义Maker坐标点
LatLng point = new LatLng(markerLatitude, markerLongitude);
// 构建MarkerOption,用于在地图上添加Marker
MarkerOptions options = new MarkerOptions().position(point)
.icon(bitmap);
// 在地图上添加Marker,并显示
//mBaiduMap.addOverlay(options);
marker = (Marker) mBaiduMap.addOverlay(options);
Bundle bundle = new Bundle();
bundle.putSerializable("info", "纬度:" + markerLatitude + " 经度:" + markerLongitude);
marker.setExtraInfo(bundle);//将bundle值传入marker中,给baiduMap设置监听时可以得到它
//点击地图之后重新定位
initLocation();
}
});
}
在该方法中我们设置了蓝点的移动以及标点的出现,我们点击标点即可获得当前点的经纬度。
3.2.5.定位初始化initLocation方法:
public void initLocation() {
// 开启定位图层
mBaiduMap.setMyLocationEnabled(true);
// 定位初始化
mLocClient = new LocationClient(this);
MyLocationListener myListener = new MyLocationListener();
mLocClient.registerLocationListener(myListener);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);// 打开gps
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);// 设置高精度定位
option.setCoorType("bd09ll");
option.setScanSpan(0);
option.setIsNeedAddress(true);
option.setOpenGps(true);
option.setIsNeedLocationDescribe(true);
option.setIsNeedLocationPoiList(true);
option.setIgnoreKillProcess(false);
option.SetIgnoreCacheException(false);
option.setEnableSimulateGps(false);
mLocClient.setLocOption(option);
mLocClient.start();//开始定位
}
这是初始化蓝点位置的方法。
3.2.6.定义监听函数MyLocationListener:
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
Toast.makeText(MainActivity.this,location.getAddrStr(),Toast.LENGTH_SHORT).show();
// MapView 销毁后不在处理新接收的位置
if (location == null || mMapView == null) {
return;
}
double resultLatitude;
double resultLongitude;
if (markerLatitude == 0) {//自动定位
resultLatitude = location.getLatitude();
resultLongitude = location.getLongitude();
ibLocation.setVisibility(View.GONE);
} else {//标点定位
resultLatitude = markerLatitude;
resultLongitude = markerLongitude;
ibLocation.setVisibility(View.VISIBLE);
}
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())// 设置定位数据的精度信息,单位:米
.direction(location.getDirection()) // 此处设置开发者获取到的方向信息,顺时针0-360
.latitude(resultLatitude)
.longitude(resultLongitude)
.build();
mBaiduMap.setMyLocationData(locData);// 设置定位数据, 只有先允许定位图层后设置数据才会生效
LatLng latLng = new LatLng(resultLatitude, resultLongitude);
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(latLng).zoom(20.0f);
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
}
在该方法中我们首先会判断当前蓝点经纬度是否为null,不是则使用默认的值,然后每次点击地图后,就会重新更新其经纬度。而如果当前位置并未我们的原位置,左下角的定位到原位的imageButton就会显示出来,接下来就是定义该imageButton点击后实现的逻辑。
3.2.7.imageButton的点击方法:
public void resetLocation(View view) {
markerLatitude = 0;
initLocation();
marker.remove();//清除标点
}
我们点击该按钮后,就会重新回到原点,并且该左下角的按钮消失。
3.2.8.在oncreate方法中使用这些方法:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();//视图初始化
checkVersion();//检查版本
mapOnClick();//地图点击
}
3.2.9.运行程序后会发现定位在几内亚湾附近,需要进行以下修改:
在app的build.gralde中的android闭包下增加如下jdk1.8的使用代码
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
然后在dependencies闭包下增加如下依赖
//动态权限请求
implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation "io.reactivex.rxjava2:rxjava:2.0.0"
新增检查权限的方法:
private void checkVersion() {
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions.request(Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(granted -> {
if (granted) {//申请成功
//发起连续定位请求
initLocation();// 定位初始化
} else {//申请失败
Toast.makeText(MainActivity.this,"权限未开启",Toast.LENGTH_SHORT).show();
}
});
}else {
initLocation();// 定位初始化
}
}
然后我们就发现可以成功定位了,虽然是在谷歌。。。但是定位也是成功了,毕竟这是因为虚拟机的原因。
4.实验小结:
本次实验在老师的带领下完成了地图显示的功能,然后通过网上搜索以及查看官方文档完成了显示当前定位的功能。本次实验学习了百度地图在安卓中的部分功能的使用,而且加强了自己独自学习以及完成指定任务的能力。