接上篇。

改造一下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相关推荐

  1. 关于Google Map API V2 版本的定位与导航

    近来,在关注安卓手机上的GoogleMap应用的开发,但是目前官方API版本网页版已经升级到V3版,而对于Android的支持也已经升级到V2版本,虽然Google说继续对V1版提供服务,但是不再提供 ...

  2. Google Map API v2的定位

    昨天刚开始看LBS相关的东西,搜了下发现几个问题:一个是时效性的问题,很多发表时间还算近的 内容写的却是V1的,很容易让我们这些菜鸟走更多的弯路:另一个是知识面的,发现有太多太多相同的文章 都在写一个 ...

  3. Google Map API v2 (三)----- 地图上添加标记(Marker),标记info窗口,即指定经纬度获取地址字符串...

    接上篇 http://www.cnblogs.com/inkheart0124/p/3536322.html 1,在地图上打个标记 1 private MarkerOptions mMarkOptio ...

  4. android Google Map API V2 (key 申请)

    要使用V2 的API,需要到Google APIs Console将Google Maps Android API v2服务开启(前提是你已经拥有Google帐号,并创建一个项目),见图: 然后用ke ...

  5. google map Api接口整理

    Google Map Api接口整理 一:基本知识: 1. 使用谷歌地图 API 的第一步就是要注册一个 API 密钥,需要注意一下两点: 1.如果使用 API 的页面还没有发布,只是在本地调试,可以 ...

  6. Android传感器、语音识别、定位系统、Google Map API、快捷方式、widget编程总结及示例

    Android特色开发 第一部分 传感器    传感器是一种物理装置或生物器官,能够探测.感受外界的信号.物理条件(如:光.热.湿度)或化学组成(如:烟雾),并将探知的信息传递给其他设备或器官.    ...

  7. Android传感器、语音识别、定位系统、Google Map API、快捷方式、widget编程总结及示例...

    Android特色开发 第一部分 传感器 传感器是一种物理装置或生物器官,能够探测.感受外界的信号.物理条件(如:光.热.湿度)或化学组成(如:烟雾),并将探知的信息传递给其他设备或器官. Andro ...

  8. Google Map Api for Android

    Google Map Api for Android 项目需要使用了谷歌的地图api,总结一下. 先上几个图 一.项目介绍 1.点击搜索附近的公园 这个展示的可以点击地图的任意位置获取经纬度,并标记M ...

  9. 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 ...

最新文章

  1. 关闭windows窗口时操作
  2. 蓝桥杯入门 (二)
  3. c#连接远程sqlserver2008_C#用代码控制网络断开与重连
  4. 汇编语言串指令经典题目
  5. ElasticSearch重启策略
  6. html搜索结果 重置,搜索结果和后退按钮/ HTML表格
  7. 快学Scala 第二课 (apply, if表达式,循环,函数的带名参数,可变长参数,异常)...
  8. java 可能尚未初始化变量,java - 局部变量“变量”可能尚未初始化-Java - 堆栈内存溢出...
  9. 1560F1. Nearest Beautiful Number (easy version)
  10. 数据库-MySQL中间的注释
  11. asyu中datagrid load 与reload
  12. 苹果电脑mysql_MacBook 安装 MySQL 5.7.29(新手都看得懂的安装教程)
  13. HDU 6070 线段树
  14. C++之客户消费积分管理系统
  15. 云计算淡定从容的大局观
  16. 2022-12-24 三阶魔方完整教程和口诀速记,二级魔方教程
  17. 【★】生成树算法终极解析!
  18. 信息精准智能推送(push)的五个关键
  19. 用matlab做矩阵变换(理解+实践);假设随机发给某班所有同学任意数字,生成10*5的矩阵
  20. 修改Thinkphp-cmf上传视频大小限制

热门文章

  1. 程序运行依赖的重要文件版本不对_Deno核心模块:灵活依赖amp;安全沙箱
  2. SUID + SGID + STICKY
  3. dedecms模版php,好织梦-专业dedecms模板,dede模板,织梦模板下载平台
  4. vue.js 默认选中select_vue.js 解决v-model让select默认选中不生效的问题
  5. 学习笔记-----关于C++中类的成员函数可以访问私有成员的问题
  6. ansible(5)——使用通配符操作ansible命令
  7. 包含Iphlpapi.h 编译错误 error C2065: 'HRASCONN'
  8. 和菜鸟一起学linux内核源码之基础准备篇
  9. 计算器服务端/客户端
  10. facenet + Mtcnn 实现人脸识别(实现步骤)