- 移动开发技术 作业4:LBS
- 实验需求
- 一、百度地图API准备
- 1.开发包下载
- 2.申请应用的Key
- 二、配置编码阶段
- 1. 清单文件配置
- 2.activitiy_main.xml代码及分析
- 3.MainActivity.java代码及分析
- 三、运行效果
- 虚拟定位解决办法
- 手机真实定位效果
- 四、Gitee仓库地址
- gitee
实验需求
1、根据官方文档,开发百度地图定位APP,显示出当前位置坐标。
参考网址:https://lbsyun.baidu.com/index.php?title=android-locsdk
一、百度地图API准备 1.开发包下载
- 访问http://lbsyun.baidu.com,依次选择:开发文档->Android 地图SDK->产品下载->自定义下载,勾选百度定位包(至少选择基础定位和基础地图)后下载。
- 下载后解压文件,将BaiduLBS_Android.jar包放进项目的libs文件夹里,并将右键jar文件,选择“Add As Library”
新建jniLibs文件夹,将解压后的其他文件移动到此文件夹
- 访问http://lbsyun.baidu.com,依次选择:开发文档->Android 地图SDK->获取密钥
进入控制台->创建应用,这里根据自己的需求填写选择
使用 keytool(jdk自带工具)获取
- 运行进入控制台Windows:运行 -> 输入cmd -> 确定。Mac:直接打开 终端。
- 在控制台内,定位到.android文件夹,输入cd .android
如下截图为windows效果。
这样就获取到了所需要的SHA1 - 在控制台填写自己的SHA1和包名即可提交(包名可在build.gradle里面查看)
提交后,生成应用的AK,查看应用Key并复制,以供清单文件配置应用Key用。
二、配置编码阶段 1. 清单文件配置
- 在清单文件里,在Activity组件注册的代码后,添加注册远程服务和配置应用Key的代码:
- 在模块的清单文件里,增加如下权限:
2.activitiy_main.xml代码及分析
- 界面布局使用帧布局,包含有重叠效果的地图和位置文本,activity_main.xml的完整代码如下:
重点代码分析:MapView地图容器:MapView是View的一个子类,用于在Android View中放置地图。MapView的使用方法与Android提供的其他View一样。
3.MainActivity.java代码及分析
- 界面程序MainActivity.java代码如下:
package com.example.my_lbs;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
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.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
public class MainActivity extends AppCompatActivity {
LocationClient mLocationClient; //定位客户端
MapView mapView; //Android Widget地图控件
BaiduMap baiduMap;
boolean isFirstLocate = true;
TextView tv_Lat; //纬度
TextView tv_Lon; //经度
TextView tv_Add; //地址
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//如果没有定位权限,动态请求用户允许使用该权限
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, "没有定位权限!", Toast.LENGTH_LONG).show();
finish();
} else {
requestLocation();
}
}
}
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);//开启地图的定位图层
tv_Lat = findViewById(R.id.tv_Lat);
tv_Lon = findViewById(R.id.tv_Lon);
tv_Add = findViewById(R.id.tv_Add);
LocationClientOption option = new LocationClientOption();
//设置扫描时间间隔
option.setScanSpan(1000);
//设置定位模式,三选一
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
//设置需要地址信息
option.setIsNeedAddress(true);
//保存定位参数
mLocationClient.setLocOption(option);
}
//内部类,百度位置监听器
private class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
tv_Lat.setText(bdLocation.getLatitude()+"");
tv_Lon.setText(bdLocation.getLongitude()+"");
tv_Add.setText(bdLocation.getAddrStr());
if(bdLocation.getLocType()==BDLocation.TypeGpsLocation || bdLocation.getLocType()==BDLocation.TypeNetWorkLocation){
navigateTo(bdLocation);
}
}
}
private void navigateTo(BDLocation bdLocation) {
if(isFirstLocate){
LatLng ll = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
MyLocationData locationData = new MyLocationData.Builder().latitude(ll.latitude).longitude(ll.longitude).build();
baiduMap.animateMapStatus(update);
baiduMap.setMyLocationData(locationData);
isFirstLocate = false;
}
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocationClient.stop();
mapView.onDestroy();
}
}
主要代码分析
- 开启地图的定位图层(前几次实验没有加这行,导致不能出现定位的小蓝点==,找了好久)
mBaiduMap.setMyLocationEnabled(true);
- 实现BDAbstractLocationListener接口
Android定位SDK自V7.2版本起,对外提供了Abstract类型的监听接口BDAbstractLocationListener,用于实现定位监听。原有BDLocationListener暂时保留,推荐开发者升级到Abstract类型的新监听接口使用,该接口会异步获取定位结果,官方文档中给的核心代码如下:
public class MyLocationListener extends BDAbstractLocationListener{
@Override
public void onReceiveLocation(BDLocation location){
//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取经纬度相关(常用)的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明
double latitude = location.getLatitude(); //获取纬度信息
double longitude = location.getLongitude(); //获取经度信息
float radius = location.getRadius(); //获取定位精度,默认值为0.0f
String coorType = location.getCoorType();
//获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
int errorCode = location.getLocType();
//获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
}
}
三、运行效果
提示:我用的是AS里面的虚拟设备,所以导致定位不是我现在的定位,后面给出解决办法。
虚拟定位解决办法
Build APK安装包,locate该安装包并发送到手机



