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 available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if(ConnectionResult.SUCCESS == resultCode) {
log("Google Play services is available.");
isServiceOk = true;
} else {
// Get the error code
ConnectionResult connectionResult = new ConnectionResult(resultCode, null);
int errorCode = connectionResult.getErrorCode();
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
errorCode,
this,
RESULT_CODE_SERVICE_FAILURE); // If Google Play services can provide an error dialog
if(errorDialog != null) {
errorDialog.show();
}
isServiceOk = false;
}
return isServiceOk;
}
上一篇说过,手机调试环境需要安装Google Play服务和play store。如果没有安装,这里就会返回错误码。
initMapView 初始化
private void initMapView(){
mMapView = ((MapFragment)getFragmentManager().findFragmentById(R.id.map_view)).getMap();
mMapView.setMapType(GoogleMap.MAP_TYPE_NORMAL); UiSettings setting = mMapView.getUiSettings();
setting.setTiltGesturesEnabled(true);
//setting.setCompassEnabled(false);
}
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函数中注册监听
@Override
protected void onResume(){
super.onResume();
if(isServiceOk == false)
return; String provider = getBestProvider();
if(provider != null){
mLocManager.requestLocationUpdates(provider, 5*1000, 1, this);
} updateCurrentLoction();
setLatLng();
}
7行,获得可用的Location Provider,开启GPS的情况下这里得到的是GPS provider
9行,注册位置变化监听。第二入参5*1000表示每隔5秒更新一次,第三入参表示移动超过1米更新一次。最后一个入参即LocationListener,由于activity implement了LocationListener,所以这里只需要给activity的this指针。
12行和13行的两个函数,用于主动获取最新位置,移动地图到该位置,稍后贴出。
先看一下位置变化的监听函数,activity在implement了LocationListener后 需要实现一下几个函数:
/* LocationListener begin */
@Override
public void onLocationChanged(Location newLoction) {
if(mLocation != null){
mLocation.setLatitude(newLoction.getLatitude());
mLocation.setLongitude(newLoction.getLongitude());
animateLatLng();
}
} @Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
/* 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
private void updateCurrentLoction(){
String bestProvider = getBestProvider();
Location newLoction = null; if(bestProvider != null)
newLoction = mLocManager.getLastKnownLocation(bestProvider); if(mLocation == null){
mLocation = new Location("");
} if(newLoction != null){
mLocation.setLatitude(newLoction.getLatitude());
mLocation.setLongitude(newLoction.getLongitude());
}
}
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()
private void setLatLng(boolean marked){
if(mLocation == null){
Toast.makeText(this, R.string.gpserr, Toast.LENGTH_LONG).show();
return;
} double dLat = mLocation.getLatitude();
double dLong = mLocation.getLongitude();
log("setLatLng: (" + dLat + "," + dLong + ")"); //LatLng latlng = new LatLng(31.13893, 121.39668);
LatLng latlng = new LatLng(dLat, dLong);
if((latlng.latitude == 0) && (latlng.longitude == 0)){
//mMapView.moveCamera(CameraUpdateFactory.newLatLng(latlng));
}else{
mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 15));
}
} private void animateLatLng(boolean guide){
if(mLocation == null){
Toast.makeText(this, R.string.gpserr, Toast.LENGTH_LONG).show();
return;
} double dLat = mLocation.getLatitude();
double dLong = mLocation.getLongitude();
log("animateLatLng: (" + dLat + "," + dLong + ")");
LatLng latlng = new LatLng(dLat, dLong); mMapView.animateCamera(CameraUpdateFactory.newLatLng(latlng));
}
先看第一个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有很多中构造方法,可以单独或同时指定位置和放大倍数。指定边界等待,详见
最后,要在onPause函数中注销位置服务监听
mLocManager.removeUpdates(this);
Google Map API v2 步步为营 (二)----- Location的更多相关文章
- Google Map API v2 步步为营(一) ----- 初见地图
官方文档:https://developers.google.com/maps/documentation/android/start?hl=zh-CN 先谷歌后百度.使用google的api基本上按 ...
- Android中Google地图路径导航,使用mapfragment地图上画出线路(google map api v2)详解
在这篇里我们只聊怎么在android中google map api v2地图上画出路径导航,用mapfragment而不是mapview,至于怎么去申请key,manifest.xml中加入的权限,系 ...
- google map api v2的使用详细过程,图文并茂(原创)
上一篇中说到怎么获取key,下面来介绍怎么使用key来显示google地图 步骤1:eclipse上打开android SDK Manager,安装google play services. 步骤2: ...
- Google Map API v2 (三)----- 地图上添加标记(Marker),标记info窗口,即指定经纬度获取地址字符串
接上篇 http://www.cnblogs.com/inkheart0124/p/3536322.html 1,在地图上打个标记 private MarkerOptions mMarkOption; ...
- Google Map API V2密钥申请
之前用的都是v1,用的是MapView,好吧,仅仅能认命了.废话不再多说,開始android 的Google Maps Android API v2吧 之前參考了http://www.cnblogs. ...
- Google Map API v2 (四)----- 导航路径
仍然是建议个异步小任务 private GetPathTask mGetPathTask = null; private void getGuidePath(LatLng origin){ if(mG ...
- Google Map API v2 番外篇 关于gps位置偏差及修正方法探讨
我的手机是M35C,在我自己的map activity中,通过gps获取到的经纬度比实际地址总是有500米左右的偏差. 在网上搜索了很多,都说这个是测绘局为了保密故意弄成这样的.gps全球定位系统获得 ...
- Google Map API V3开发(1)
Google Map API V3开发(1) Google Map API V3开发(2) Google Map API V3开发(3) Google Map API V3开发(4) Google M ...
- Google Map API V3开发(4)
Google Map API V3开发(1) Google Map API V3开发(2) Google Map API V3开发(3) Google Map API V3开发(4) Google M ...
随机推荐
- Class类文件结构、类加载机制以及字节码执行
一.Class类文件结构 Class类文件严格按照顺序紧凑的排列,由无符号数和表构成,表是由多个无符号数或其他数据项构成的符合数据结构. Class类文件格式按如下顺序排列: 类型 名称 数量 u ...
- ANDROID_MARS学习笔记_S04_003_用HttpClent发http请求
一.代码 1.xml(1)activity_main.xml <TextView android:layout_width="wrap_content" android:la ...
- Mozilla研究—深入理解mozilla所需的背景知识
mozilla是一个以浏览器为中心的软件平台,它在我们平台中占有重要地位.我们用它来实现WEB浏览器.WAP浏览器.邮件系统.电子书和帮助阅读器等应用程序.为此,我最近花了不少时间去阅读mozilla ...
- VS2008编译器编译出来的文件比mingw编译的要几乎小一半
为什么要在VS2008中使用QT静态编译呢?很简单,因为VS2008编译器编译出来的文件比mingw编译的要几乎小一半. 好了现在我们来做些准备工作,VS2008自然要安装的,然后打上SP1的补丁.然 ...
- 【Xamarin开发 Android 系列 7】 Android 结构基础(下)
原文:[Xamarin开发 Android 系列 7] Android 结构基础(下) *******前期我们不打算进行太深入的东西,省的吓跑刚进门的,感觉门槛高,so,我们一开始就是跑马灯一样,向前 ...
- queue与topic的技术特点对比
1 queue与topic的技术特点对比 Topic Queue 概要 Publish Subscribe messaging 发布订阅消息 Point-to-Point 点对点 有无状态 to ...
- bzoj1034
贪心 尽可能让最强的赢,最弱的赢,都不行则最弱打最强 感性的想,我肯定要尽可能的赢,而且赢的要对等 实在不能赢就拿最小的拼,所谓的田忌赛马策略 由于总分一定,己方最差即己方最好时对方的分数 ..] o ...
- ASP.NET中定制自己的委托和事件参数类
本文笔记选自<庖丁解牛:纵向切入ASP.NET 3.5控件和组件开发技术>一书 一般在实际开发中,对于事件不需要传递数据信息时,像上面的KingTextBox控件的事件,在引发事件时传递的 ...
- calabash-android Win10 入门笔记
参考官方文档:https://developer.xamarin.com/guides/testcloud/calabash/ 概述 Calabash是一个BDD的UI自动化验收测试框架, ...
- ambari的重新安装
ambari是什么呢? 这里我简单说一下ambari的目的,他的目的就是简化hadoop集群的安装和管理.对于安装简化到什么地步呢?只需要几个命令,在页面上配置几个参数,几百几千个节点的集群就能安装成 ...