Google Map API v2 步步为营 (二)----- Location
接上篇。
改造一下MapsActivity:
public class MapsActivity extends Activity implements LocationListener, InfoWindowAdapter, OnMarkerClickListener, OnMarkerDragListener{ }實(shí)現(xiàn)4個(gè)interface:
android.location.LocationListener
GoogleMap.InfoWindowAdapter
GoogleMap.OnMarkerClickListener
GoogleMap.OnMarkerDragListener
本篇要實(shí)現(xiàn)在地圖上定位,主要用到LocationListener接口。
另外3個(gè)接口關(guān)系到 打標(biāo)記(Marker),移動(dòng)標(biāo)記點(diǎn),以及點(diǎn)擊標(biāo)記彈出info窗口。這些功能將在下一篇文中整理。???
?
地圖初始化
首先在onCreate中需要對(duì)地圖對(duì)象做一些設(shè)置:
@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; }上一篇說過,手機(jī)調(diào)試環(huán)境需要安裝Google Play服務(wù)和play store。如果沒有安裝,這里就會(huì)返回錯(cuò)誤碼。
?
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 } 92行,獲得地圖對(duì)象 GoogleMap mMapView;后面很多操作都要通過它。
3行,設(shè)在地圖模式為normal
4行,UiSettings 設(shè)置人機(jī)交互相關(guān)的各種按鈕手勢(shì)等待,例如:
void setTiltGesturesEnabled(boolean)? 是否允許手勢(shì)改變視角;
void setCompassEnabled(boolean)? 是否顯示指南針;
詳細(xì)的UiSettings用法可參考官文 https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/UiSettings
?
移動(dòng)到經(jīng)緯度地點(diǎn)
先闡明一個(gè)概念,Goolge Map假定地圖本身是固定不動(dòng)的,移動(dòng)的是camera(public final class CameraUpdate)。
想象一下,在地球上空漂浮著一只佳能無敵兔,把鏡頭對(duì)準(zhǔn)魔都,焦距拉近看到了一號(hào)線,再拉遠(yuǎn),視角傾斜一下,看到了魔都全貌,還是帶廣角的。不錯(cuò)吧!
?
回到代碼,這里需要用的GPS。通過LocationManager來獲得位置服務(wù)
mLocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); mGPSOk = mLocManager.isProviderEnabled(LocationManager.GPS_PROVIDER);獲得LocationManager,并檢查GPS是否可用。
在onResume函數(shù)中注冊(cè)監(jiān)聽
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行,注冊(cè)位置變化監(jiān)聽。第二入?yún)?*1000表示每隔5秒更新一次,第三入?yún)⒈硎疽苿?dòng)超過1米更新一次。最后一個(gè)入?yún)⒓碙ocationListener,由于activity implement了LocationListener,所以這里只需要給activity的this指針。
12行和13行的兩個(gè)函數(shù),用于主動(dòng)獲取最新位置,移動(dòng)地圖到該位置,稍后貼出。
先看一下位置變化的監(jiān)聽函數(shù),activity在implement了LocationListener后 需要實(shí)現(xiàn)一下幾個(gè)函數(shù):
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,這個(gè)函數(shù)在location發(fā)生變化時(shí)會(huì)調(diào)用到。
我們用了一個(gè)私有數(shù)據(jù):private Location mLocation = null;
在onLocationChanged函數(shù)中,把新的location保存到mLocation中,然后調(diào)用animateLatLng把地圖移動(dòng)到該位置。
=================================================================
mLocation用于記錄每次更新的經(jīng)緯度,建議在onPause的時(shí)候把這個(gè)數(shù)據(jù)保存到本地,我是保存在preference中的。在onResume時(shí)讀出來。
這樣可以避免gps不可用的時(shí)候,地圖飛回非洲。
當(dāng)然也可一增加一個(gè)對(duì)network provider的監(jiān)聽,通過網(wǎng)絡(luò)獲取不太準(zhǔn)確的位置,這部份我沒做完整。
因?yàn)榛鹦亲鴺?biāo)系的問題,我最后換了baidu map,google map的這個(gè)apk很多后續(xù)的優(yōu)化就沒做了,汗吧!
=================================================================
有時(shí)我們需要主動(dòng)查詢最新的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行,獲取最優(yōu)的provider
7行,獲取最近一次的location
8~16行,同樣的,新位置記錄到mLocation中。
getBestProvider函數(shù)體如下:
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;
}
?
上文用到的兩個(gè)函數(shù)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 }?
先看第一個(gè)setLatLng():
7~8行,從mLocation中調(diào)用getLatitude()取得維度,getLongitude()取得經(jīng)度。
12行,構(gòu)造一個(gè)LatLng對(duì)象
16行, mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 15));
CameraUpdateFactory.newLatLngZoom(latlng, 15) 返回一個(gè)CameraUpdate對(duì)象,入?yún)⑹墙?jīng)緯度和zoom level;
GoogleMap的moveCamera方法把地圖移動(dòng)到該位置。
animateLatLng()函數(shù)
31行? 基本相同,唯一的區(qū)別是最后調(diào)用的是animateCamera,我們會(huì)看到地圖從原location移動(dòng)到新location的過程。而moveCamera方法是瞬移過去的,不會(huì)看到移動(dòng)過程。
CameraUpdate有很多中構(gòu)造方法,可以單獨(dú)或同時(shí)指定位置和放大倍數(shù)。指定邊界等待,詳見
https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/CameraUpdateFactory
?
?
最后,要在onPause函數(shù)中注銷位置服務(wù)監(jiān)聽
mLocManager.removeUpdates(this);
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/inkheart0124/p/3536322.html
總結(jié)
以上是生活随笔為你收集整理的Google Map API v2 步步为营 (二)----- Location的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7款Flash和Javascript网页
- 下一篇: 各种OS间文件传输