20212324 2023-2024-2 《移动平台开发与实践》第5次作业
问题1:在实现标记和删除覆盖物部分功能时,需要我们自己导入素材xxx.png到/res/drawable目录。在控制台创建应用,需要发布版的sha1,因此需要在as里创建签名文件,并用keytool来获取sha1。问题3解决方案:多次尝试仍无解,猜测本虚拟机API版本过低(24),不能具备相应正确定位功能:(问题2解决方案:通过逐次实验(猜测及二分法),我终于将标点标到了操场上!问题2:在实现自动
·
20212324 2023-2024-2 《移动平台开发与实践》第5次作业
1.实验内容和目的
- 设计并开发一个地图应用系统。
- 该实验需提前申请百度API Key,调用接口实现百度地图的定位功能、地图添加覆盖物和显示文本信息。
1.1项目功能
- 本次实验我通过调用百度地图APK,顺利完成了项目。项目功能如下:
- 地图显示的是卫星图
- 可以实现对本机的定位
- 程序自动在北京电子科技学院地址处标了点,妈妈再也不用担心我找不到学校地址了
- 可以允许用户在地图上标点(覆盖物)及删除,过程中会弹出提示
2.实验过程
2.1在百度申请密钥
-
在控制台创建应用,需要发布版的sha1,因此需要在as里创建签名文件,并用keytool来获取sha1
-
创建release版本的签名文件:
- 先去Build菜单下生成一个正式的.jks签名文件.Build>Generate signed APK
-
进行release版本的签名验证:
- file>project structure>signing
- 此时在builde.gradle文件中就多了对正式签名文件的配置引用: 注意要在buildTypes中添加对正式签名配置的引用.
-
3.获取sha1:
- keytool -list -v -keystore 你的签名文件
-
4.申请key
2.2配置开发环境
2.2.1在项目中集成BaiduMap SDK
- 百度官方文档
- 下载开发包,将其拷贝至工程
2.2.2添加jar、so文件
- 在src/main/目录下新建jniLibs目录(如果的项目中已经包含该目录不用重复创建),在下载的开发包中拷贝项目中需要的CPU架构对应的so文件文件夹到jniLibs目录,如图:
- 在libs目录下,选中每一个jar文件(此处只有一个BaiduLbs_Android.jar)右键,选择Add As Library…
- 此时会发现在app目录的build.gradle的dependencies块中生成了工程所依赖的jar文件的对应说明,如下所示:
- 最后如下图所示:
3.编写Kotlin代码
3.1配置AndroidManifest.xml文件
-
在中加入如下代码配置开发密钥(AK),或者通过SDKInitializer.setApiKey(“ak”)动态设置AK
-
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="6lmYlAJwcQUNz2gGwem8VXpq0T7lDGxG" />
-
-
在外部添加如下权限声明,权限对应的代码均如下
-
<!--百度定位所需要权限,前面是LOCATE权限组的2个危险权限--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <!--百度定位所需要的普通权限--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <!--因为程序要与百度云服务交互--> <uses-permission android:name="android.permission.INTERNET"/>
-
3.1 MainActivity.kt
-
package com.example.mapp; import android.content.DialogInterface; import android.os.Bundle; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.CoordType; import com.baidu.mapapi.SDKInitializer; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BaiduMapOptions; import com.baidu.mapapi.map.BitmapDescriptor; import com.baidu.mapapi.map.BitmapDescriptorFactory; import com.baidu.mapapi.map.MapStatus; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.Marker; import com.baidu.mapapi.map.MarkerOptions; import com.baidu.mapapi.map.MyLocationData; import com.baidu.mapapi.map.OverlayOptions; import com.baidu.mapapi.map.SupportMapFragment; import com.baidu.mapapi.model.LatLng; /* 百度地图应用,包含定位信息和地图显示 一般需要打开定位服务,选择高精度定位模式,有网络连接 需要在清单文件里使用百度云服务(参见清单文件service标签) 需要创建应用(模块)的Key,并写入清单文件(参见清单文件meta标签) */ public class MainActivity extends AppCompatActivity { public MapView mMapView = null; public LocationClient mLocClient; public BaiduMap mBaiduMap; boolean isFirstLoc = true; protected void onCreate(Bundle savedInstanceState) { //定位监视器 super.onCreate(savedInstanceState); SDKInitializer.initialize(getApplicationContext());//一定要先初始化,再加载布局 SDKInitializer.setCoordType(CoordType.BD09LL); //经纬坐标,使用中国国测局的。 setContentView(R.layout.activity_main); //加载布局 //获取地图控件引用 mMapView = (MapView) findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); initLocation(); // 创建一个标记点 LatLng latLng = new LatLng(39.844, 116.2855); // 北京电子科技学院的经纬度 // 创建一个MarkerOptions对象,用于设置标记点的属性 MarkerOptions markerOptions = new MarkerOptions() .position(latLng) // 设置标记点的坐标 .icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_lala)) // 设置标记点的图标 .anchor(0.5f, 0.5f) // 设置标记点图标的锚点 .rotate(30); // 设置标记点图标的旋转角度 // 将MarkerOptions对象添加到地图上,并获取标记对象 com.baidu.mapapi.map.Marker marker = (com.baidu.mapapi.map.Marker) mBaiduMap.addOverlay(markerOptions); //地图长按事件监听接口 BaiduMap.OnMapLongClickListener longClickListener = new BaiduMap.OnMapLongClickListener() { //point 长按的地理坐标 @Override public void onMapLongClick(LatLng point) { //弹出确认框 AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this) .setTitle("创建标点") .setMessage("是否创建标点?") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //构建Marker图标 BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.icon_lala); //构建MarkerOption,用于在地图上添加Marker OverlayOptions overlayOptions = new MarkerOptions() .position(point) .icon(bitmapDescriptor); //在地图上添加Marker,并显示 mBaiduMap.addOverlay(overlayOptions); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { return; } }).create(); alertDialog.show(); } }; //设置地图长按事件监听 mBaiduMap.setOnMapLongClickListener(longClickListener); mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() { //marker被点击时回调的方法 //若响应点击事件,返回true,否则返回false //默认返回false @Override public boolean onMarkerClick(Marker marker) { //弹出确认框 AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this) .setTitle("创建标点") .setMessage("是否删除标点?") .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { marker.remove(); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { return; } }).create(); alertDialog.show(); return true; } }); } @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(); if(null!= mMapView){ mMapView.onDestroy(); } } public void initLocation(){ // 开启定位图层 mBaiduMap.setMyLocationEnabled(true); // 定位初始化 mLocClient = new LocationClient(this); MyLocationListener myListener = new MyLocationListener(); mLocClient.registerLocationListener(myListener); LocationClientOption option = new LocationClientOption(); // 打开gps option.setOpenGps(true); // 设置坐标类型 option.setCoorType("bd09ll"); option.setScanSpan(1000); mLocClient.setLocOption(option); mLocClient.start(); } public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { // MapView 销毁后不在处理新接收的位置 if (location == null || mMapView == null) { return; } MyLocationData locData = new MyLocationData.Builder() .accuracy(location.getRadius())// 设置定位数据的精度信息,单位:米 .direction(location.getDirection()) // 此处设置开发者获取到的方向信息,顺时针0-360 .latitude(location.getLatitude()) .longitude(location.getLongitude()) .build(); // 设置定位数据, 只有先允许定位图层后设置数据才会生效 mBaiduMap.setMyLocationData(locData); if (isFirstLoc) { isFirstLoc = false; LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); MapStatus.Builder builder = new MapStatus.Builder(); builder.target(latLng).zoom(20.0f); mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); } } } }
activity_main.xml布局代码
-
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" /> </LinearLayout> </FrameLayout>
DemoApplication
- 在SDK各功能组件使用之前都需要调用“SDKInitializer.initialize(getApplicationContext())”,因此我们直接在应用创建时初始化SDK引用的Context为全局变量。
import android.app.Application;
import com.baidu.mapapi.CoordType;
import com.baidu.mapapi.SDKInitializer;
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);
}
}
- 在AndroidManifest.xml文件中声明该Application
(四)运行与调试
- 运行程序,给予程序定位权限:
- 演示视频如下
2024-05-17 23-19-03
3.学习中遇到的困难及解决
-
问题1:在实现标记和删除覆盖物部分功能时,需要我们自己导入素材xxx.png到/res/drawable目录
问题1解决方案:一开始我想到找一个电脑上应用的图标,比较干净没有背景:
谁曾想不支持.ico,最后到网上截了个图,调整大小后作为素材导入
-
问题2:在实现自动在北京电子科技学院上标点功能时,搜索到的经纬度和地图上略有差异
问题2解决方案:通过逐次实验(猜测及二分法),我终于将标点标到了操场上!附前后经纬度差异
-
问题3:对本机的定位定到了非洲黄金海岸甚至是大西洋上
问题3解决方案:多次尝试仍无解,猜测本虚拟机API版本过低(24),不能具备相应正确定位功能:(
4.学习感悟、思考
- 本次实验通过实践操作,结合之前实践,我更加掌握了百度地图SDK及其内部的各种模块各种类的定义及使用方法,并成功实现了定位、地图添加覆盖物和显示信息。
- 实验中还是遇到了很多问题,但好在有前人栽树,代码逻辑的实现等都比较顺利。此外,官方的参考文档让我受益颇丰,不会对着偌大的接口无能为力!
参考资料
更多推荐
已为社区贡献2条内容
所有评论(0)