Baidu地图安卓SDK使用
soapgu opened this issue · 0 comments
-
配置及初始化
- 注册百度账号
- 申请api key
这里申请需要填写SHA1 和 package name。
和语音识别api认证差不多,需要用到
gradle signingReport 命令
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 访问网络,进行地图相关业务数据请求,包括地图数据,路线规划,POI检索等 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 读取外置存储。如果开发者使用了so动态加载功能并且把so文件放在了外置存储区域,则需要申请该权限,否则不需要 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 写外置存储。如果开发者使用了离线地图,并且数据写在外置存储区域,则需要申请该权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MapforBaidu"
tools:targetApi="31">
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="ykHFKEKef1oLj79NDWMR4NqDykVvL7CW" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>
需要设置四个权限、自定义application以及meta-data的API_KEY
- 设置sdk依赖
implementation 'com.baidu.lbsyun:BaiduMapSDK_Map:7.5.4'
选用最简单的。
- 自定义Application实现
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
SDKInitializer.initialize(this);
SDKInitializer.setCoordType(CoordType.BD09LL);
}
}
按照文档直接抄代码需要初始化SDK
然鹅报错了
Caused by: com.baidu.mapapi.common.BaiduMapSDKException: not agree privacyMode, please invoke SDKInitializer.setAgreePrivacy(Context, boolean) function
at com.baidu.mapsdkplatform.comapi.a.d(BMapManagerInternal.java:37)
at com.baidu.mapsdkplatform.comapi.Initializer.initialize(Initializer.java:33)
at com.baidu.mapapi.SDKInitializer.initialize(SDKInitializer.java:1)
at com.demo.mapforbaidu.MyApplication.onCreate(MyApplication.java:12)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202)
- SDK注意事项
这里设置privacyMode是必填项。
抄代码还不行,SDKInitializer.setAgreePrivacy(this, false);
还是报错!一定要设SDKInitializer.setAgreePrivacy(this, true);
百度怎么想的,既然设置false不能用sdk,为啥开放出来设置一次?
-
添加地图控件
<?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/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"/>
</androidx.constraintlayout.widget.ConstraintLayout>
public class MainActivity extends AppCompatActivity {
private MapView mMapView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.mMapView = findViewById(R.id.mapView);
}
@Override
protected void onResume() {
super.onResume();
this.mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
this.mMapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
this.mMapView.onDestroy();
}
}
-
初始位置以及地图类型设置
看前面截图总感觉哪里怪怪的!
对哦,我也不在皇城脚下啊。
SDK一般常规操作是定位到当前位置
不过我觉得这样代价其实蛮高的,需要获取定位权限。如果我只是要看某一个位置地图哪?
首先通过拾取坐标工具,找出要显示位置的经度纬度
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.mMapView = findViewById(R.id.mapView);
LatLng centerPoint = new LatLng(31.170474,121.401209);
MapStatus mapStatus = new MapStatus.Builder().target(centerPoint).zoom(18).build();
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
BaiduMap map = this.mMapView.getMap();
map.setMapStatus(mapStatusUpdate);
map.setMapType(BaiduMap.MAP_TYPE_NORMAL);
}
利用API的BaiduMap对象来设置,还是比较简单的
现在顺眼多了吧
-
绘制点标记
//定义Maker坐标点
LatLng point = new LatLng(31.170503, 121.402091);
//构建Marker图标
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.mark);
//构建MarkerOption,用于在地图上添加Marker
OverlayOptions option = new MarkerOptions()
.position(point)
.icon(bitmap);
//在地图上添加Marker,并显示
this.mMapView.getMap().addOverlay(option);
图标可以完全自定义
比较遗憾的是MarkerOption的title方法已经deprecated了,调用了也没作用
可替代方案是再在个TextOptions
OverlayOptions mTextOptions = new TextOptions()
.text("我的起点") //文字内容
//.bgColor(0xAAFFFF00) //背景色
.fontSize(24) //字号
.fontColor(0xFF000000) //文字颜色
.position(point);
this.mMapView.getMap().addOverlay(mTextOptions);
-
一些高级功能的尝试
-
鸟瞰图
其实地图是支持3D的
把MapStatus的overlook这个api设一个俯视角度就行 -
小小挫折
一开始我想要拿到所在坐标的3D建筑模型,百度其实基本为所有的建筑物都建模了,有现成的东西为啥还要自己画
结果发现API缺依赖,加了 implementation 'com.baidu.lbsyun:BaiduMapSDK_Search:7.5.4'
首先这个api不能在onCreate调用。
后面发现账号权限不够
- 绘制3D棱柱
好了只能“手工”画了
private void renderPrism(){
List locations = new ArrayList<>();
locations.add(new LatLng(31.170561,121.40181));
locations.add(new LatLng(31.170642,121.402066));
locations.add(new LatLng(31.170437,121.402156));
locations.add(new LatLng(31.170352,121.401905));
PrismOptions prismOptions = new PrismOptions();
prismOptions.setHeight(20);
prismOptions.setPoints(locations);
prismOptions.setSideFaceColor(0xAAFF0000);
prismOptions.setTopFaceColor(0xAA00FF00);
// 控制3D建筑物单体动画
prismOptions.setAnimation(true);
// 设置3D建筑物开始显示层级
prismOptions.setShowLevel(4);
mMapView.getMap().addOverlay(prismOptions);
}
-
3DMarker
看起来差不多了,但是标记跑到下面去了
为了和3D棱柱配合使用只能使用3DMarker了
Projection projection = this.mMapView.getMap().getProjection();
LatLng point = new LatLng(31.170503, 121.402091);
Point srcPoint = projection.geoPoint3toScreenLocation(point, 20);
LatLng latLng = projection.fromScreenLocation(srcPoint);
加上投影转换,这些差不多了吧。结果projection是空的,应该是地图还没加载的关系。需要调整下调用时机
一开始在setOnMapDrawFrameCallback的回调后使用发觉没用,最后还是用OnMapLoadedCallback
map.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
render3DMarkPoint();
}
});
-
参考链接
完结撒花