前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 百度地图SDK 自动定位、标记定位

Android 百度地图SDK 自动定位、标记定位

作者头像
晨曦_LLW
发布2022-05-10 11:09:48
2.2K1
发布2022-05-10 11:09:48
举报
文章被收录于专栏:Android、鸿蒙开发

先看效果图,如果不是你想要的,也就不浪费你时间了,这样对大家都好。

在这里插入图片描述
在这里插入图片描述

Android 百度地图SDK 自动定位、标记定位

一、创建项目引入SDK

如果是你满意的那样,我们就可以开始写了,首先创建一个名为MapDemo的项目。 打开AndroidManifest.xml,复制你的包名

在这里插入图片描述
在这里插入图片描述

然后进入百度地图开放平台,没有注册的小伙伴先注册,已注册的就直接登录,登录进去之后找到控制台→我的应用→创建应用

在这里插入图片描述
在这里插入图片描述

点击之后进入,填写相关资料

在这里插入图片描述
在这里插入图片描述

输入了应用名称、选择了应用类型和启用的服务,输入了包名。还差开发版和发布版的SHA1了

① 获取开发版SHA1 鼠标点击右侧边栏的GradleappTasksandroid→ 双击signingReport

在这里插入图片描述
在这里插入图片描述

当你的AS版本为最新版时,你会发现这里好像有点不一样了,找不到signingReport了,这是AS更新之后默认这个功能关掉了,需要去手动打开它。在设置里面

在这里插入图片描述
在这里插入图片描述

如下图这里默认勾选上了,现在把这根勾选上的去掉,

在这里插入图片描述
在这里插入图片描述

然后Sync,或者点击这个小图标。

在这里插入图片描述
在这里插入图片描述

然后你的项目的右侧边栏就会出现这个熟悉的task了。

粘贴到开发版SHA1的输入框

在这里插入图片描述
在这里插入图片描述

② 获取发布版SHA1 BuildGenerate Signed Bundle or APK

在这里插入图片描述
在这里插入图片描述

选择APK 点击Next

在这里插入图片描述
在这里插入图片描述

这里是没有秘钥的,需要创建一个新的秘钥,点击 Create New…

在这里插入图片描述
在这里插入图片描述

先创建项目的jks文件,点击右侧的文件夹图标,指定对应的文件

在这里插入图片描述
在这里插入图片描述

没有文件夹就先自己创建一个,选择好文件夹之后,输入jks的名字,这里你可以自己取名,然后点击OK

在这里插入图片描述
在这里插入图片描述

输入密码,点击OK

在这里插入图片描述
在这里插入图片描述

别管这个,点击OK

在这里插入图片描述
在这里插入图片描述

勾选上记住密码,然后OK

在这里插入图片描述
在这里插入图片描述

下面还有一个地方要改一下就是APK生成的位置,我不希望它生成在项目里面的默认文件夹,因为找起来不方便,还有一个原因就是clean Project的时候会删除掉你的APK,不管是调试版还是发布版,点击那个小文件夹进行路径修改

在这里插入图片描述
在这里插入图片描述

选中APK,点击创建文件图标,新建一个子文件夹

在这里插入图片描述
在这里插入图片描述

输入文件夹名称,点击OK

在这里插入图片描述
在这里插入图片描述

然后选中这个刚创建的文件夹,点击Finish

在这里插入图片描述
在这里插入图片描述

这个时候,底部会出现一个进度条,表示在生成APK文件,然后底部右侧出现这个这个提示弹窗表示,生成APK成功。

在这里插入图片描述
在这里插入图片描述

然后找到这个APK的所在目录

在这里插入图片描述
在这里插入图片描述

这个就是你生成的APK所在地址。以你自己前面设置的路径为准。接下来进入Android Studio的Terminal工具输入如下图所示的命令和jks存放路径。

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
//如果你前面的步骤和我一模一样的话,这里你就可以复制粘贴,不一样的话就修改jks的路径就可以了
keytool -list -v -keystore D:\APK\mapdemo.jks

输入这行命令之后回车会让你输入密码,就是之前创建秘钥的的那个密码,输入的过程中你是看不见密码的,光标也不会移动,不过不用担心,输入无误后回车就可以了

在这里插入图片描述
在这里插入图片描述

找到这个SHA1,然后复制,粘贴到发布版SHA1的输入框里

在这里插入图片描述
在这里插入图片描述

那么这个页面的所需资料就填写完毕,点击提交

在这里插入图片描述
在这里插入图片描述

应用创建成功

在这里插入图片描述
在这里插入图片描述

点击开发文档选择Android地图SDK

在这里插入图片描述
在这里插入图片描述

点击自定义下载

在这里插入图片描述
在这里插入图片描述

选择Jar

在这里插入图片描述
在这里插入图片描述

下载开发包

在这里插入图片描述
在这里插入图片描述

下载后解压文件夹,进入libs里面

在这里插入图片描述
在这里插入图片描述

复制这些文件,然后进入你的Android Studio,切换到Project模式,找到libs,然后粘贴

在这里插入图片描述
在这里插入图片描述

打开build.gradle,复制如下代码进去,注意放置的位置是在android闭包中,然后Sync,保存修改配置文件

代码语言:javascript
复制
	sourceSets{
        main{
            jniLibs.srcDir 'libs'
            jni.srcDirs = []    //disable automatic ndk-build
        }
    }
在这里插入图片描述
在这里插入图片描述

配置成功,jar包就是可以展开的

在这里插入图片描述
在这里插入图片描述

然后进入开放平台,复制你的应用AK

在这里插入图片描述
在这里插入图片描述

二、显示地图

切换到Android文件模式,打开AndroidManifest.xml,在application标签下写入

代码语言:javascript
复制
		<!--百度定位AK-->
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="WpVg5eIh4kYWPHtPjG3arHIf6bGEn49s" />

注意这个value里面的值是你自己的应用的,你用我的是没用的。 然后放入定位服务

代码语言:javascript
复制
		<!--百度定位服务  这个服务也是放在application标签下的-->
        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" />
在这里插入图片描述
在这里插入图片描述

最后放入权限

代码语言:javascript
复制
	<!--以下权限与application标签是平级的-->
    <!-- 这个权限用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!-- 这个权限用于访问GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- 访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET" />

创建一个MapApplication类,继承Application,在onCreate方法中完成SDK的初始化,代码如下:

代码语言:javascript
复制
package com.llw.mapdemo;

import android.app.Application;

import com.baidu.mapapi.CoordType;
import com.baidu.mapapi.SDKInitializer;

public class MapApplication 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

在这里插入图片描述
在这里插入图片描述

现在修改activity_main.xml文件

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />

</LinearLayout>

然后在MainActivity中

在这里插入图片描述
在这里插入图片描述

这个时候你的地图就会显示出来,可能会比较慢,这个与网络有关。运行起来

在这里插入图片描述
在这里插入图片描述

SDK默认指定了北京的坐标,那么这肯定不是你想要的,所以要定位到实际的位置才行。

三、定位当前所在位置

修改一下styles.xml文件

在这里插入图片描述
在这里插入图片描述

进入MainActivity

在这里插入图片描述
在这里插入图片描述

initLocation方法代码如下:

代码语言:javascript
复制
	/**
     * 定位初始化
     */
    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();
    }

MyLocationListener 代码如下:

代码语言:javascript
复制
	/**
     * 定位SDK监听函数
     */
    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()));
            }

        }
    }

最后改动一下onDestroy

代码语言:javascript
复制
	@Override
    protected void onDestroy() {
        super.onDestroy();
        // 退出时销毁定位
        mLocClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        // 在activity执行onDestroy时必须调用mMapView.onDestroy()
        mMapView.onDestroy();
    }

运行效果如下图

在这里插入图片描述
在这里插入图片描述

现在就已经在地图上定位到当前所在位置了。

当然光是定位到自己的位置也是不够的,我还希望点击地图的时候能够定位过去,

四、标点定位、回到原位

先修改MainActivity.xml文件, 根布局改为RelativeLayout,然后增加一个ImageButton

在这里插入图片描述
在这里插入图片描述

里面用到的图标

在这里插入图片描述
在这里插入图片描述

写完之后你会发现你的你少了一个resetLocation方法,进入MainActivity,写下如下方法:

代码语言:javascript
复制
	/**
     * 点切换到其他标点位置时,重置定位显示,点击之后回到自动定位
     *
     * @param view
     */
    public void resetLocation(View view) {
        
    }

然后

在这里插入图片描述
在这里插入图片描述

既然要定位到其他地方肯定是要先点击地图的,所以写一个地图的点击方法

代码语言:javascript
复制
	/**
     * 地图点击
     */
    private void mapOnClick() {
        // 设置marker图标
        bitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon_marka);
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            @Override
            public void onMapPoiClick(MapPoi mapPoi) {

            }

            //此方法就是点击地图监听
            @Override
            public void onMapClick(LatLng latLng) {
                //获取经纬度
                markerLatitude = latLng.latitude;
                markerLongitude = latLng.longitude;
                //先清除图层
                mBaiduMap.clear();
                // 定义Maker坐标点
                LatLng point = new LatLng(markerLatitude, markerLongitude);
                // 构建MarkerOption,用于在地图上添加Marker
                MarkerOptions options = new MarkerOptions().position(point)
                        .icon(bitmap);
                // 在地图上添加Marker,并显示
                //mBaiduMap.addOverlay(options);
                marker = (Marker) mBaiduMap.addOverlay(options);
                Bundle bundle = new Bundle();
                bundle.putSerializable("info", "纬度:" + markerLatitude + "   经度:" + markerLongitude);
                marker.setExtraInfo(bundle);//将bundle值传入marker中,给baiduMap设置监听时可以得到它

                //点击地图之后重新定位
                initLocation();
            }
        });

    }

这里面有一个图标icon_marka

在这里插入图片描述
在这里插入图片描述

上面的代码很明确了吧,当点击地图时添加一个标点,同时绑定它的经纬度,当点击标点的时候就会显示出经纬度。当标点在地图上绘制之后,就重新定位。再来看看这个方法吧

代码语言:javascript
复制
	/**
     * 定位初始化
     */
    public void initLocation() {

        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        // 定位初始化
        mLocClient = new LocationClient(this);
        MyLocationListener myListener = new MyLocationListener();
        mLocClient.registerLocationListener(myListener);
        LocationClientOption option = new LocationClientOption();

        option.setOpenGps(true);// 打开gps
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);// 设置高精度定位
        option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
        option.setScanSpan(0);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
        option.setOpenGps(true);//可选,默认false,设置是否使用gps
        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选,默认false,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认杀死
        option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
        option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
        mLocClient.setLocOption(option);
        mLocClient.start();//开始定位
    }

这里面我增加了一些属性,重点不是这个,是定位后的监听。

代码语言:javascript
复制
	/**
     * 定位SDK监听函数
     */
    public class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            // MapView 销毁后不在处理新接收的位置
            if (location == null || mMapView == null) {
                return;
            }
            double resultLatitude;
            double resultLongitude;

            if (markerLatitude == 0) {//自动定位
                resultLatitude = location.getLatitude();
                resultLongitude = location.getLongitude();
                ibLocation.setVisibility(View.GONE);
            } else {//标点定位
                resultLatitude = markerLatitude;
                resultLongitude = markerLongitude;
                ibLocation.setVisibility(View.VISIBLE);
            }

            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())// 设置定位数据的精度信息,单位:米
                    .direction(location.getDirection()) // 此处设置开发者获取到的方向信息,顺时针0-360
                    .latitude(resultLatitude)
                    .longitude(resultLongitude)
                    .build();

            mBaiduMap.setMyLocationData(locData);// 设置定位数据, 只有先允许定位图层后设置数据才会生效
            LatLng latLng = new LatLng(resultLatitude, resultLongitude);
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(latLng).zoom(20.0f);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

        }

    }

在一开始我生命两个double类型的变量,分别是标点的经度和纬度,当一开始进来的时候判断是否等于0,如果是,则使用自动的定位,如果不是,则使用标点的定位,我在点击地图时,将获得的位置坐标赋值给了这两个变量,所以当你点击其他地方的时候就会马上定位过去。这时候就要显示出重置定位这个图标,在手机屏幕的左下角。 然后在这个定位图标的点击时写入如下代碼。

代码语言:javascript
复制
	/**
     * 点切换到其他标点位置时,重置定位显示,点击之后回到自动定位
     *
     * @param view
     */
    public void resetLocation(View view) {
        markerLatitude = 0;
        initLocation();
        marker.remove();//清除标点
    }

最后还差一个标点的点击,那就重新写一个initView,把相关的findById都写到这里面吧。

代码语言:javascript
复制
	private void initView() {
        // 地图初始化
        mMapView = (MapView) findViewById(R.id.bmapView);
        //回到当前定位
        ibLocation = (ImageButton) findViewById(R.id.ib_location);
        mMapView.showScaleControl(false);  // 设置比例尺是否可见(true 可见/false不可见)
        //mMapView.showZoomControls(false);  // 设置缩放控件是否可见(true 可见/false不可见)
        mMapView.removeViewAt(1);// 删除百度地图Logo

        mBaiduMap = mMapView.getMap();

        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                final String info = (String) marker.getExtraInfo().get("info");
                Toast.makeText(MainActivity.this, info, Toast.LENGTH_SHORT).show();
                return true;

            }
        });
    }

然后你再看这个onCreate方法

在这里插入图片描述
在这里插入图片描述

只要调用就可以了。运行效果如下:

在这里插入图片描述
在这里插入图片描述

五、源码

  做一个Demo,自然要把源码放上去,先看效果图,合适再运行源码,OK,最后不理解代码再来看博客的讲述,你就知道是怎么回事了,至于自己写的原因是在于官方的文档我觉得并不详细,而我可以把每一步写进来,这才是我写作的初衷。

源码地址:MapDemo,还是我懂你吧!

六、疑问解决

如果你运行源码之后发现定位到的地方并不是当前的位置,甚至偏了十万八千里,那么你就要检查一下是不是鉴权信息错误了,这其实是你当前相关的开发版SHA1和当前平台上的不一致造成了,比如我现在在家里的电脑克隆源码下来,然后运行在自己的手机上,发现定位在海里,等我放大之后发现在几内亚湾,都到了非洲的海域了。

你可以看一下你运行时你的Run里面有没有如下这样的异常信息。

在这里插入图片描述
在这里插入图片描述

如果有的话,那么现在就来解决一下。首先重新获取一下当前的开发版SHA1,如果你不记得了,往上滑动再看看就好。

在这里插入图片描述
在这里插入图片描述

然后你再看看平台上的开发版SHA1

在这里插入图片描述
在这里插入图片描述

你都不用全部看完,只要有一个鉴权失败,铁定就不行,那么只要改变一下平台上的开发版SHA1就可以了,复制刚才控制台中的SHA1,然后粘贴到平台的这个输入框中,然后点击提交,之前你再运行刚才的项目。

然后你会发现,还是在几内亚湾,不过你看Run中的报错已经没有了,不过还有一个错误,我之前写这个文章的时候这个地图的SDK还不需要我写数据,所以我就没有动态请求权限,而现在又要了,很明显是百度的人动了手脚。

在这里插入图片描述
在这里插入图片描述

那么下面就来动态请求一下写入文件的权限。

在app的build.gralde中的android闭包下增加如下jdk1.8的使用代码:

代码语言:javascript
复制
	compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

然后在dependencies闭包下增加如下依赖

代码语言:javascript
复制
	//动态权限请求
    implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
    implementation "io.reactivex.rxjava2:rxjava:2.0.0"

然后点击Sync同步一下,然后进入到MainActivity,新增检查权限的方法

代码语言:javascript
复制
	/**
     * 检查版本
     */
    private void checkVersion() {
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            RxPermissions rxPermissions = new RxPermissions(this);
            rxPermissions.request(Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.READ_PHONE_STATE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .subscribe(granted -> {
                        if (granted) {//申请成功
                            //发起连续定位请求
                            initLocation();// 定位初始化
                        } else {//申请失败
                            Toast.makeText(MainActivity.this,"权限未开启",Toast.LENGTH_SHORT).show();
                        }
                    });
        }else {
            initLocation();// 定位初始化
        }
    }

Android6.0以下和动态权限请求允许之后调用initLocation()进行定位,然后在onCreate中调用

在这里插入图片描述
在这里插入图片描述

最后在AndroidManifest.xml中增加一个静态权限。

代码语言:javascript
复制
	<!--读取手机状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

然后运行,发现就可以了,终于不是在几内亚湾了。

在这里插入图片描述
在这里插入图片描述

下载源码和APK,通过CSDN资源下载,我设置的0积分。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Android 百度地图SDK 自动定位、标记定位
  • 一、创建项目引入SDK
  • 二、显示地图
  • 三、定位当前所在位置
  • 四、标点定位、回到原位
  • 五、源码
  • 六、疑问解决
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档