以前个人项目中的位置定位使用的是基站方法,使用的Google提供的API,可是前天中午忽然就不返回数据了,到网上搜了一下才知道,Google的接口不提供服务了,基于时间紧迫用了百度现有的SDK,可是在使用过程当中第一次获取位置老是空值,通过屡次实验终于成功。固然,若是须要精确的位置,你能够再加上位置偏移算法。个人应用对这个要求不高,就没作,一搜一大把,就很少说了。 java
下面这段话来自 百度地图API>定位SDK android
百度地图定位SDK免费对外开放,无需申请key。在使用百度定位SDK前,但愿先阅读百度定位地图的API。若是使用则被视为对使用条款的彻底接收,并赞成接收本协议的各项条款约束。
目前百度地图定位SDK只支持Android和Symbian量大平台,其余产品正在开放中。 git
下面事例是使用Android平台的部分代码。对于这个平台百度的开放人员已经写了完整的demo,把工程导入到eclipse中以后通常没有错误,若是报错的话,eclipse也会给出提示。通常能够经过将propertie.properties文件名字改成default.properties就能够了,若是还有错误的话,显示工程activity错误啊什么的,就是SDK版本不对的问题了,你能够经过他的manifest文件查看<uses-sdk android:minSdkVersion="8" />找到这个最小值,好比我下载的是2.6他的最低版本是5,我eclipse默认版本是8,就能够同过右键单击该工程,选择最下面那个properties项,而后在弹出对话框的右侧列表中选择Android,在左侧选择API level为5,也就是2.0,而后肯定。就木有问题了。 算法
下面说一下使用该API的具体步骤:
也能够查看百度定位SDK本身的开发指南 服务器
一、首先第一步就是搭配环境:
①先将百度demo中的libs文件夹复制到本身的工程。(别忘记把jar包build path)
②而后复制 网络
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" android:permission="android.permission.BAIDU_LOCATION_SERVICE"> <intent-filter> <action android:name="com.baidu.location.service_v2.6"></action> </intent-filter> </service>
到manifest的application 节点
接下来复制百度地位SDK须要的permission app
<permission android:name="android.permission.BAIDU_LOCATION_SERVICE"></permission> <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"> </uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"> </uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE"> </uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"> </uses-permission> <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
③ 接下来就能够在代码中放心的使用百度定位SDK了.
下面是来自百度的提醒.须要注意的是第五条,由于咱们第一次常常定位不到位置: eclipse
一、您须要确保程序编译经过。若是对本身写的代码有疑问,能够下载官方高级示例,查看标准源代码。 ide
二、请确保网络通畅,不管是链接wifi仍是使用2G/3G信号。 测试
三、定位SDK的调用必须在主线程中。
四、必须在定位SDK启动前设定好参数,例如是否使用GPS,扫描时间间隔设置等。咱们强烈建议您设置本身的prodName,并保管好,这样方便咱们为您提供更好的定位服务。
五、定位SDK start以后当即执行,这种状况下很难定位成功,由于定位SDK刚开始启动尚未获取到定位信息。这时getlocation通常为null。若是是要获取位置成功,能够在listerner中添加一个判断若是strData为空,则再发起一次定位。
六、定位覆盖率大概在98%。就是说有2%可能服务器没有数据,因此定位会失败。只须要走到别的地方,或者多试几回便可成功定位。
七、请使用真机。在虚拟机上没法进行定位测试。
下面就是个人事例代码:
具体思路是:将开启和获取位置的代码分开来作,能够在程序刚开启的时候就start。由于据上面所说,有时候可能两分钟才能获取到位置,对于咱们须要展现信息来讲,这是绝对不能够的。若是在主线程卡两分钟后果可想而知的。
须要说名的是:我这里没有设置时间间隔public void setScanSpan ( int ) //设置定时定位的时间间隔。单位ms,若是不设置或者所设置的整数值小于1000(ms)时,采用第一次定位模式。每调用一次requestLocatin(),定位SDK会发起一次定位。请求定位与监听结果一一对应;若是所设的整数值大于等于1000(ms)时,定位SDK内部使用定时定位模式。调用requestLocation( )后,每隔设定的时间,定位SDK就会进行一次定位。若是定位SDK根据定位依据发现位置没有发生变化,就不会发起网络请求,返回上一次定位的结果;若是发现位置改变,就进行网络请求进行定位,获得新的定位结果。定时定位时,调用一次requestLocation,会定时监听到定位结果。设定了定时定位后,能够热切换成一次定位,须要从新设置时间间隔小于1000(ms)便可。locationClient对象stop后,将再也不进行定位。若是设定了定时定位模式后,屡次调用requestLocation(),则是每隔一段时间进行一次定位,同时额外的定位请求也会进行定位,但频率不会超过1秒一次。
import android.content.Context; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.palmdeal.entity.LocationInfo.SItude; import com.palmdeal.util.Logger; public class LocationProvider { private static LocationClient mLocationClient = null; private static SItude station = new SItude(); private static MyBDListener listener = new MyBDListener(); Context context; public LocationProvider(Context context) { super(); this.context = context; } public void startLocation() { mLocationClient = new LocationClient(context); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); // 打开gps option.setCoorType("bd09ll"); // 设置坐标类型为bd09ll option.setPriority(LocationClientOption.NetWorkFirst); // 设置网络优先 option.setProdName("demo"); // 设置产品线名称 mLocationClient.setLocOption(option); mLocationClient.registerLocationListener(listener); mLocationClient.start();//将开启与获取位置分开,就能够尽可能的在后面的使用中获取到位置 } /** * 中止,减小资源消耗 */ public void stopListener() { if (mLocationClient != null && mLocationClient.isStarted()) { mLocationClient.stop(); mLocationClient = null; } } /** * 更新位置并保存到SItude中 */ public void updateListener() { if (mLocationClient != null && mLocationClient.isStarted()) { mLocationClient.requestLocation(); Logger.i("update the location"); } } /** * 获取经纬度信息 * * @return */ public SItude getLocation() { return station; } private static class MyBDListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location.getCity() == null) { int type = mLocationClient.requestLocation(); Logger.e("first request false" + type); } station.latitude = location.getLatitude(); station.longitude = location.getLongitude(); } @Override public void onReceivePoi(BDLocation arg0) { // return } } }
public class LocationInfo { /** 经纬度信息结构体 */ public static class SItude { /** 纬度 */ public double latitude; /** 经度 */ public double longitude; } }在使用的时候,在一开始就开启LocationClient,即调用startLocation()方法。个人是在服务服务中的onCreate中调用的,而后在代码中这样使用:
LocationInfo.SItude station = location.getLocation(); if (station.latitude == 0.0 && station.longitude == 0.0) { location.updateListener(); station = location.getLocation(); } if (station.latitude == 0.0 && station.longitude == 0.0) { return "未定位到您如今的位置,请重试"; } location.stopListener();使用上面的方法后,第一次使用都能拿到位置信息。