Android使用百度地图api获取定位信息(经纬度)

文章目录

  • 注册
  • 申请密钥
  • 配置
  • 使用
  • 遇到问题

注册

登录百度地图开放平台 注册百度地图开发者,填写相关信息
Android使用百度地图api获取定位信息(经纬度)_第1张图片
提交成功后收到邮件
Android使用百度地图api获取定位信息(经纬度)_第2张图片
点击链接弹出如下提示就算激活成功了
Android使用百度地图api获取定位信息(经纬度)_第3张图片

申请密钥

点击申请密钥或者创建应用
Android使用百度地图api获取定位信息(经纬度)_第4张图片

填入应用相关信息
Android使用百度地图api获取定位信息(经纬度)_第5张图片

  • Android Studio获取SHA1方式
  1. release
    在底部Terminal控制台(没有这栏,在顶部View->Tool Windows选上或者AIt+F12)中,输入:keytool -list -keystore -v -keystore + .jks文件的绝对路径

    keytool -list -v -keystore C:\keystore.jks
    

    我的jks就在项目底下所以直接输入keystore.jks
    Android使用百度地图api获取定位信息(经纬度)_第6张图片

    然后输入密钥库口令(没印象有这东西的试试看直接回车),就成功获取我们需要的SHA1
    Android使用百度地图api获取定位信息(经纬度)_第7张图片

  2. debug
    如果知道debug.keystore的路径,就和release的方式一样获取。

    还可以通过点击右侧Gradle(没有这栏,在顶部View->Tool Windows选上)->appName->Tasks->android->signingReport
    Android使用百度地图api获取定位信息(经纬度)_第8张图片
    等待片刻就可以在Run一栏看到我们要的debug的SAH1了
    Android使用百度地图api获取定位信息(经纬度)_第9张图片
    申请密钥时最好把发布版和开发版的SHA1都填上,方便我们调试。

  • 包名获取
    build.gradle的applicationId或者AndroidManifest的package
    Android使用百度地图api获取定位信息(经纬度)_第10张图片
    在这里插入图片描述
    注意:使用Android Studio开发,如遇到applicationId 与在 AndroidManifest.xml 中定义的包名不一致的情况,以appclicationid为准。

提交成功就可以在查看应用中看到我们的应用信息
Android使用百度地图api获取定位信息(经纬度)_第11张图片

配置

前往百度地图SDK下载所需的sdk,因为我们只需要获取定位信息,所以下载基础定位的就够了
Android使用百度地图api获取定位信息(经纬度)_第12张图片
Android使用百度地图api获取定位信息(经纬度)_第13张图片

将我们下载的基础定位包解压后,将里面的东西拷贝一份到libs文件夹中,如果没有可以新建一个。
Android使用百度地图api获取定位信息(经纬度)_第14张图片

然后在gradle配置我们的libs路径(sourceSets和defaultConfig同级)

sourceSets{
        main{
            //说明so的路径为该libs路径
            jniLibs.srcDir 'libs'
        }
    }

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

jniLibs.srcDirs =['src/main/libs']

然后在build.gradle添加依赖

dependencies{
  api files('libs/BaiduLBS_Android.jar')
}

或者通过顶部File->Project Sturcture(Ctrl+Alt+Shift+S)打开窗口,根据图示选择需要的jar包,会自动引入上方代码,最后同步一下gradle。
Android使用百度地图api获取定位信息(经纬度)_第15张图片

如果需要混淆的,在proguard-rules.pro加入以下代码

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

使用

在AndoirdMainifest.xml的application底下添加






 

加入所需的权限



















获取定位信息我用了官方demo中的LocationService(最后会附上代码),在需要的activity初始化中加入

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_location);
    locationService = new LocationService(this);
    locationService.registerListener(mListener);
    locationService.setLocationOption(locationService.getDefaultLocationClientOption());
}
  • 初始化location实例

    locationService = new LocationService(this);
    

    如果是多个activity中使用建议在Application中初始化location实例,新建一个App类

    public class App extends Application {
        public LocationService locationService;
    
        @Override
        public void onCreate() {
            super.onCreate();
            locationService = new LocationService(this);
        }
    }
    

    在AndoirdMainifest.xml的application加上name属性

    
    
    

    然后在我们要用的activity中获取Application中的实例

    locationService = ((App) getApplication()).locationService;
    
  • 注册定位服务

    locationService.registerListener(mListener);
    

    mListener为我们定位后的回调结果

    /*****
    *
    * 定位结果回调,重写onReceiveLocation方法
    *
    */
    private BDAbstractLocationListener mListener = new BDAbstractLocationListener() {
    
       @Override
       public void onReceiveLocation(BDLocation location) {
           // TODO Auto-generated method stub
           if (null != location && location.getLocType() != BDLocation.TypeServerError) {
           		//获取信息后的操作
           }
       }
    };
    
  • 设置配置

    locationService.setLocationOption(locationService.getDefaultLocationClientOption());
    

    目前我使用的是demo中的默认配置,可按自己的要求修改

    //默认Option设置 
    public LocationClientOption getDefaultLocationClientOption(){
    	if(mOption == null){
    		mOption = new LocationClientOption();
    		mOption.setLocationMode(LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
    		mOption.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
    		mOption.setScanSpan(3000);//可选,默认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;
    }
    

初始化以及注册实例后我们就可以使用了,在要定位的启动

//启动
locationService.start();

停止定位

//停止
locationService.stop();

当然不要忘了在销毁页面注销监听

@Override
    protected void onDestroy() {
        super.onDestroy();
        locationService.unregisterListener(mListener); //注销掉监听
        locationService.stop(); //停止定位服务
    }

效果图如下
Android使用百度地图api获取定位信息(经纬度)_第16张图片
最后附上代码
LocationService.class

import android.content.Context;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;

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(LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
			mOption.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
			mOption.setScanSpan(3000);//可选,默认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();
	}
}

LocationActivity.class

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.Poi;
import com.ffcs.imr.service.LocationService;

public class LocationActivity extends Activity {
    private LocationService locationService;
    private TextView mTextView;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_location);

        mTextView = findViewById(R.id.textview);
        button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (button.getText().toString().equals("打开定位")) {
                    locationService.start();
                } else {
                    locationService.stop();
                    button.setText("打开定位");
                    mTextView.setText("");
                }
            }
        });

        locationService = new LocationService(this);
//        多个activity
//        locationService = ((App) getApplication()).locationService;
        locationService.registerListener(mListener);
        locationService.setLocationOption(locationService.getDefaultLocationClientOption());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        locationService.unregisterListener(mListener); //注销掉监听
        locationService.stop(); //停止定位服务
    }

    /*****
     *
     * 定位结果回调,重写onReceiveLocation方法,可以直接拷贝如下代码到自己工程中修改
     *
     */
    private BDAbstractLocationListener mListener = new BDAbstractLocationListener() {

        @Override
        public void onReceiveLocation(BDLocation location) {
            // TODO Auto-generated method stub
            if (null != location && location.getLocType() != BDLocation.TypeServerError) {
                button.setText("停止定位");
                StringBuilder sb = new StringBuilder(256);
                sb.append("time : ");
                /**
                 * 时间也可以使用systemClock.elapsedRealtime()方法 获取的是自从开机以来,每次回调的时间;
                 * location.getTime() 是指服务端出本次结果的时间,如果位置不发生变化,则时间不变
                 */
                sb.append(location.getTime());
                sb.append("\nlocType : ");// 定位类型
                sb.append(location.getLocType());
                sb.append("\nlocType description : ");// *****对应的定位类型说明*****
                sb.append(location.getLocTypeDescription());
                sb.append("\nlatitude : ");// 纬度
                sb.append(location.getLatitude());
                sb.append("\nlontitude : ");// 经度
                sb.append(location.getLongitude());
                sb.append("\nradius : ");// 半径
                sb.append(location.getRadius());
                sb.append("\nCountryCode : ");// 国家码
                sb.append(location.getCountryCode());
                sb.append("\nCountry : ");// 国家名称
                sb.append(location.getCountry());
                sb.append("\ncitycode : ");// 城市编码
                sb.append(location.getCityCode());
                sb.append("\ncity : ");// 城市
                sb.append(location.getCity());
                sb.append("\nDistrict : ");// 区
                sb.append(location.getDistrict());
                sb.append("\nStreet : ");// 街道
                sb.append(location.getStreet());
                sb.append("\naddr : ");// 地址信息
                sb.append(location.getAddrStr());
                sb.append("\nUserIndoorState: ");// *****返回用户室内外判断结果*****
                sb.append(location.getUserIndoorState());
                sb.append("\nDirection(not all devices have value): ");
                sb.append(location.getDirection());// 方向
                sb.append("\nlocationdescribe: ");
                sb.append(location.getLocationDescribe());// 位置语义化信息
                sb.append("\nPoi: ");// POI信息
                if (location.getPoiList() != null && !location.getPoiList().isEmpty()) {
                    for (int i = 0; i < location.getPoiList().size(); i++) {
                        Poi poi = (Poi) location.getPoiList().get(i);
                        sb.append(poi.getName() + ";");
                    }
                }
                if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                    sb.append("\nspeed : ");
                    sb.append(location.getSpeed());// 速度 单位:km/h
                    sb.append("\nsatellite : ");
                    sb.append(location.getSatelliteNumber());// 卫星数目
                    sb.append("\nheight : ");
                    sb.append(location.getAltitude());// 海拔高度 单位:米
                    sb.append("\ngps status : ");
                    sb.append(location.getGpsAccuracyStatus());// *****gps质量判断*****
                    sb.append("\ndescribe : ");
                    sb.append("gps定位成功");
                } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                    // 运营商信息
                    if (location.hasAltitude()) {// *****如果有海拔高度*****
                        sb.append("\nheight : ");
                        sb.append(location.getAltitude());// 单位:米
                    }
                    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号和大体定位时间到[email protected],会有人追查原因");
                } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                    sb.append("\ndescribe : ");
                    sb.append("网络不同导致定位失败,请检查网络是否通畅");
                } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                    sb.append("\ndescribe : ");
                    sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
                }
                logMsg(sb.toString());
            }
        }

    };

    /**
     * 显示请求字符串
     */
    public void logMsg(final String str) {
        try {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    mTextView.post(new Runnable() {
                        @Override
                        public void run() {
                            mTextView.setText(str);
                        }
                    });
                }
            }).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

activity_location.xml




    

遇到问题

  1. NetWork location failed because baidu location service can not decrypt the request query, please check the so file!
    a. 确保自己的so文件没有少
    b. 在检查下build.gradle的lib配置是否正确,详细内容请看本文的配置 。
  2. NetWork location failed because baidu location service check the key is unlegal, please check the key in AndroidManifest.xml!
    a. 先检查AndroidManifest.xml是否配置了AK
    b. 看看申请的包名和所用的AK是否匹配
    c. 注意下自己申请的时候用的SHA1是哪个版本的,如果你直接运行AndroidStudio的debug版本,要确保有在申请的时候填入相应的SHA1。打包路径的签名只能让你release版本使用定位功能。debug版本的签名获取请看本文的申请密钥 。
  3. Offline location failed, please check the net (wifi/cell)!
    a. 检查网路是否打开
    b. 是否在AndroidManifest.xml加入网络权限
    c. 是否赋予应用网络权限,权限的选择看本文的使用
  4. Location failed beacuse we can not get any loc information!
    a. 是否在AndroidManifest.xml加入定位权限
    b. 是否赋予应用定位权限,权限的选择看本文的使用
    • 无法获取定位信息定位
    • 成功定位一次后,接下来无法获取定位信息
    • 回调BDAbstractLocationListener没有执行

检查错误3是否发生,再确认AndoirdMainifest.xml的application有没有加上






 

你可能感兴趣的:(Android使用百度地图api获取定位信息(经纬度))