不用百度地图,不用高德地图,使用原生的android api也可以定位并做相应的优化
来源:互联网 发布:网络新技术专题报告 编辑:程序博客网 时间:2024/05/18 00:54
之前使用过高德地图和百度地图,大部分都还是很准,不过有时也漂移得很利害,没有别的办法,只能上报给相应的地图公司,等呀等,无聊的时候就研究了一下,android自己的原生api,嘿,原来也可以使用,官网还给了优化的东西,好了,不多说了,上图上代码:
下面来说说主要关键代码:
private LocationManager locationManager=null;
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
上面代码是获取相应的定位管理器。
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0, 0,locationListener);
使用定位管理器对象请求定位,第一个参数可以是NETWORK_PROVIDER(网络定位—基于基站和wifi),和GPS_PROVIDER(GPS定位—基于卫星),当然定位需要获取权限,所以要在AndroidManifest.xml文件声明:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
或者
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
他们都声明比较保险,但文档说,如果要用到NETWORK_PROVIDER和GPS_PROVIDER,可以使用ACCESS_FINE_LOCATION,如果只用到NETWORK_PROVIDER,就声明ACCESS_COARSE_LOCATION就可以了,推荐声明ACCESS_FINE_LOCATION这个吧,省得麻烦,第二个参数是连续定位的间隔时间,这里的单位是毫秒,第三个参数是连续定位的间隔距离,单位是米,最后那个参数是定位结果的回调,我下面会列出来
LocationListenerlocationListener=newLocationListener() {
public void onLocationChanged(Location location) {
// Called whena new location is found by the network location provider.
//makeUseOfNewLocation(location);
if(isBetterLocation(location,curLocation)){
curLocation=location;
getAddrByhandler(curLocation);
}
Log.e(getClass().getName(),"location lat:"+location.getLatitude()+",lon:"+location.getLongitude());
}
public void onStatusChanged(String provider,intstatus, Bundleextras) {
Log.e(getClass().getName(),"onStatusChanged");
}
public void onProviderEnabled(String provider) {
Log.e(getClass().getName(),"onProviderEnabled");
}
public void onProviderDisabled(String provider) {
Log.e(getClass().getName(),"onProviderDisabled");
}
};
上面代码定位结果的回调,当定位到结果,我保存前会检查其的新旧合理性,过滤掉一些不太好的结果,代码我会贴到下面:
protected boolean isBetterLocation(Locationlocation, Location currentBestLocation) {
if (currentBestLocation == null) {
return true;
}
long timeDelta = location.getTime() -currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta> EXPIRE_TIME;
boolean isSignificantlyOlder = timeDelta< -EXPIRE_TIME;
boolean isNewer = timeDelta > 0;
if (isSignificantlyNewer) {
return true;
} else if (isSignificantlyOlder) {
return false;
}
int accuracyDelta = (int)(location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta >0;
boolean isMoreAccurate = accuracyDelta <0;
boolean isSignificantlyLessAccurate =accuracyDelta > 200;
boolean isFromSameProvider =isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
if (isMoreAccurate) {
return true;
} else if (isNewer &&!isLessAccurate) {
return true;
} else if (isNewer &&!isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
上面的代码主要是根据刚刚返回的结果与之前已存的结果在时间新旧,定位的精准度和是否是同种定位来源上作比较,把好的好的留下,定位结果返回的只有经纬度一些信息,其中不包括详细的地址,下面我将介绍通过经纬度来获取相应的详细地址:
private Geocoder geocoder=null;
geocoder = new Geocoder(this,Locale.getDefault());
上面是创建一个地理编码器对象,下面介绍如何使用它:
privatevoid getAddrByhandler(Location location){
List<Address>addresses = null;
try{
addresses =geocoder.getFromLocation(location.getLatitude(),
location.getLongitude(),1);
} catch (IOException ioException) {
Log.e(TAG, "服务不可用!", ioException);
} catch (IllegalArgumentExceptionillegalArgumentException) {
Log.e(TAG, "无效的经纬度" + ". " +"Latitude = " + location.getLatitude()+", Longitude = " +
location.getLongitude(),illegalArgumentException);
}
if (addresses == null ||addresses.size() == 0) {
Log.e(TAG, "没有找到相关地址!");
} else {
Address address = addresses.get(0);
ArrayList<String>addressFragments = new ArrayList<String>();
curAddr="";
for(int i = 0; i <address.getMaxAddressLineIndex(); i++) {
addressFragments.add(address.getAddressLine(i));
curAddr=curAddr+address.getAddressLine(i);
}
if(!TextUtils.isEmpty(address.getFeatureName())
&&!addressFragments.isEmpty()
&& !addressFragments.get(addressFragments.size()-1).equals(address.getFeatureName())){
addressFragments.add(address.getFeatureName());
curAddr=curAddr+address.getFeatureName();
}
updateShowData();
Log.i(TAG, "详情地址已经找到,地址:"+curAddr);
}
}
上面是通过经纬度把相应的详细地址取到,其中我测试的结果address.getMaxAddressLineIndex()是2,但结果却是那个列表却是3,有点坑,所以我补写了一段把address.getFeatureName()加上去了(刚刚没有拿到的),好了,主要代码就已经写完了,有的匆匆忙忙,有很多不足之处,请大家指点,谢谢大家!
原代码的demo已经上传,请移步到如下地址:
http://download.csdn.net/detail/bright789/9388324
参考了资料:
http://developer.android.com/guide/topics/location/strategies.html#BestPerformance
http://developer.android.com/training/location/display-address.html
- 不用百度地图,不用高德地图,使用原生的android api也可以定位并做相应的优化
- 使用百度地图API,定位并显示自己的位置
- 百度地图Android定位SDK的API
- 百度地图定位API,locationClient的使用
- 高德地图 Android API 的定位原理及使用方法
- Android-百度地图定位的使用
- android百度地图---使用API定位不成功
- 百度地图定位的使用
- 百度地图的使用(定位)
- 百度地图定位的使用
- Android中使用百度API定位,并实现手势操作(显示最后点击地图的位置)
- 百度地图定位,高德地图定位
- iOS 跳转到地图后导航(高德地图,百度地图,腾讯地图,苹果手机原生的地图)
- Android 高德地图,显示地图,并定位当前的位置
- Android高德地图的定位
- 百度地图API解决 android 6.0定位不了的问题
- 百度地图API解决 android 6.0定位不了的问题
- 百度地图API解决 android 6.0定位不了的问题
- Android SQLite数据库存储
- java检测linux系统中所有端口的ip地址
- linux shell数据重定向(输入重定向与输出重定向)详细分析
- [Java开发之路](12)JDOM和DOM4J解析XML文档
- Opencv人脸识别项目简介
- 不用百度地图,不用高德地图,使用原生的android api也可以定位并做相应的优化
- 解析Excel时列号数字转换为字母
- 从第一个字符串中删除第二个字符串中出现的所有字符
- linux下网络连接socket统计工具ss学习小结
- BZOJ 1009 KMP思想 + DP + 矩阵快速幂
- XML操作
- [HDU 4263]Red/Blue Spanning Tree[kruskal]
- 数据结构学习笔记——单链表
- 代理模式