当前位置:   article > 正文

Android进阶:步骤四:Android 接入百度地图API 基础实现_android 连接百度地图build.gradle中配置signingconfig,

android 连接百度地图build.gradle中配置signingconfig,

内容概括:

  1. 注册申请百度地图开发平台账号 这里是地址  如何申请百度地图的账号也有官方文档:在这里
  2. 申请秘钥(AK)、快速获取发布版SHA1和测试版SHA1和包名
  3. (文档里面也有如果创建应用以及申请的教程,但在Android Studio中实现更加简单)
  4. 百度地图的Android Studio的配置
  5. app上实现百度地图的基础功能
  6. app实现切换百度地图的类型(基本和卫星地图)
  7. 实现定位功能
  8. 显示附近商家

一、创建接入百度地图的应用 这里是链接 必须先注册验证成功

1.下面创建应用的界面

2.应用名称随意:我这里填写baiduMap

3.我们选择应用类型为Android SDK 

4.启动服务默认全选就好

5.发布版SHA1和测试版SHA1是什么?怎么简单获取这才是重点

也就是所谓的debug版本和release版本的数字签名,这里不做过多解析,一种加密算法来保证app安全的。

怎么简单获取应用的发布版SHA1和测试版SHA1?

我们打开Android Studio新建一个工程(命名为BaiduMapDemo)

注意红色框框内就是我们这个应用的包名可以修改:我这里写的是

包名:com.demo.baidumap

其他设置默认,创建成功。 

创建好工程后,我们找到Gradle Scripts

1.点击工程下的build.gradle

2.点击屏幕右边隐藏一个侧边区域(Gradle)

3.如果点击后出现的是空白页面点击,蓝色按钮就会出现了

4.那么找到,android包下的signingReport 双击(双击)

双击后再AS的下面Run界面 就会出现

5.我们要的测试版(debug)的SHA1在这里了

这个就是测试版的SHA1:

SHA1: DA:6C:6E:D6:09:98:8B:7D:1C:93:47:03:EC:C2........省略

  1. ----------
  2. Variant: debug
  3. Config: debug
  4. Store: /Users/mac/.android/debug.keystore
  5. Alias: AndroidDebugKey
  6. MD5: 91:83:72:3C:C4:74:5A:8D:99:28:59:BE:90:A0:10:C8
  7. SHA1: DA:6C:6E:D6:09:98:8B:7D:1C:93:47:03:EC:C2........省略
  8. Valid until: 2048年3月1日 星期日
  9. ----------

6、怎么获取发布版的SHA1

1.Build——>Generate Singed APK

2.默认app即可,next

3.点击create new... 

4.第一个是你存放文件的路径,注意: 后缀名是.keystore (因为它要生成一个.keystore的文件)

password 自定 我这里是android 所有都设置成了android 要记下这个密码,下面的填写任意

填写完成点击OK

 

不需要点击next,这时候你存放的路径就有一个.keystore文件了

6.拿到.keystore文件后,打开终端 

复制这行命令:

keytool -list -v -keystore 

空一个格,将你的.keystore文件拉进终端,就会自动识别它所在的路径

enter键,后提示输入输入密钥库口令:  就是上面那个密码 我这里是android

7.输入密码之后,就会出现发布版的SHA1了

这里我们两个SHA1都拿到了

返回百度地图开发平台的应用创建界面

填写相应的SHA1即可,注意包名千万不能写错,SHA1也是,错了就无法用到百度地图sdk了,注意检查上面是否有遗漏步骤

提交后,你就有一个访问应用的AK了,接下来配置有用 

二、百度地图的Android Studio的配置

1.下载百度地图sdk的jar包这里是地址 在产品下载

这里我们选择自定义下载 我们选择了 你可以全部选择,因为接下来的实现效果只用上这么多所有我们选择了3个基础功能

  1. 基础定位
  2. 基础地图
  3. 计算工具

下载开发包和示例代码和类参考,如要进行深入开发,可以看他的demo

下载完成后解压

这里是百度地图官方的Android Studio配置文档

看不懂我的操作的,可以看看官方的配置文档

1.拷贝BaiduLBS_Android.jar(我们所需要的jar包在⁨BaiduLBS_AndroidSDK_Lib⁩ ▸ ⁨libs⁩里面)放到工程app/libs目录下

找不到libs目录?你可能隐藏了双击上面就会显示出来了

2.在src/main/目录下新建jniLibs目录,并把 armeabi目录和x86目录加载到jniLibs目录中

注意:

这里我只放了armeabi和x86的两个平台的包,而官方建议是放所有的平台,也就是4个,但是每一个体积有4M多,放入更多就会使app的体积变大,所以这里放2个,接下来的操作都是文档里不涉及的,是为了解决放2个而导致的问题的

放四个可以参考官方文档:

 

这里是百度地图官方的Android Studio配置文档

 3.新增配置解决2个平台引入新的问题

1.打开module的build.gradle

在defaultConfig模块中添加一个ndk模块 如下(目的保证所有的应用只生成两个平台的,不生成其他平台的so不加会导致奔溃)

  1. compileSdkVersion 27
  2. defaultConfig {
  3. applicationId "com.demo.baidumap"
  4. minSdkVersion 19
  5. targetSdkVersion 27
  6. versionCode 1
  7. versionName "1.0"
  8. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  9. ndk{
  10. abiFilters 'armeabi','x86'
  11. }
  12. }

 2.添加jar文件的依赖 同样是在build.gradle,中

dependencies模块中添加依赖   :implementation files('libs/BaiduLBS_Android.jar') 然后同步一下
  1. dependencies {
  2. implementation fileTree(include: ['*.jar'], dir: 'libs')
  3. implementation 'com.android.support:appcompat-v7:27.1.1'
  4. implementation 'com.android.support.constraint:constraint-layout:1.1.3'
  5. implementation files('libs/BaiduLBS_Android.jar')
  6. testImplementation 'junit:junit:4.12'
  7. androidTestImplementation 'com.android.support.test:runner:1.0.2'
  8. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
  9. }

3.应用混淆

集成地图SDK的应用,在打包混淆的时候,需要注意与地图SDK相关的方法不可被混淆。混淆方法如下:

  1. -keep class com.baidu.** {*;}
  2. -keep class mapsdkvi.com.** {*;}
  3. -dontwarn com.baidu.**

注意:保证百度类不能被混淆,否则会出现网络不可用等运行时异常

复制上面的代码,打开proguard-rules.pro

然后粘贴到末尾,粘贴进去其实并没有生效

接下来,在来到build.gradle里面开启混淆配置

在buildTypes模块中(这是初始的样子)

  1. buildTypes {
  2. release {
  3. minifyEnabled false
  4. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  5. }
  6. }

修改后 开启混淆配置为true

  1. buildTypes {
  2. release {
  3. minifyEnabled true
  4. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  5. }
  6. }

之后还有在build.gradle模块中配置我们刚刚上面的keystore文件

1.将.keystore文件拷贝到module目录下

做如下配置:新建signingConfigs模块,并且在buildTypes中引入

下面的keyAlias和密码是你创建.keystore写的

  1. signingConfigs{
  2. releaseConfig{
  3. storeFile file('baidumap.keystore')
  4. storePassword 'android'
  5. keyAlias 'android'
  6. keyPassword 'android'
  7. }
  8. }
  9. buildTypes {
  10. release {
  11. minifyEnabled true
  12. signingConfig signingConfigs.releaseConfig
  13. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  14. }
  15. }

注意: 此时可以通过点击右边Gradle,双击工程的android目录下signingReport,就获取到release和debug两个的SHA1,检查一下是否和在百度地图开发平台写的一致,我检查了一遍,发现开发版SHA1的不一致,以signingReport出来的为准.(切记,还有包名不要写错)

包名在build的defaultConfig模块也可以看到:applicationId "com.demo.baidumap"

1.开发版SHA1

2.测试版SHA1

3.包名

三者确保没有写错!

三、 app上实现百度地图的基础功能

1.在module的AndroidManifest.xml配置

(1)在application中添加开发密钥(AK)

示例: 

  1. <application>
  2. .....
  3. <meta-data
  4. android:name="com.baidu.lbsapi.API_KEY"
  5. android:value="开发者 key" />
  6. ......
  7. </application>

开发者Key是创建应用完成后的访问应用的AK

(2)添加所需权限

注意: 权限应添加在 appliction 之外,如添加到appliction 内部,会导致无法访问网络,不显示地图。

  1. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  2. <!--获取设备网络状态,禁用后无法获取网络状态-->
  3. <uses-permission android:name="android.permission.INTERNET"/>
  4. <!--网络权限,当禁用后,无法进行检索等相关业务-->
  5. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  6. <!--读取设备硬件信息,统计数据-->
  7. <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
  8. <!--读取系统信息,包含系统版本等信息,用作统计-->
  9. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  10. <!--获取设备的网络状态,鉴权所需网络代理-->
  11. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  12. <!--允许sd卡写权限,需写入地图数据,禁用后无法显示地图-->
  13. <uses-permission android:name="android.permission.WRITE_SETTINGS" />
  14. <!--获取统计数据-->
  15. <uses-permission android:name="android.permission.CAMERA" />
  16. <!--使用步行AR导航,配置Camera权限-->

(3) 在布局xml文件中添加地图控件;

acitivity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context=".MainActivity">
  7. <com.baidu.mapapi.map.MapView
  8. android:id="@+id/id_baidumap"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. android:clickable="true" />
  12. </LinearLayout>

(4)新建一个BaiduMapApplication类继承Application 在oncreate方法中写如下:

  • 注意:在SDK各功能组件使用之前都需要调用
  • SDKInitializer.initialize(getApplicationContext());,因此我们建议该方法放在Application的初始化方法中
  1. public class BaiduMapApplication extends Application {
  2. @Override
  3. public void onCreate() {
  4. super.onCreate();
  5. //在使用SDK各组件之前初始化context信息,传入ApplicationContext
  6. SDKInitializer.initialize(this);
  7. //自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
  8. //包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
  9. SDKInitializer.setCoordType(CoordType.BD09LL);
  10. }
  11. }

然后到AndroidManifest.xml更改我们的Application (别忘了)

       加入: android:name=".BaiduMapApplication"

  1. <application
  2. android:allowBackup="true"
  3. android:icon="@mipmap/ic_launcher"
  4. android:label="@string/app_name"
  5. android:roundIcon="@mipmap/ic_launcher_round"
  6. android:supportsRtl="true"
  7. android:name=".BaiduMapApplication"
  8. android:theme="@style/AppTheme">

(5) 创建地图BaiduMapActivity,管理地图生命周期;

  1. public class BaiduMapActivity extends AppCompatActivity {
  2. private MapView mMapView = null;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. //获取地图控件引用
  8. mMapView = findViewById(R.id.bmapView);
  9. }
  10. @Override
  11. protected void onDestroy() {
  12. super.onDestroy();
  13. //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
  14. mMapView.onDestroy();
  15. }
  16. @Override
  17. protected void onResume() {
  18. super.onResume();
  19. //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
  20. mMapView.onResume();
  21. }
  22. @Override
  23. protected void onPause() {
  24. super.onPause();
  25. //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
  26. mMapView.onPause();
  27. }
  28. }

 完成以上步骤后(打开失败,请仔细检查是否遗漏哪些步骤),运行程序,即可在您的应用中显示地图。 

如果没有遗漏,请检查你的发布版SHA1 和测试版SHA1

(点击Gradle—>android—>双击signingReport在run插入 release和debug的SHA1是否和百度地图创建应用填写的一致)

和包名是否写错

四、调通示例百度Map的Demo

我们下载了BaiduLBS_AndroidSDK_Sample.zip 官方的示例demo

解压后我们把BaiduLoc_AndroidSDK_v7.5_Demo包中Studio版本的BaiduLocDemo的app文件(此时是一个module)导入到我们的工程中

File——>New——>import Module——>选择要导入的module

导入之后,会提示一些错误,比如版本不匹配,或者是compile 要修改成implementation

运行之后你还有可能出现

 Failed to extract native libraries, res=-113的错误

意味着你的模拟器不支持,可以新建一个arm平台的模拟器(不建议非常慢),当然用真机更好

MAC 版android studio 真机调试

注意,版本大于23之后要动态添加权限

五、app实现切换百度地图的类型(基本和卫星地图)

参考百度地图官方切换地图的文档

  1. import android.support.v7.app.AppCompatActivity;
  2. import android.os.Bundle;
  3. import android.view.Menu;
  4. import android.view.MenuItem;
  5. import com.baidu.mapapi.map.BaiduMap;
  6. import com.baidu.mapapi.map.MapView;
  7. public class BaiduMapActivity extends AppCompatActivity {
  8. public static final int ITEM_ID_NORMAL_MAP = 101;
  9. public static final int ITEM_ID_SATELLITE = 102;
  10. public static final int ITEM_ID_TIME = 103;
  11. public static final int ITEM_ID_HOT = 104;
  12. private MapView mMapView = null;
  13. private BaiduMap mBaiduMap;
  14. @Override
  15. protected void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. //获取地图控件引用
  19. mMapView = findViewById(R.id.bmapView);
  20. //拿到map对象
  21. mBaiduMap = mMapView.getMap();
  22. }
  23. /**
  24. * 创建添加菜单
  25. *
  26. * @param menu
  27. * @return
  28. */
  29. @Override
  30. public boolean onCreateOptionsMenu(Menu menu) {
  31. menu.add(Menu.NONE, ITEM_ID_NORMAL_MAP, 0, "切换成普通地图");
  32. menu.add(Menu.NONE, ITEM_ID_SATELLITE, 0, "切换成卫星地图");
  33. menu.add(Menu.NONE, ITEM_ID_TIME, 0, "切换成实时路况图地图");
  34. menu.add(Menu.NONE, ITEM_ID_HOT, 0, "切换成城市热力地图");
  35. return super.onCreateOptionsMenu(menu);
  36. }
  37. /**
  38. * 菜单点击事件
  39. *
  40. * @param item
  41. * @return
  42. */
  43. @Override
  44. public boolean onOptionsItemSelected(MenuItem item) {
  45. switch (item.getItemId()) {
  46. case ITEM_ID_NORMAL_MAP:
  47. mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
  48. mBaiduMap.setTrafficEnabled(false);
  49. mBaiduMap.setBaiduHeatMapEnabled(false);
  50. break;
  51. case ITEM_ID_SATELLITE:
  52. mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
  53. mBaiduMap.setTrafficEnabled(false);
  54. mBaiduMap.setBaiduHeatMapEnabled(false);
  55. break;
  56. case ITEM_ID_TIME:
  57. mBaiduMap.setTrafficEnabled(true);
  58. mBaiduMap.setBaiduHeatMapEnabled(false);
  59. break;
  60. case ITEM_ID_HOT:
  61. mBaiduMap.setBaiduHeatMapEnabled(true);
  62. mBaiduMap.setTrafficEnabled(false);
  63. break;
  64. }
  65. return super.onOptionsItemSelected(item);
  66. }
  67. @Override
  68. protected void onDestroy() {
  69. super.onDestroy();
  70. //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
  71. mMapView.onDestroy();
  72. }
  73. @Override
  74. protected void onResume() {
  75. super.onResume();
  76. //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
  77. mMapView.onResume();
  78. }
  79. @Override
  80. protected void onPause() {
  81. super.onPause();
  82. //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
  83. mMapView.onPause();
  84. }
  85. }

效果: 

六、实现定位功能

参考官方定位文档

1.定位SDK的配置

(1)AndroidManifest.xml中添加定位权限

 

 

1.使用定位SDK,需在Application标签中声明service组件,每个App拥有自己单独的定位service,代码如下:

  1. <service
  2. android:name="com.baidu.location.f"
  3. android:enabled="true" android:process=":remote">
  4. </service>

2. 除添加service组件外,使用定位SDK还需添加如下权限:(注意权限可能和上方之前的有些重复,要去掉)

  1. <!-- 这个权限用于进行网络定位-->
  2. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
  3. <!-- 这个权限用于访问GPS定位-->
  4. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
  5. <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
  6. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
  7. <!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
  8. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
  9. <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
  10. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
  11. <!-- 用于读取手机当前的状态-->
  12. <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
  13. <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
  14. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
  15. <!-- 访问网络,网络定位需要上网-->
  16. <uses-permission android:name="android.permission.INTERNET" />
  17. <!-- SD卡读取权限,用户写入离线定位数据-->
  18. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>

 

2.初始化LocationClient类

  1. import android.content.Context;
  2. import com.baidu.location.BDAbstractLocationListener;
  3. import com.baidu.location.BDLocation;
  4. import com.baidu.location.LocationClient;
  5. import com.baidu.location.LocationClientOption;
  6. /**
  7. * 实现获取定位信息返回给我们的主Activity
  8. */
  9. public class LocationInstance {
  10. /**
  11. * 第一步:初始化LocationClient类
  12. */
  13. public LocationClient mLocationClient;
  14. private MyLocationListener myListener;
  15. //BDAbstractLocationListener为7.2版本新增的Abstract类型的监听接口
  16. //原有BDLocationListener接口暂时同步保留。具体介绍请参考后文第四步的说明
  17. public LocationInstance(Context context, MyLocationListener myListener) {
  18. mLocationClient = new LocationClient(context);
  19. //声明LocationClient类
  20. mLocationClient.registerLocationListener(myListener);
  21. //注册监听函数
  22. /**
  23. * 第二步:配置定位SDK参数
  24. */
  25. LocationClientOption option = new LocationClientOption();
  26. option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
  27. option.setCoorType("bd09ll");
  28. option.setScanSpan(1000);
  29. option.setOpenGps(true);
  30. option.setLocationNotify(true);
  31. option.setIgnoreKillProcess(false);
  32. option.SetIgnoreCacheException(false);
  33. option.setWifiCacheTimeOut(5 * 60 * 1000);
  34. option.setEnableSimulateGps(false);
  35. option.setIsNeedAddress(true);
  36. mLocationClient.setLocOption(option);
  37. }
  38. /**
  39. * 第三步.实现BDAbstractLocationListener接口
  40. */
  41. public static class MyLocationListener extends BDAbstractLocationListener {
  42. @Override
  43. public void onReceiveLocation(BDLocation location) {
  44. //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
  45. //以下只列举部分获取经纬度相关(常用)的结果信息
  46. //更多结果信息获取说明,请参照类参考中BDLocation类中的说明
  47. double latitude = location.getLatitude(); //获取纬度信息
  48. double longitude = location.getLongitude(); //获取经度信息
  49. float radius = location.getRadius(); //获取定位精度,默认值为0.0f
  50. String coorType = location.getCoorType();
  51. //获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
  52. int errorCode = location.getLocType();
  53. //获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
  54. }
  55. }
  56. /**
  57. * 第四步:设置定位的开始和结束的方法
  58. * 1s定位一次非常耗电的操作
  59. */
  60. public void start() {
  61. mLocationClient.start();
  62. }
  63. public void stop() {
  64. mLocationClient.stop();
  65. }
  66. }

3.在主界面中拿到实例 

  1. private LocationInstance mLocationInstance;
  2. private BDLocation lastLocation;//存放最新一次的位置
  3. ....
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. .....
  9. //初始化定位
  10. initLocation();
  11. }
  12. /**
  13. * 初始化定位获取实例的方法
  14. */
  15. private void initLocation() {
  16. mLocationInstance = new LocationInstance(
  17. this,
  18. new LocationInstance.MyLocationListener() {
  19. @Override
  20. public void onReceiveLocation(BDLocation location) {
  21. super.onReceiveLocation(location);
  22. //在这里拿到返回的Location的信息
  23. lastLocation=location;
  24. Log.d("MAP",
  25. location.getAddrStr()+","+"" +
  26. location.getLatitude()+","+
  27. location.getLongitude());
  28. }
  29. });
  30. }
  31. /**
  32. * 开启Location
  33. */
  34. @Override
  35. protected void onStart() {
  36. mLocationInstance.start();
  37. super.onStart();
  38. }
  39. /**
  40. * 关闭Location
  41. */
  42. @Override
  43. protected void onStop() {
  44. mLocationInstance.stop();
  45. super.onStop();
  46. }

 4.动态申请权限

此时运行程序,如果是android6.0 sdk23之前都可以显示定位信息

但是:android6.0之后一些权限需要动态申请才行

所有写一个SplashActivity在没进入主界面的时候来获取权限,如果必要的权限没有获取到

就退出应用,并提升用户还有哪些权限没获取;

下次打开之后,只要获取未获取的权限即可,不用重新再获取一遍

参考这篇文章:android6.0之后动态获取权限的封装

打印结果 

  1. com.demo.baidumap D/MAP: 中国湖北省武汉市******,30.501075,114.402673
  2. com.demo.baidumap D/MAP: 中国湖北省武汉市******,30.501075,114.402673
  3. com.demo.baidumap D/MAP: 中国湖北省武汉市******,30.501075,114.402673

3.将定位功能引入我们界面中去:

 显示自己的定位并绘制一个点标记:官方参考文档

  1. case ITEM_LOCATION:
  2. //当点击我的定位之后会定位到我的位置,并出现一个方向图片
  3. mBaiduMap.clear();//每次点击不清除就会叠加
  4. //定义Maker坐标点(获取经纬度)
  5. LatLng point = new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude());
  6. //构建Marker图标
  7. BitmapDescriptor bitmap = BitmapDescriptorFactory
  8. .fromResource(R.drawable.navi_map_gps_locked);
  9. //构建MarkerOption,用于在地图上添加Marker
  10. OverlayOptions option = new MarkerOptions()
  11. .position(point)
  12. .icon(bitmap);
  13. //在地图上添加Marker,并显示
  14. mBaiduMap.addOverlay(option);
  15. //地图可以移动到中心点过去
  16. mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(point));
  17. break;

改变地图手势的中心点(地图的中心点)

改变地图手势的中心点,即需要改变地图的中心点,手势旋转等操作是以地图中心点 做旋转的。

在上面的代码最后加上:

  1. mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(point));

修改默认的缩放级别,在oncreate中添加

        mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(15f));

 

这是使用Vysor同手机屏幕在电脑上

旋转手机可以使定位箭头随传感器移动而移动:

参考文档:显示定位文档

1.写一个传感器类:SensorInstantce.java

  1. import android.content.Context;
  2. import android.hardware.Sensor;
  3. import android.hardware.SensorEvent;
  4. import android.hardware.SensorEventListener;
  5. import android.hardware.SensorManager;
  6. /**
  7. * 这是传感器的一个类
  8. * 传出x
  9. * 设置位置指针的走向
  10. */
  11. public class SensorInstantce implements SensorEventListener {
  12. private Context mContext;
  13. SensorManager mSensorManager;
  14. public SensorInstantce(Context mContext) {
  15. this.mContext = mContext;
  16. }
  17. public void start() {
  18. //开启传感器服务
  19. mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
  20. if (mSensorManager != null) {//防止有些手机不支持
  21. //拿到sensor对象,方向传感器
  22. Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
  23. if (sensor != null) {
  24. mSensorManager.registerListener((SensorEventListener) this, sensor, SensorManager.SENSOR_DELAY_UI);
  25. }
  26. }
  27. }
  28. public void stop() {
  29. //停止服务
  30. mSensorManager.unregisterListener(this);
  31. }
  32. @Override
  33. public void onSensorChanged(SensorEvent sensorEvent) {
  34. if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) {
  35. float x = sensorEvent.values[SensorManager.DATA_X];
  36. if (mListener != null) {
  37. //把x传出去
  38. mListener.onOrientation(x);
  39. }
  40. }
  41. }
  42. @Override
  43. public void onAccuracyChanged(Sensor sensor, int i) {
  44. }
  45. /***
  46. * OnOrientationChangedListener 利用这个方法来将实时改变的x传出去
  47. */
  48. private OnOrientationChangedListener mListener;
  49. public void setOnOrientationChangedListener(OnOrientationChangedListener listener) {
  50. mListener = listener;
  51. }
  52. public static interface OnOrientationChangedListener {
  53. void onOrientation(float x);
  54. }
  55. }

2.在BaiduMapAcitivity中

(1)添加成员变量

mIsFirstLocation来实现,第一次如果有定位就直接定位到你当前的定位了

  1. private SensorInstantce mSensorInstance;//方向传感器对象
  2. private boolean mIsFirstLocation = true;

(2)oncreate方法中初始化

  1. mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(15f));
  2. //初始化定位
  3. initLocation();
  4. //初始化方向传感器
  5. initSensorInstance();
  6. // 开启定位图层
  7. mBaiduMap.setMyLocationEnabled(true);

这是初始化传感器的方法

  1. /**
  2. * 初始化方向传感器,控制定位指针的随传感器的移动而改变
  3. * 手机移动到哪,图标就指哪个方向
  4. */
  5. private void initSensorInstance() {
  6. mSensorInstance = new SensorInstantce(getApplicationContext());
  7. mSensorInstance.setOnOrientationChangedListener(new SensorInstantce.OnOrientationChangedListener() {
  8. @Override
  9. public void onOrientation(float x) {
  10. //设置定位图标
  11. if (lastLocation == null) {//如果上次没有定位,则不需要改变
  12. return;
  13. }
  14. //实现定位功能
  15. // 构造定位数据
  16. MyLocationData locData = new MyLocationData.Builder()
  17. .accuracy(lastLocation.getRadius())
  18. // 此处设置开发者获取到的方向信息,顺时针0-360
  19. .direction(x).latitude(lastLocation.getLatitude())
  20. .longitude(lastLocation.getLongitude()).build();
  21. // 设置定位数据
  22. mBaiduMap.setMyLocationData(locData);
  23. // 设置自定义定位图层的配置(定位模式,是否允许方向信息,用户自定义定位图标)
  24. // BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
  25. // .fromResource(R.drawable.navi_map_gps_locked);
  26. //不需要自定义图标
  27. MyLocationConfiguration config = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL,
  28. true, null);
  29. mBaiduMap.setMyLocationConfiguration(config);
  30. /**
  31. * 实现以进入地图就定位到我们的位置
  32. */
  33. if (mIsFirstLocation) {
  34. mIsFirstLocation = false;
  35. //拿到位置
  36. LatLng point = new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude());
  37. mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(point));
  38. }
  39. }
  40. });
  41. }

(3)同样要在Acitivity的onstart 和onStop中开启、关闭 

  1. /**
  2. * 开启Location和传感器
  3. */
  4. @Override
  5. protected void onStart() {
  6. mLocationInstance.start();
  7. mSensorInstance.start();
  8. super.onStart();
  9. }
  10. /**
  11. * 关闭Location和传感器
  12. */
  13. @Override
  14. protected void onStop() {
  15. mLocationInstance.stop();
  16. mSensorInstance.stop();
  17. super.onStop();
  18. }

最后如果出现了两个图标

在定位的菜单的点击事件中,除掉一个图标

  1. case ITEM_LOCATION:
  2. 。。。。。
  3. //在地图上添加Marker,并显示
  4. //将下面那一个图标去掉
  5. // mBaiduMap.addOverlay(option);

指针方向随手机移动方向改变

 

 

 七、实现添加附件商家的Marker

百度地图拾取坐标系统的查询

通过拿到的经纬度查询坐标

com.demo.baidumap D/MAP: 中国湖北省武汉市******,30.501075,114.402673(纬度,经度)

longtitute:经度 

Latitude:纬度

 第一:给商家信息做一个分装类

AddressInfo.java
  1. /**
  2. * 附件商家信息的封装
  3. */
  4. public class AddressInfo {
  5. private double latitude;//经度
  6. private double longtitude;//纬度
  7. private int imgId;//图片
  8. private String name;//名称
  9. private String distance;//距离
  10. public AddressInfo() {
  11. }
  12. public AddressInfo(double latitude, double longtitude, int imgId, String name, String distance) {
  13. this.latitude = latitude;
  14. this.longtitude = longtitude;
  15. this.imgId = imgId;
  16. this.name = name;
  17. this.distance = distance;
  18. }
  19. public double getLatitude() {
  20. return latitude;
  21. }
  22. public void setLatitude(double latitude) {
  23. this.latitude = latitude;
  24. }
  25. public double getLongtitude() {
  26. return longtitude;
  27. }
  28. public void setLongtitude(double longtitude) {
  29. this.longtitude = longtitude;
  30. }
  31. public int getImgId() {
  32. return imgId;
  33. }
  34. public void setImgId(int imgId) {
  35. this.imgId = imgId;
  36. }
  37. public String getName() {
  38. return name;
  39. }
  40. public void setName(String name) {
  41. this.name = name;
  42. }
  43. public String getDistance() {
  44. return distance;
  45. }
  46. public void setDistance(String distance) {
  47. this.distance = distance;
  48. }
  49. }

第二:拿到所有商家信息的集合类

  1. /**
  2. * 商家数据类
  3. */
  4. public class AddressInfoLab {
  5. public static List<AddressInfo> generateDatas() {
  6. List<AddressInfo> addressInfos = new ArrayList<>();
  7. // http://api.map.baidu.com/lbsapi/getpoint/index.html
  8. addressInfos.add(new AddressInfo(30.499861, 114.405871, R.drawable.a1, "关山荷兰风情园",
  9. "距离209米"));
  10. addressInfos.add(new AddressInfo(30.50288, 114.402457, R.drawable.a2, "长江职业学院",
  11. "距离897米"));
  12. addressInfos.add(new AddressInfo(30.500655, 114.40005, R.drawable.a3, "天龙公寓",
  13. "距离249米"));
  14. addressInfos.add(new AddressInfo(30.501277, 114.403679, R.drawable.a4, "三福",
  15. "距离679米"));
  16. return addressInfos;
  17. }
  18. }

第三:在主界面中添加附件商家的菜单按钮

  1. case ITEM_SHOWSHOP:
  2. //遍历商家,添加marker
  3. showShops();
  4. break;

具体的商家显示的方法: 

  1. /**
  2. * 显示商家的方法,并添加marker
  3. */
  4. private void showShops() {
  5. mBaiduMap.clear();//每次点击不清除就会叠加
  6. //拿到商家信息
  7. List<AddressInfo> addressInfoList = AddressInfoLab.generateDatas();
  8. for (AddressInfo addressInfo : addressInfoList) {
  9. //定义Maker坐标点(获取经纬度)
  10. LatLng point = new LatLng(addressInfo.getLatitude(), addressInfo.getLongtitude());
  11. //构建Marker图标
  12. BitmapDescriptor bitmap = BitmapDescriptorFactory
  13. .fromResource(R.drawable.maker);
  14. //构建MarkerOption,用于在地图上添加Marker
  15. OverlayOptions option = new MarkerOptions()
  16. .position(point)
  17. .icon(bitmap);
  18. //在地图上添加Marker,并显示
  19. mBaiduMap.addOverlay(option);
  20. }
  21. //如果没有地址直接返回
  22. if (addressInfoList.isEmpty()) {
  23. return;
  24. }
  25. LatLng point = new LatLng(addressInfoList.get(0).getLatitude()
  26. , addressInfoList.get(0).getLongtitude());
  27. //让地图自动移动到第一个商家的位置
  28. mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(point));
  29. }

 

接下来要处理两个事件

  • 1.商家marker的点击事件
  • 2.点击之后显示商家信息

1.点击事件会弹出一个View

所以建一个布局 item_address_info.xml 用来显示点击商家的信息

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content"
  6. android:background="#cc4e5a6b">
  7. <ImageView
  8. android:id="@+id/id_marker_img"
  9. android:layout_width="match_parent"
  10. android:layout_height="180dp"
  11. android:layout_margin="12dp"
  12. android:background="@drawable/bg_img_icon"
  13. android:scaleType="fitXY"
  14. android:src="@drawable/a1" />
  15. <FrameLayout
  16. android:layout_width="match_parent"
  17. android:layout_height="wrap_content"
  18. android:layout_below="@id/id_marker_img"
  19. android:layout_marginBottom="6dp"
  20. android:layout_marginEnd="6dp"
  21. android:layout_marginStart="6dp"
  22. android:background="#4d5c6c">
  23. <TextView
  24. android:id="@+id/id_tx_name"
  25. android:layout_width="wrap_content"
  26. android:layout_height="wrap_content"
  27. android:textSize="14dp"
  28. tools:text="关山风情园" />
  29. <TextView
  30. android:id="@+id/id_tx_distance"
  31. android:layout_width="wrap_content"
  32. android:layout_height="wrap_content"
  33. android:layout_gravity="right"
  34. android:textSize="14dp"
  35. tools:text="关山风情园" />
  36. </FrameLayout>
  37. </RelativeLayout>

2.为了让主界面不那么显得容易,单独建个类来实现View的展示

AddressView.java 商家信息显示的View类

  1. import android.content.Context;
  2. import android.util.AttributeSet;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.widget.ImageView;
  6. import android.widget.RelativeLayout;
  7. import android.widget.TextView;
  8. import com.demo.baidumap.R;
  9. import com.demo.baidumap.bean.AddressInfo;
  10. /**
  11. * marker详情布局
  12. */
  13. public class AddressView extends RelativeLayout {
  14. private ImageView mIvIcon;
  15. private TextView mTvName;
  16. private TextView mTvDistance;
  17. public AddressView(Context context, AttributeSet attrs) {
  18. super(context, attrs);
  19. setVisibility(View.GONE);
  20. LayoutInflater
  21. .from(context)
  22. .inflate(
  23. R.layout.item_address_info,
  24. this);
  25. mIvIcon = findViewById(R.id.id_marker_img);
  26. mTvName = findViewById(R.id.id_tx_name);
  27. mTvDistance = findViewById(R.id.id_tx_distance);
  28. }
  29. //对外接受商家信息
  30. public void setAddressInfo(AddressInfo info) {
  31. mIvIcon.setImageResource(info.getImgId());
  32. mTvName.setText(info.getName());
  33. mTvDistance.setText(info.getDistance());
  34. setVisibility(View.VISIBLE);
  35. }
  36. }

3.在主Activity中

1.声明视图对象

  1. //声明布局对象
  2. private AddressView mAddressView;

2.oncreate中初始化视图 和点击事件

  1. //底部商家详情页
  2. mAddressView = findViewById(R.id.id_address_view);
  3. //初始化点击事件
  4. initEvent();

3.点击事件(点击marker和点击地图)两个事件

  1. public static final String SHOW_INFO = "showInfo";
  2. private void initEvent() {
  3. /**
  4. * 商家marker的点击事件
  5. */
  6. mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
  7. @Override
  8. public boolean onMarkerClick(Marker marker) {
  9. //点击marker之后拿到marker传来的额外信息
  10. Bundle extraInfo = marker.getExtraInfo();
  11. AddressInfo addressInfo = (AddressInfo) extraInfo.getSerializable(SHOW_INFO);
  12. //点击某个marker之后
  13. mAddressView.setAddressInfo(addressInfo);
  14. Log.d("TAG", addressInfo.getName());
  15. //show view
  16. return false;
  17. }
  18. });
  19. /**
  20. * 点击地图的事件(让商家信息消失)
  21. */
  22. mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
  23. @Override
  24. public void onMapClick(LatLng latLng) {
  25. mAddressView.setVisibility(View.GONE);
  26. }
  27. @Override
  28. public boolean onMapPoiClick(MapPoi mapPoi) {
  29. return false;
  30. }
  31. });
  32. }

在显示商家的方法中将商家的位置放进bundle等待点击事件的触发(获取商家额外信息extraInfo)

  1. /**
  2. * 显示商家的方法,并添加marker
  3. */
  4. private void showShops() {
  5. .......
  6. //构建Marker图标
  7. BitmapDescriptor bitmap = BitmapDescriptorFactory
  8. .fromResource(R.drawable.maker);
  9. /**
  10. * 拿到额外信息存到extraInfo里面
  11. */
  12. Bundle bundle = new Bundle();
  13. bundle.putSerializable(SHOW_INFO, addressInfo);
  14. //并传进去
  15. //构建MarkerOption,用于在地图上添加Marker
  16. OverlayOptions option = new MarkerOptions()
  17. .position(point)
  18. .extraInfo(bundle)//将bundle传进去
  19. .icon(bitmap);
  20. ........
  21. }

最后还有在显示商家的方法中GONE掉视图

  1. case ITEM_SHOWSHOP:
  2. //点击mark gone掉
  3. mAddressView.setVisibility(View.GONE);
  4. //遍历商家,添加marker
  5. showShops();
  6. break;

最终效果: 

参考:百度地图开发者文档、和帮助与反馈、还有demo来学习百度地图的SDK 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/297527
推荐阅读
相关标签
  

闽ICP备14008679号