百度地图的用法总结1——配置,简单定位,反编译获取地区

注册百度开发者账户、获取密钥

  • 注册百度账号
    要使用百度定位,首先我们要申请一个百度账号,官网申请入口,登录注册好的账号
  • 获取密钥
    1.登录后将进入API控制台,网址在这,如下图:

在这里插入图片描述

2.点击“创建应用”开始申请开发密钥,如下图:
在这里插入图片描述
3.填写应用名称,注意应用类型选择“Android SDK”、正确填写SHA1 和 程序包名
在这里插入图片描述
应用名称:
    自己随便写
包名:
    就是你应用程序的包名,打开应用程序的AndroidManifest.xml文件,package后面就是包名
在这里插入图片描述
开发版SHA1:
        打开Android Studio任意一个项目,点击右侧工具栏Gradle->项目名->app->Tasks->android,双击signingReport
在这里插入图片描述

在下方就会出现SHA1,把它复制到开发版SHA1。

发布版SHA1:
    如果你的应用只是用于平时的程序练习,简单起见,可以直接在这里填写上面的开发版SHA1,之后提交,就可以得到对应的AK了
在这里插入图片描述

下载百度地图SDK

点击开发文档->Android地图SDk->产品下载->自定义下载
在这里插入图片描述

要实现什么功能就选择下载什么,我这里只是用于获取经纬度,所以只用选择基础定位下载即可。
下载后解析点开他有两个文件,第一个文件是我们一会要用的。
在这里插入图片描述

Android Stdio的配置

  • 点开刚才的libs文件,里面有如下文件

在这里插入图片描述

  • 把他们全放在libs目录下
    在这里插入图片描述
  • 配置build.gradle文件
    在build.gradle配置我们的libs路径(sourceSets和defaultConfig同级)
sourceSets{
        main{
                 jniLibs.srcDir 'libs'
         }
}   	

注意这边的libs是和src同级,才会生效,不同目录结构按以下修改

jniLibs.srcDirs =['src/main/libs']
  • 添加依赖
 api files('libs/BaiduLBS_Android.jar')

添加后完整的build.gradle如下

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.example.gps"
        minSdkVersion 16
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets{
        main{
            jniLibs.srcDir 'libs'
            jni.srcDirs = []    //disable automatic ndk-build
        }
    }

}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    api files('libs/BaiduLBS_Android.jar')
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}
  • AndoirdMainifest.xml中的配置
    在AndoirdMainifest.xml的application底下添加
<!-- 声明service组件 -->
<application
	<service
    	android:name="com.baidu.location.f"
    	android:enabled="true"
    	android:process=":remote">
    </service>

	<!-- AK鉴权 -->
	<!-- meta-data需要写在application中 -->
	<meta-data
    	android:name="com.baidu.lbsapi.API_KEY"
    	android:value="申请的密钥AK" /> 
</application>

加入所需的权限

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

使用

获取经纬度信息

  1. 初始化LocationClient类

        主线程中声明LocationClient类对象,该对象初始化需传入Context类型参数。

 	private LocationClient locationClient;
 	//这个类的具体实现在下面
    private MyLocationListener myLocationListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建LocationClient对象
        locationClient = new LocationClient(getApplicationContext());
        //注册监听函数
        locationClient.registerLocationListener(myLocationListener);
      
   }
  1. 配置定位SDK参数
            通过参数配置,可选择定位模式、可设定返回经纬度坐标类型、可设定是单次定位还是连续定位
 LocationClientOption option = new LocationClientOption();
 option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,设置定位模式,默认高精度
        //LocationMode.Hight_Accuracy:高精度;
        //LocationMode. Battery_Saving:低功耗;
        //LocationMode. Device_Sensors:仅使用设备;

        option.setCoorType("bd09ll");
        //可选,设置返回经纬度坐标类型,默认GCJ02
        //GCJ02:国测局坐标;
        //BD09ll:百度经纬度坐标;
        //BD09:百度墨卡托坐标;
        //海外地区定位,无需设置坐标类型,统一返回WGS84类型坐标

        option.setScanSpan(1000);
        //可选,设置发起定位请求的间隔,int类型,单位ms
        //如果设置为0,则代表单次定位,即仅定位一次,默认为0
        //如果设置非0,需设置1000ms以上才有效

        option.setOpenGps(true);
        //可选,设置是否使用gps,默认false
        //使用高精度和仅用设备两种定位模式的,参数必须设置为true

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

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

        option.SetIgnoreCacheException(false);
        //可选,设置是否收集Crash信息,默认收集,即参数为false

        option.setWifiCacheTimeOut(5*60*1000);
        //可选,V7.2版本新增能力
        //如果设置了该接口,首次启动定位时,会先判断当前Wi-Fi是否超出有效期,若超出有效期,会先重新扫描Wi-Fi,然后定位

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

        option.setNeedNewVersionRgc(true);
        //可选,设置是否需要最新版本的地址信息。默认需要,即参数为true

        locationClient.setLocOption(option);
  1. 实现BDAbstractLocationListener接口
class MyLocationListener extends BDAbstractLocationListener {
    
    

        @Override
        public void onReceiveLocation(BDLocation location) {
    
    
            double latitude = location.getLatitude();    //获取纬度信息
            double longitude = location.getLongitude();    //获取经度信
            Log.d("MainActivity",latitude+"    "+longitude);
            float radius = location.getRadius();    //获取定位精度,默认值为0.0f

            String coorType = location.getCoorType();
            //获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准

            int errorCode = location.getLocType();
            //获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
        }
    }
  • 获取定位经纬度

只需发起定位,便能够从BDAbstractLocationListener监听接口中获取定位结果信息

   locationClient.start();

使用baiduSDK解析城市名

直接可在 BDAbstractLocationListener接口的实现类中获取到,在 onReceiveLocation()方法中添加如下方法遍可获取到对应的地区

public class MyLocationListener extends BDAbstractLocationListener{
    
    
    @Override
    public void onReceiveLocation(BDLocation location){
    
    
        //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
        //以下只列举部分获取地址相关的结果信息
        //更多结果信息获取说明,请参照类参考中BDLocation类中的说明
			
        String addr = location.getAddrStr();    //获取详细地址信息
        String country = location.getCountry();    //获取国家
        String province = location.getProvince();    //获取省份
        String city = location.getCity();    //获取城市
        String district = location.getDistrict();    //获取区县
        String street = location.getStreet();    //获取街道信息
        String adcode = location.getAdCode();    //获取adcode
        String town = location.getTown();    //获取乡镇信息
    }
}

把上述代码进行封装

  • 定义回调接口,用于把获取到的经纬度返回
public interface ReturnLocation {
    
    
    public void return_LatIng(String Lat,String Ing);
}

  • BDAbstractLocationListener接口的实现类

class MyLocationListener extends BDAbstractLocationListener {
    
    
  
    private ReturnLocation returnLocation;
    public MyLocationListener() {
    
    
    }

    public MyLocationListener(ReturnLocation returnLocation) {
    
    
        this.returnLocation = returnLocation;
    }

    @Override
    public void onReceiveLocation(BDLocation location){
    
    
        //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
        //以下只列举部分获取经纬度相关(常用)的结果信息
        //更多结果信息获取说明,请参照类参考中BDLocation类中的说明
        double latitude = location.getLatitude();    //获取纬度信息
        double longitude = location.getLongitude();    //获取经度信息

        returnLocation.return_LatIng(String.valueOf(latitude),String.valueOf(longitude));


        float radius = location.getRadius();    //获取定位精度,默认值为0.0f

        String coorType = location.getCoorType();
        //获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准

        int errorCode = location.getLocType();
        //获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
    }

}

  • 主要的定位服务类
public class LocationService {
    
    
    private LocationClient client = null;
    private LocationClientOption mOption,DIYoption;
    private Object objLock = new Object();

    public LocationService(Context locationContext){
    
    
        synchronized (objLock) {
    
    
            if(client == null){
    
    
                client = new LocationClient(locationContext);
                client.setLocOption(getDefaultLocationClientOption());
            }
        }
    }

    // 注册
    public boolean registerListener(BDAbstractLocationListener listener){
    
    
        boolean isSuccess = false;
        if(listener != null){
    
    
            client.registerLocationListener(listener);
            isSuccess = true;
        }
        return  isSuccess;
    }

    // 注销
    public void unregisterListener(BDAbstractLocationListener listener){
    
    
        if(listener != null){
    
    
            client.unRegisterLocationListener(listener);
        }
    }

    //设置配置
    public boolean setLocationOption(LocationClientOption option){
    
    
        boolean isSuccess = false;
        if(option != null){
    
    
            if(client.isStarted())
                client.stop();
            DIYoption = option;
            client.setLocOption(option);
        }
        return isSuccess;
    }

    //默认Option设置
    public LocationClientOption getDefaultLocationClientOption(){
    
    
        if(mOption == null){
    
    
            mOption = new LocationClientOption();
            mOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
            mOption.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
            mOption.setScanSpan(1000);//可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
            mOption.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
            mOption.setIsNeedLocationDescribe(true);//可选,设置是否需要地址描述
            mOption.setNeedDeviceDirect(false);//可选,设置是否需要设备方向结果
            mOption.setLocationNotify(false);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
            mOption.setIgnoreKillProcess(true);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
            mOption.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
            mOption.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
            mOption.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
            mOption.setOpenGps(true);//可选,默认false,设置是否开启Gps定位
            mOption.setIsNeedAltitude(false);//可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用

        }
        return mOption;
    }


    //自定义Option设置
    public LocationClientOption getOption(){
    
    
        if(DIYoption == null) {
    
    
            DIYoption = new LocationClientOption();
        }
        return DIYoption;
    }

    public void start(){
    
    
        synchronized (objLock) {
    
    
            if(client != null && !client.isStarted()){
    
    
                client.start();
            }
        }
    }
    public void stop(){
    
    
        synchronized (objLock) {
    
    
            if(client != null && client.isStarted()){
    
    
                client.stop();
            }
        }
    }

    public boolean isStart() {
    
    
        return client.isStarted();
    }

    public boolean requestHotSpotState(){
    
    
        return client.requestHotSpotState();
    }
   
}

使用示例;

private LocationService locationService;
    private MyLocationListener myListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
                PackageManager.PERMISSION_GRANTED) {
    
    

            ActivityCompat.requestPermissions(this, new String[]{
    
    Manifest.permission.ACCESS_FINE_LOCATION}, 1);
        }
        else{
    
    

            get();
        }
    }
    private void get() {
    
    
        locationService = new LocationService(this);
        myListener = new MyLocationListener(new ReturnLocation() {
    
    
            @Override
            public void return_LatIng(String Lat, String Ing) {
    
    
                Log.d("MainActivity","纬度  "+Lat);
                Log.d("MainActivity","经度  "+Ing);
            }
        });
        locationService.registerListener(myListener);
        locationService.setLocationOption(locationService.getDefaultLocationClientOption());
        locationService.start();

    }

    @Override
    protected void onDestroy() {
    
    
        super.onDestroy();
        locationService.stop();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    
    
        switch (requestCode){
    
    
            case 1:
                if(grantResults.length > 0 && grantResults[0]==PackageManager.PERMISSION_GRANTED)
                    get();
        }
    }

真机运行结果
在这里插入图片描述
    

使用经纬度反编译获取地区名

    如果你已经知道了经纬度,可以无需进行Android Stdio配置baidu SDK,直接使用它提供的api可直接访问到经纬度对应的位置
官网地址链接

 http://api.map.baidu.com/geocoder?output=json&location=31.225696563611,121.49884033194&key=你的AK

返回的数据如下,之后进行解析就可获取到相应的地区

{
    
    
    "status":"OK",
    "result":{
    
    
        "location":{
    
    
            "lng":121.49884,
            "lat":31.225696
        },
        "formatted_address":"上海市黄浦区净土街31弄-4号",
        "business":"老西门,城隍庙,豫园",
        "addressComponent":{
    
    
            "city":"上海市",
            "direction":"north",
            "distance":"58",
            "district":"黄浦区",
            "province":"上海市",
            "street":"净土街",
            "street_number":"31弄-4号"
        },
        "cityCode":289
    }
}

使用示范如下:

发送okHttp的帮助类,具体的使用方法链接

public class HTTpUtil {
    
    

    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){
    
    
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .build();
        //OkHtt在enqueue()方法的内部已经帮我们开好子线程了,它会在子线程中去执行HTTP请求,并将结果回调到okhttp3.Callback中
        client.newCall(request).enqueue(callback);
    }
}

使用GSON解析的解析类
GSON的具体使用

public class GetLocationPlace {
    
    
  
    @SerializedName("status")
    public String status;
    @SerializedName("result")
    public Result result;

    public class Result{
    
    
        @SerializedName("formatted_address")
        public String formatted_address;
        @SerializedName("addressComponent")
        public AddressComponent addressComponent;
    }

    public  class  AddressComponent{
    
    
        @SerializedName("city")
        public String city;
        @SerializedName("district")
        public String district;
        @SerializedName("province")
        public String province;
    }

}

GSON解析的工具类

public class Utility {
    
    
    public static GetLocationPlace handlePlaceResponse(String response){
    
    
        Gson gson = new Gson();
        try{
    
    
            GetLocationPlace getLocationPlace = gson.fromJson(response,GetLocationPlace.class);
            return getLocationPlace;
        }catch (Exception e){
    
    
            return null;
        }

    }
}

活动中的使用代码,传入经纬度打印地区

public void getAddress(final String Lat, final String Ing) {
    
    
		//CoolWeatherApplication.getBaiduApptoken()中放的是baiduSDK申请到的AK值
        String address = "http://api.map.baidu.com/geocoder?output=json&location="
                + Lat + "," + Ing + "&key=" + CoolWeatherApplication.getBaiduApptoken();
        HTTpUtil.sendOkHttpRequest(address, new Callback() {
    
    
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
    
    
                runOnUiThread(new Runnable() {
    
    
                    @Override
                    public void run() {
    
    
                        Toast.makeText(CoolWeatherApplication.getContext(), "获取地区失败", Toast.LENGTH_SHORT).show();
                      
                    }
                });
            }
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
    
    
                String re = response.body().string();
                final GetLocationPlace locationPlace = Utility.handlePlaceResponse(re);

                runOnUiThread(new Runnable() {
    
    
                    @Override
                    public void run() {
    
    
                        if(locationPlace==null){
    
    
                            Toast.makeText(CoolWeatherApplication.getContext(), "获取地区失败", Toast.LENGTH_SHORT).show();
                            return;
                        }
                        String placeName = locationPlace.result.formatted_address;
                        Log.d("MainActivity",placeName);
                    }
                });

            }
        });
    }

猜你喜欢

转载自blog.csdn.net/haazzz/article/details/109297968