欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android 获取经纬度(百度地图)

程序员文章站 2022-07-03 19:47:57
...

今天做原生获取经纬度,本来以为很容易,毕竟之前也做过,我使用的是 LocationManager 和 Location 来获取,但是,最终我怎么也获取不到经纬度,debug才发现最终的 Location 一直是空,我给了权限,动态权限也做了,也到设置里看到给了权限,但还是获取不到,百度大量博客发现可能的问题如下:

1、有些国行手机由于某些XXX的原因把google组件阉割掉了,网络定位默认使用google maps来获取,而GPS获取位置的时间又比较久,所以 Location 一直是空(我在室内测试的,获取定位走的确实是 GPS定位)

2、我也不记得在哪里看到,说安卓因为版本升级,把原生获取定位的给“咔嚓”了(没有证实)

 

 

于是,我只好做百度地图定位,这个也挺简单的,步骤如下:

1、进入百度地图开发平台 > 功能与服务 > 定位 > android定位SDK > 获取**(当然,要先注册账号登录)

上面的操作完成之后,将会看到下图,如图所示:

第一步,输入你要接入的app应用名称(中英文都行)

第二步,选择好应用类型为 android SDK 之后,选择你需要的功能

第三步,输入SHA1,

如何获得SHA1呢?在android studio中,在应用的下面,有一个Terminal ,点击你会发现,它类似于控制台,其实就是android studio的控制台,在里面输入 C: 进入C盘,接着在C盘下输入 cd Users\你的用户名\.android ,在这里有两个 SHA1可以获取:

首先输入命令:keytool -list -v -keystore debug.keystore 下面你会被要求输入**库口令:android  (这个密匙是默认的),于是你就可以获取开发板的 SHA1 

接着输入命令:keytool -list -v -keystore (jks路径)XXX.jks,输入你自定义的**库口令:********(jks打包参考

在第三步中,将开发板和发布版的输入框中分别输入对应的 SHA1,这样无论是在调试中或是打包后,都可以获取到准确的百度定位信息。

第四步,输入应用包名,这个在项目的 AndroidManifest.xml 里面能获取到

最后,点击提交,就能获取到**(AK)了

android 获取经纬度(百度地图)

 

 

2、获取到**之后,就去下载相应的SDK,步骤是:功能与服务 > 定位 > android定位SDK > 相关下载 > 功能开发包-去下载

因为我这里只需要定位功能,所以只选择了基础定位,然后就点击下载-开发包

android 获取经纬度(百度地图)

开发包结构如下

BaiduLBS_Android.jar 放到项目的 libs 下面,

其他的都是 so 文件如果项目集成了其他的第三方插件,如果也有 so 文件的话,可以根据目录把它们放到相应的文件夹中去

如果没有,就把 这些文件夹都放到 libs 文件夹下面,注意:如果项目没有找到相应的 so 文件是获取不到经纬度的,

可以在 build.grade 里面的 android{这里} 里面加入 so 文件的路径,如下:(路径根据自己放置的位置定)

sourceSets.main {
    jniLibs.srcDirs = ['libs']  
}

android 获取经纬度(百度地图)

 

 

3、jar 包和 so 文件放置好好之后,需要在  AndroidManifest.xml  里面注册百度地图的服务

当然,还有一些权限是必须的,多谢  weixin_38438309 的提醒(因为是在我项目中抽取出来的,所以权限可能会有冗余)

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

6.0以上部分权限需要动态获取,可以参考我的另一篇:Android动态申请权限

<!--百度定位-->
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"/>
<meta-data
    android:name="com.baidu.lbsapi.API_KEY"
    android:value="xtH67GRtCWQuclLenU7vo8BLDtsjRbFM" />

注:android:value="xtH67GRtCWQuclLenU7vo8BLDtsjRbFM" 中的 value 值,就是 1、 中的 **(AK)

 

 

4、接下来就是获取定位了,这里需要写三个类来获取经纬度(这个是我看百度给的demo和参考网友博客写的)

第一个是定位工具类  BDLocationUtils 如下:

import android.content.Context;

import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;

/**
 * Created by ccy 2018/7/31.
 */

public class BDLocationUtils {
    public Context context;
    public LocationClient mLocationClient = null;    //LocationClient类是定位SDK的核心类
    public BDLocationListener myListener = new MyLocationListener();

    public BDLocationUtils(Context context){
        this.context = context;
    }

    public void doLocation(){
        //声明LocationClient类
        mLocationClient = new LocationClient(context.getApplicationContext());
        //注册监听函数
        mLocationClient.registerLocationListener( myListener );
        //初始化定位
        initLocation();
    }

    private void initLocation(){
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备

        option.setCoorType("bd09ll");
        //可选,默认gcj02,设置返回的定位结果坐标系

        int span=1000;
        option.setScanSpan(span);
        //可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的

        option.setIsNeedAddress(true);
        //可选,设置是否需要地址信息,默认不需要

        option.setOpenGps(true);
        //可选,默认false,设置是否使用gps

        option.setLocationNotify(true);
        //可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果

        option.setIsNeedLocationDescribe(true);
        //可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京*附近”

        option.setIsNeedLocationPoiList(true);
        //可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到

        option.setIgnoreKillProcess(false);
        //可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死

        option.SetIgnoreCacheException(false);
        //可选,默认false,设置是否收集CRASH信息,默认收集

        option.setEnableSimulateGps(false);
        //可选,默认false,设置是否需要过滤GPS仿真结果,默认需要

        mLocationClient.setLocOption(option);
    }

}

第二个类是获取位置信息  MyLocationListener

import android.util.Log;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.Poi;
import com.example.ccy.cat2.view.Const;

import java.util.List;

/**
 * Created by ccy on 2018/7/31.
 */

public class MyLocationListener implements BDLocationListener {

    @Override
    public void onReceiveLocation(BDLocation location) {
        //获取定位结果
        StringBuffer sb = new StringBuffer(256);

        sb.append("time : ");
        sb.append(location.getTime());    //获取定位时间

        sb.append("\nerror code : ");
        sb.append(location.getLocType());    //获取类型类型

        sb.append("\nlatitude : ");
        sb.append(location.getLatitude()+"");    //获取纬度信息

        sb.append("\nlontitude : ");
        sb.append(location.getLongitude()+"");    //获取经度信息

        sb.append("\nradius : ");
        sb.append(location.getRadius());    //获取定位精准度

        if (location.getLocType() == BDLocation.TypeGpsLocation){

            // GPS定位结果
            sb.append("\nspeed : ");
            sb.append(location.getSpeed());    // 单位:公里每小时

            sb.append("\nsatellite : ");
            sb.append(location.getSatelliteNumber());    //获取卫星数

            sb.append("\nheight : ");
            sb.append(location.getAltitude());    //获取海拔高度信息,单位米

            sb.append("\ndirection : ");
            sb.append(location.getDirection());    //获取方向信息,单位度

            sb.append("\naddr : ");
            sb.append(location.getAddrStr());    //获取地址信息

            sb.append("\ndescribe : ");
            sb.append("gps定位成功");

        } else if (location.getLocType() == BDLocation.TypeNetWorkLocation){

            // 网络定位结果
            sb.append("\naddr : ");
            sb.append(location.getAddrStr());    //获取地址信息

            sb.append("\noperationers : ");
            sb.append(location.getOperators());    //获取运营商信息

            sb.append("\ndescribe : ");
            sb.append("网络定位成功");

        } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {

            // 离线定位结果
            sb.append("\ndescribe : ");
            sb.append("离线定位成功,离线定位结果也是有效的");

        } else if (location.getLocType() == BDLocation.TypeServerError) {

            sb.append("\ndescribe : ");
            sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到aaa@qq.com,会有人追查原因");

        } else if (location.getLocType() == BDLocation.TypeNetWorkException) {

            sb.append("\ndescribe : ");
            sb.append("网络不同导致定位失败,请检查网络是否通畅");

        } else if (location.getLocType() == BDLocation.TypeCriteriaException) {

            sb.append("\ndescribe : ");
            sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");

        }

        sb.append("\nlocationdescribe : ");
        sb.append(location.getLocationDescribe());    //位置语义化信息

        List<Poi> list = location.getPoiList();    // POI数据
        if (list != null) {
            sb.append("\npoilist size = : ");
            sb.append(list.size());
            for (Poi p : list) {
                sb.append("\npoi= : ");
                sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
            }
        }

        Log.i("BaiduLocationApiDem", sb.toString());

        //现在已经定位成功,可以将定位的数据保存下来,Const就是保存数据的类
        Const.LONGITUDE = location.getLongitude();
        Const.LATITUDE = location.getLatitude();
    }
}

第三个类 Const

public class Const {
    public static double LONGITUDE = 0;//经度
    public static double LATITUDE = 0;//纬度
}

这样我们就获得了经纬度,可以调用

 

5、初始化百度定位

以上步骤实现之后,就可以开始定位了,我这里把开启定位的代码写在了启动页,如下:

//获取经纬度
BDLocationUtils bdLocationUtils = new BDLocationUtils(SplashActivity.this);
bdLocationUtils.doLocation();//开启定位
bdLocationUtils.mLocationClient.start();//开始定位

 

如此,获取到定位之后就可以通过:

Const.LONGITUDE    获取经度

Const.LATITUDE         获取维度

 

 

 

注:这里只是单纯的定位,我只拿了经纬度,其实在 MyLocationListener 类中可以看到,可以获得的位置信息还有很多,同时,我这里只集成了定位功能,需要其他功能的,也是一样的集成思路,希望对大家有帮助!