Google Map API v2 步步为营 (二)----- Location
接上篇。
改造一下MapsActivity:
public class MapsActivity extends Activity implements LocationListener, InfoWindowAdapter, OnMarkerClickListener, OnMarkerDragListener{ }
实现4个interface:
android.location.LocationListener
GoogleMap.InfoWindowAdapter
GoogleMap.OnMarkerClickListener
GoogleMap.OnMarkerDragListener
本篇要实现在地图上定位,主要用到LocationListener接口。
另外3个接口关系到 打标记(Marker),移动标记点,以及点击标记弹出info窗口。这些功能将在下一篇文中整理。
地图初始化
首先在onCreate中需要对地图对象做一些设置:
@Override public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.map);........if(servicesConnected()){initMapView();} }
servicesConnected 检查service是否可用
private boolean servicesConnected() {// Check that Google Play services is availableint resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);// If Google Play services is availableif(ConnectionResult.SUCCESS == resultCode) {log("Google Play services is available.");isServiceOk = true;} else {// Get the error codeConnectionResult connectionResult = new ConnectionResult(resultCode, null);int errorCode = connectionResult.getErrorCode();// Get the error dialog from Google Play servicesDialog errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode,this,RESULT_CODE_SERVICE_FAILURE);// If Google Play services can provide an error dialogif(errorDialog != null) {errorDialog.show();}isServiceOk = false;}return isServiceOk; }
上一篇说过,手机调试环境需要安装Google Play服务和play store。如果没有安装,这里就会返回错误码。
initMapView 初始化
1 private void initMapView(){ 2 mMapView = ((MapFragment)getFragmentManager().findFragmentById(R.id.map_view)).getMap(); 3 mMapView.setMapType(GoogleMap.MAP_TYPE_NORMAL); 4 5 UiSettings setting = mMapView.getUiSettings(); 6 setting.setTiltGesturesEnabled(true); 7 //setting.setCompassEnabled(false); 8 } 9
2行,获得地图对象 GoogleMap mMapView;后面很多操作都要通过它。
3行,设在地图模式为normal
4行,UiSettings 设置人机交互相关的各种按钮手势等待,例如:
void setTiltGesturesEnabled(boolean) 是否允许手势改变视角;
void setCompassEnabled(boolean) 是否显示指南针;
详细的UiSettings用法可参考官文 https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/UiSettings
移动到经纬度地点
先阐明一个概念,Goolge Map假定地图本身是固定不动的,移动的是camera(public final class CameraUpdate)。
想象一下,在地球上空漂浮着一只佳能无敌兔,把镜头对准魔都,焦距拉近看到了一号线,再拉远,视角倾斜一下,看到了魔都全貌,还是带广角的。不错吧!
回到代码,这里需要用的GPS。通过LocationManager来获得位置服务
mLocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); mGPSOk = mLocManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
获得LocationManager,并检查GPS是否可用。
在onResume函数中注册监听
1 @Override 2 protected void onResume(){ 3 super.onResume(); 4 if(isServiceOk == false) 5 return; 6 7 String provider = getBestProvider(); 8 if(provider != null){ 9 mLocManager.requestLocationUpdates(provider, 5*1000, 1, this); 10 } 11 12 updateCurrentLoction(); 13 setLatLng(); 14 }
7行,获得可用的Location Provider,开启GPS的情况下这里得到的是GPS provider
9行,注册位置变化监听。第二入参5*1000表示每隔5秒更新一次,第三入参表示移动超过1米更新一次。最后一个入参即LocationListener,由于activity implement了LocationListener,所以这里只需要给activity的this指针。
12行和13行的两个函数,用于主动获取最新位置,移动地图到该位置,稍后贴出。
先看一下位置变化的监听函数,activity在implement了LocationListener后 需要实现一下几个函数:
1 /* LocationListener begin */ 2 @Override 3 public void onLocationChanged(Location newLoction) { 4 if(mLocation != null){ 5 mLocation.setLatitude(newLoction.getLatitude()); 6 mLocation.setLongitude(newLoction.getLongitude()); 7 animateLatLng(); 8 } 9 } 10 11 @Override 12 public void onProviderDisabled(String arg0) { 13 // TODO Auto-generated method stub 14 } 15 @Override 16 public void onProviderEnabled(String arg0) { 17 // TODO Auto-generated method stub 18 } 19 @Override 20 public void onStatusChanged(String arg0, int arg1, Bundle arg2) { 21 } 22 /* LocationListener end */
3~9行,我这里只处理了onLocationChanged,这个函数在location发生变化时会调用到。
我们用了一个私有数据:private Location mLocation = null;
在onLocationChanged函数中,把新的location保存到mLocation中,然后调用animateLatLng把地图移动到该位置。
=================================================================
mLocation用于记录每次更新的经纬度,建议在onPause的时候把这个数据保存到本地,我是保存在preference中的。在onResume时读出来。
这样可以避免gps不可用的时候,地图飞回非洲。
当然也可一增加一个对network provider的监听,通过网络获取不太准确的位置,这部份我没做完整。
因为火星坐标系的问题,我最后换了baidu map,google map的这个apk很多后续的优化就没做了,汗吧!
=================================================================
有时我们需要主动查询最新的Location
1 2 private void updateCurrentLoction(){ 3 String bestProvider = getBestProvider(); 4 Location newLoction = null; 5 6 if(bestProvider != null) 7 newLoction = mLocManager.getLastKnownLocation(bestProvider); 8 9 if(mLocation == null){ 10 mLocation = new Location(""); 11 } 12 13 if(newLoction != null){ 14 mLocation.setLatitude(newLoction.getLatitude()); 15 mLocation.setLongitude(newLoction.getLongitude()); 16 } 17 }
3行,获取最优的provider
7行,获取最近一次的location
8~16行,同样的,新位置记录到mLocation中。
getBestProvider函数体如下:
private String getBestProvider(){
Criteria criteria = new Criteria();
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String bestOne = mLocManager.getBestProvider(criteria, true);
return bestOne;
}
上文用到的两个函数setLatLng()和animateLatLng()
1 private void setLatLng(boolean marked){ 2 if(mLocation == null){ 3 Toast.makeText(this, R.string.gpserr, Toast.LENGTH_LONG).show(); 4 return; 5 } 6 7 double dLat = mLocation.getLatitude(); 8 double dLong = mLocation.getLongitude(); 9 log("setLatLng: (" + dLat + "," + dLong + ")"); 10 11 //LatLng latlng = new LatLng(31.13893, 121.39668); 12 LatLng latlng = new LatLng(dLat, dLong); 13 if((latlng.latitude == 0) && (latlng.longitude == 0)){ 14 //mMapView.moveCamera(CameraUpdateFactory.newLatLng(latlng)); 15 }else{ 16 mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 15)); 17 } 18 } 19 20 private void animateLatLng(boolean guide){ 21 if(mLocation == null){ 22 Toast.makeText(this, R.string.gpserr, Toast.LENGTH_LONG).show(); 23 return; 24 } 25 26 double dLat = mLocation.getLatitude(); 27 double dLong = mLocation.getLongitude(); 28 log("animateLatLng: (" + dLat + "," + dLong + ")"); 29 LatLng latlng = new LatLng(dLat, dLong); 30 31 mMapView.animateCamera(CameraUpdateFactory.newLatLng(latlng)); 32 }
先看第一个setLatLng():
7~8行,从mLocation中调用getLatitude()取得维度,getLongitude()取得经度。
12行,构造一个LatLng对象
16行, mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 15));
CameraUpdateFactory.newLatLngZoom(latlng, 15) 返回一个CameraUpdate对象,入参是经纬度和zoom level;
GoogleMap的moveCamera方法把地图移动到该位置。
animateLatLng()函数
31行 基本相同,唯一的区别是最后调用的是animateCamera,我们会看到地图从原location移动到新location的过程。而moveCamera方法是瞬移过去的,不会看到移动过程。
CameraUpdate有很多中构造方法,可以单独或同时指定位置和放大倍数。指定边界等待,详见
https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/CameraUpdateFactory
最后,要在onPause函数中注销位置服务监听
mLocManager.removeUpdates(this);
转载于:https://www.cnblogs.com/inkheart0124/p/3536322.html
Google Map API v2 步步为营 (二)----- Location相关推荐
- 关于Google Map API V2 版本的定位与导航
近来,在关注安卓手机上的GoogleMap应用的开发,但是目前官方API版本网页版已经升级到V3版,而对于Android的支持也已经升级到V2版本,虽然Google说继续对V1版提供服务,但是不再提供 ...
- Google Map API v2的定位
昨天刚开始看LBS相关的东西,搜了下发现几个问题:一个是时效性的问题,很多发表时间还算近的 内容写的却是V1的,很容易让我们这些菜鸟走更多的弯路:另一个是知识面的,发现有太多太多相同的文章 都在写一个 ...
- Google Map API v2 (三)----- 地图上添加标记(Marker),标记info窗口,即指定经纬度获取地址字符串...
接上篇 http://www.cnblogs.com/inkheart0124/p/3536322.html 1,在地图上打个标记 1 private MarkerOptions mMarkOptio ...
- android Google Map API V2 (key 申请)
要使用V2 的API,需要到Google APIs Console将Google Maps Android API v2服务开启(前提是你已经拥有Google帐号,并创建一个项目),见图: 然后用ke ...
- google map Api接口整理
Google Map Api接口整理 一:基本知识: 1. 使用谷歌地图 API 的第一步就是要注册一个 API 密钥,需要注意一下两点: 1.如果使用 API 的页面还没有发布,只是在本地调试,可以 ...
- Android传感器、语音识别、定位系统、Google Map API、快捷方式、widget编程总结及示例
Android特色开发 第一部分 传感器 传感器是一种物理装置或生物器官,能够探测.感受外界的信号.物理条件(如:光.热.湿度)或化学组成(如:烟雾),并将探知的信息传递给其他设备或器官. ...
- Android传感器、语音识别、定位系统、Google Map API、快捷方式、widget编程总结及示例...
Android特色开发 第一部分 传感器 传感器是一种物理装置或生物器官,能够探测.感受外界的信号.物理条件(如:光.热.湿度)或化学组成(如:烟雾),并将探知的信息传递给其他设备或器官. Andro ...
- Google Map Api for Android
Google Map Api for Android 项目需要使用了谷歌的地图api,总结一下. 先上几个图 一.项目介绍 1.点击搜索附近的公园 这个展示的可以点击地图的任意位置获取经纬度,并标记M ...
- Google Map API V3开发(5)
Google Map API V3开发(1) Google Map API V3开发(2) Google Map API V3开发(3) Google Map API V3开发(4) Google M ...
最新文章
- 关闭windows窗口时操作
- 蓝桥杯入门 (二)
- c#连接远程sqlserver2008_C#用代码控制网络断开与重连
- 汇编语言串指令经典题目
- ElasticSearch重启策略
- html搜索结果 重置,搜索结果和后退按钮/ HTML表格
- 快学Scala 第二课 (apply, if表达式,循环,函数的带名参数,可变长参数,异常)...
- java 可能尚未初始化变量,java - 局部变量“变量”可能尚未初始化-Java - 堆栈内存溢出...
- 1560F1. Nearest Beautiful Number (easy version)
- 数据库-MySQL中间的注释
- asyu中datagrid load 与reload
- 苹果电脑mysql_MacBook 安装 MySQL 5.7.29(新手都看得懂的安装教程)
- HDU 6070 线段树
- C++之客户消费积分管理系统
- 云计算淡定从容的大局观
- 2022-12-24 三阶魔方完整教程和口诀速记,二级魔方教程
- 【★】生成树算法终极解析!
- 信息精准智能推送(push)的五个关键
- 用matlab做矩阵变换(理解+实践);假设随机发给某班所有同学任意数字,生成10*5的矩阵
- 修改Thinkphp-cmf上传视频大小限制
热门文章
- 程序运行依赖的重要文件版本不对_Deno核心模块:灵活依赖amp;安全沙箱
- SUID + SGID + STICKY
- dedecms模版php,好织梦-专业dedecms模板,dede模板,织梦模板下载平台
- vue.js 默认选中select_vue.js 解决v-model让select默认选中不生效的问题
- 学习笔记-----关于C++中类的成员函数可以访问私有成员的问题
- ansible(5)——使用通配符操作ansible命令
- 包含Iphlpapi.h 编译错误 error C2065: 'HRASCONN'
- 和菜鸟一起学linux内核源码之基础准备篇
- 计算器服务端/客户端
- facenet + Mtcnn 实现人脸识别(实现步骤)