[Android Studio]百度地图定位 显示当前地理位置
运行结果如下,我的定位用圆形小蓝点表示,图中不作展示
百度地图开发者注册
注册百度账号并登录。
获取密钥
查看开发文档,有详细说明。
进入此页面进行相关配置http://lbsyun.baidu.com/apiconsole/key#/home。
- 点击“创建应用”;
- “应用类型”选择“Android SDK”;
- 填写“应用名称”;
- 获取SHA1(我的发布版SHA1和开发版SHA1相同)并填写;
打开Android Studio
-> Build -> Generate Signed Bundle or APK
-> 找到自己计算机中的debug.keystore位置
-> 填写密码
Finish后:
-> View -> Tool Windows -> Terminal
-> 如下指令操作
//打开计算机中Android Studio\jre\bin目录
cd D:\Program Files\Android\Android Studio\jre\bin
keytool -list -v -keystore C:\Users\xxx\.android\debug.keystore
- 填写“PackageName”;
- 提交;
- 可见此应用的密钥:“访问应用(AK)”。
Android 地图 SDK 下载配置
查看 开发文档。
勾选并下载SDK:
Android Studio配置及地图显示
此部分具体操作主要参考官方文档说明(包括开发文档中的 “Android 地图 SDK” 和 “Android 定位 SDK”)。我一开始运行AS项目有报错,说libs出了问题,就是因为和开发文档上的操作方法有不同。
Android Studio配置 要做的工作有添加SDK、配置build.gradle(Module: app)、添加AK、添加定位权限。
<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!-- 访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
地图显示需自定义类完成对SDK的初始化,在地图Activity中管理MapView的生命周期。
完成之后即可编写主要程序代码。
编写布局activity_main.xml
使用了FrameLayout(帧布局),此布局方法中所有的控件默认放置于布局的左上角。因此显示位置的LinearLayout(TextView)叠加在MapView之上。注意FrameLayout中控件代码编写的顺序,避免出现控件覆盖。
android:background="#CC000000"
颜色#CC000000 前两位代表透明度值。
编写MainActivity.java
- 申请权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
requestLocation();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Without Location Permissions!", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(this, "Got Location Permissions!", Toast.LENGTH_SHORT).show();
requestLocation();
}
break;
}
}
- 获取定位
LocationMode:- High_Accuracy: 高精度定位模式,GPS与网络综合定位,优先返回最高精度的定位结果;
- Battery_Saving: 低功耗定位模式,仅使用网络定位(WiFi和基站定位);
- Device_Sensors: 仅使用设备(GPS)定位。
private void requestLocation() {
initLocation();
mLocationClient.start();
}
private void initLocation() {
MyLocationListener myLocationListener = new MyLocationListener();
mLocationClient = new LocationClient(getApplicationContext());
mLocationClient.registerLocationListener(myLocationListener);
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.bmapView);
baiduMap = mapView.getMap();
baiduMap.setMyLocationEnabled(true);
txtPosition = findViewById(R.id.txtPosition);
LocationClientOption option = new LocationClientOption();
option.setScanSpan(1000);
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
// option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
// option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);
option.setIsNeedAddress(true);
mLocationClient.setLocOption(option);
}
private class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
StringBuffer currentPosition = new StringBuffer();
currentPosition.append("Longitude: ").append(bdLocation.getLongitude()).append("\n");
currentPosition.append("Latitude: ").append(bdLocation.getLatitude()).append("\n");
currentPosition.append("Address: ").append(bdLocation.getAddrStr());
String s = "" + bdLocation.getLatitude();
txtPosition.setText(currentPosition);
if (bdLocation.getLocType() == BDLocation.TypeGpsLocation || bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) {
navigateTo(bdLocation);
}
}
}
private void navigateTo(BDLocation bdLocation) {
if (isFirstLocation) {
LatLng latLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(latLng);
MyLocationData locationData = new MyLocationData.Builder().latitude(latLng.latitude).longitude(latLng.longitude).build();
baiduMap.animateMapStatus(update);
baiduMap.setMyLocationData(locationData); // 地图上显示定位点
isFirstLocation = false;
}
}
我这得加上locationData的定义再给baiduMap setMyLocationData才能显示出地图上定位点(小蓝点)。
代码参考 教程。
如果是在虚拟机上运行的话,经纬度只会显示4.9E-324,而且地图显示不是北京就是非洲几内亚湾(或许听说其他同学还出现了其他地理位置情况?)。因为虚拟机没有GPS。换作手机就可以了。
参考AS连接手机设备的方法 [Android Studio]AS连接手机 安装应用。
源码已上传至 GitHub。