一、功能需求
根据官方文档,开发百度地图定位APP,显示出当前位置坐标。
二、实现过程
1. 实验环境
Android Studio3.1
2.获取百度开发者KEY
https://lbsyun.baidu.com/index.php?title=androidsdk
(1)创建用户
这一部分内容和每一个app注册流程一样,不再赘述。
(2)获取密钥
创建新的应用,并选择自己所需要的应用类型
(3)SHA1和PackageName的获取
打开AndroidStudio的终端terminal,并在命令行操作
先进入C盘中自己用户下,在输入.android命令后再keytool -list -v -keystore debug.keystore
在build.gradle中可以查看包名
(4)创建好Key后进行下载
下载文件并解压在D盘
复制libs下的文件至项目下的libs
在libs目录下,选中BaiduLbs_Android.jar文件右键,选择Add As Library
查看build.gradle的dependencies块中生成了工程所依赖的jar文件的对应说明
(5)配置AndroidManifest.xml文件
<application>
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="开发者 key" />
</application>
在application外部添加权限声明:
3. 页面设计
在布局文件activity_main.xml中添加地图容器
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />
但我想实现下面有地图,上面有经纬度以及地址的展现,添加代码后为:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="0dp"
android:layout_height="0dp"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#e0000000"
android:orientation="vertical"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="20dp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="纬度:"
android:textColor="#ffffff"
android:textSize="15dp" />
<TextView
android:id="@+id/tv_Lat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#ffffff"
android:textSize="15dp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="经度:"
android:textColor="#ffffff"
android:textSize="15dp" />
<TextView
android:id="@+id/tv_Lon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#ffffff"
android:textSize="15dp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="12dp"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="地址:"
android:textColor="#ffffff"
android:textSize="15dp" />
<TextView
android:id="@+id/tv_Add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#ffffff"
android:textSize="15dp" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
4. Java代码实现
(1)MainActivity的编写
public class MainActivity extends AppCompatActivity {
MapView mMapView = null;
BaiduMap mBaiduMap ;
LocationClient mLocationClient;
TextView tv_Lat; //纬度
TextView tv_Lon; //经度
TextView tv_Add; //地址
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_Add = findViewById(R.id.tv_Add);
tv_Lon = findViewById(R.id.tv_Lon);
tv_Lat = findViewById(R.id.tv_Lat);
mMapView = findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
//设置地图类型
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
//开启地图的定位图层
mBaiduMap.setMyLocationEnabled(true);
//从系统获取定位权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}else {
//设置客户端
mLocationClient = new LocationClient(this);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);
option.setCoorType("bd09ll"); // 设置坐标类型
option.setIsNeedAddress(true); //设置是否需要地址信息,默认不需要
mLocationClient.setLocOption(option);
//设置监听器
MylocationListener myLocationListener = new MylocationListener();
mLocationClient.registerLocationListener(myLocationListener);
//开启地图定位图层
mLocationClient.start();
MyLocationConfiguration.LocationMode mCurrentMode = MyLocationConfiguration.LocationMode.FOLLOWING;
MyLocationConfiguration mLocationConfiguration = new MyLocationConfiguration(mCurrentMode,true,null,0xAAFFFF88,0xAA00FF00);
mBaiduMap.setMyLocationConfiguration(mLocationConfiguration);
}
}
private class MylocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
if (bdLocation == null || mMapView == null){
return;
}
MyLocationData locationData = new MyLocationData.Builder()
.accuracy(bdLocation.getRadius())
.direction(bdLocation.getDirection())
.latitude(bdLocation.getLatitude())
.longitude(bdLocation.getLatitude())
.build();
mBaiduMap.setMyLocationData(locationData);
//输出经纬度和地点
tv_Add.setText(bdLocation.getAddrStr());
tv_Lat.setText(bdLocation.getLatitude()+" ");
tv_Lon.setText(bdLocation.getLongitude()+" ");
LatLng ll = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(update);
}
}
}
添加Map的生命周期
@Override
protected void onResume() {
mMapView.onResume();
super.onResume();
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocationClient.stop();
mBaiduMap.setMyLocationEnabled(false);
mMapView.onDestroy();
}
}
创建建一个自定义的Application,在其onCreate方法中完成SDK的初始化
public class DemoApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
SDKInitializer.initialize(this);
//自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
//包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
SDKInitializer.setCoordType(CoordType.BD09LL);
}
}
运行后发现APP根本打不开,而DemoApplication是灰色的,所以我怀疑是这里出现的问题。查看AndroidStudio下的Run也发现错误:you have not supplyed the global app context info from SDKInitializer.initialize(Context) function,明白了是自己在AndroidManifest.xml文件中未声明该Application
解决方式:
三、运行界面展示
发现只能显示北京天安门,这里需要添加定位权限
<!-- 这个权限用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 这个权限用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
声明定位的服务
<service android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote"/>
再次运行,显示虚拟机的位置
因为这是虚拟机的位置,所以要得到自身定位,还需要我们将apk文件下载至手机后打开。
将文件下载至自己手机后打开
再次查看位置