1.獲取當前地理位置:java
Android中提供了一個LocationManager的類,用於管理地理位置。不能經過構造函數獲取該類的實例,而是經過Context的getSystemService():android
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
該類中有幾個比較經常使用的方法:git
getLastKnownLocation(String provider)用於根據傳入的provider獲取一個Location對象,該對象存儲了地理位置信息,包括經度、緯度、海拔、速度等。provider指明採用何種方式獲取地理位置信息,在LocationManager中定義了幾個字符串常量,用於指定地理位置信息的提供者:網絡
NETWORK_PROVIDER:採用網絡的方式獲取ide
GPS_PROVIDER:採用GPS獲取函數
PASSIVE_PROVIDER:被動定位方式,當其餘應用使用定位更新了定位信息,系統會保存下來,該應用接收到消息後直接讀取就能夠了佈局
注意:在使用真機測試時,必定要走到室外。由於經常使用的定位方式是GPS或者NETWORK,可是在室內這兩個基本沒起做用,我剛開始還覺得是代碼的問題,後來走出去測試才發現代碼沒有問題。測試
獲取地理位置信息以前,最好先查看下手機支持哪些定位方式,哪些是可用的,而後再選擇一個可用的來定位:動畫
getAllProviders()返回全部的地理位置提供者的全部字符串描述ui
getBestProvider()根據傳入的評判準則,返回一個最佳的地理位置提供者的字符串描述,第二個參數設置爲true,則返回全部可用中的最佳的;若爲false則返回最佳的,無論是否可用。
getProviders()返回地理位置提供者的字符串描述,參數爲true,則返回全部的可用的描述,false則返回全部的。
getProviders()根據傳入的評判準則,及第二個參數標識是否可用,來返回地理位置提供者的字符串描述。
1 List<String> providers = lm.getProviders(true); 2 3 for(int i=0; i<providers.size();i++){ 4 5 System.out.println(providers.get(i)); 6 7 }
當前是GPS和PASSIVE方式可用:
1 List<String> providers = lm.getProviders(true); 2 3 String lp = null; 4 5 if(providers.contains(LocationManager.GPS_PROVIDER)){ 6 7 lp = LocationManager.GPS_PROVIDER; 8 9 }else if(providers.contains(LocationManager.NETWORK_PROVIDER)){ 10 11 lp = LocationManager.NETWORK_PROVIDER; 12 13 }else{ 14 15 Toast.makeText(this, "當前沒有獲取地理位置的方式可用,請打開GPS", Toast.LENGTH_LONG).show(); 16 17 return; 18 19 } 20 21 Location loc = lm.getLastKnownLocation(lp);
獲取了Location實例,就能夠從中獲取關心的地理信息了:
getLatitude():獲取緯度信息,單位度
getLongitude():獲取經度信息,單位度
getAltitude():獲取海拔信息,單位米
getSpeed():獲取速度信息,單位米/秒
getTime():獲取時間信息,返回從1970.1.1到如今的毫秒數。
如:
Toast.makeText(MainActivity.this, "緯度:"+location.getLatitude() +",經度:"+location.getLongitude()+",速度:"+location.getSpeed()+"m/s," +"海拔:"+location.getAltitude()+"米", 0).show();
以上,只能獲取一次地理位置信息,如何動態實時地獲取地理位置信息呢?
這就要用到LocationManager的requestLocationUpdates()方法:
該方法有多重重載形式,這裏只簡單試用下這種重載形式,參數說明:
provider:指定獲取地理位置的方式;
minTime:指定監聽位置變化的時間間隔,單位毫秒;
minDistance:指定監聽位置變化的最小距離間隔,單位米;
listener:指定監聽器,設置不一樣事件的回調處理。
注意:註冊了監聽器以後,但應用退出時,應當將註冊的監聽器移除,能夠選擇在Activity的onDestroy()方法中,調用LocationManager的removeUpdates(listener)方法,來將requestLocationUpdates()註冊的事件監聽移除。
如:
1 listener = new LocationListener() { 2 3 4 5 @Override 6 7 public void onStatusChanged(String provider, int status, Bundle extras) { 8 9 // TODO Auto-generated method stub 10 11 Toast.makeText(MainActivity.this, "onStatusChanged", 0).show(); 12 13 } 14 15 16 17 @Override 18 19 public void onProviderEnabled(String provider) { 20 21 // TODO Auto-generated method stub 22 23 Toast.makeText(MainActivity.this, "onProviderEnabled", 0).show(); 24 25 } 26 27 28 29 @Override 30 31 public void onProviderDisabled(String provider) { 32 33 // TODO Auto-generated method stub 34 35 Toast.makeText(MainActivity.this, "onProviderDisabled", 0).show(); 36 37 } 38 39 40 41 @Override 42 43 public void onLocationChanged(Location location) { 44 45 // TODO Auto-generated method stub 46 47 tv_lat.setText(location.getLatitude()+""); 48 49 tv_lng.setText(location.getLongitude()+""); 50 51 Toast.makeText(MainActivity.this, "緯度:"+location.getLatitude() 52 53 +",經度:"+location.getLongitude()+",速度:"+location.getSpeed()+"m/s," 54 55 +"海拔:"+location.getAltitude()+"米", 0).show(); 56 57 } 58 59 }; 60 61 lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 1, listener);
每隔5秒監測下位置的變化狀況,一旦距離變化超過1米,就會回調onLocationChanged()方法,並將新的Location實例做爲參數傳入該方法。
以上,就是簡單的獲取地理位置的方法,幫助文檔中關於LocationManager還有其餘一些可能也會用到的方法,如臨近警告,測距等,在用到的時候能夠再查閱。
2.百度地圖控制器的簡單使用,設置地圖的旋轉,縮放,及視角變化:
跟2.x版本不一樣,以前在控制器中直接就能夠調用各個方法進行旋轉、縮放等操做,新版的控制器類名爲BaiduMap,這裏要用到的是它的animateMapStatus()方法:
全部要執行的旋轉、縮放等動做沒有直接對應的方法,而是把這些地圖狀態變化的動做封裝到MapStatusUpdate對象中,而後傳遞給BaiduMap的animateMapStatus()以動畫的方式執行動做。
因此,這裏的關鍵是獲取MapStatusUpdate對象,封裝要執行的動做。
可是,查看幫助文檔中,MapStatusUpdate類沒有任何實際的幫助信息……
可是,有幾個相關的類:MapStatus、MapStatus.Builder、MapStatusUpdateFactory。
首先看MapStatus:
有這麼幾個字段,用於存放地圖狀態信息,注意文檔中說明zoom的取值範圍爲3-20,overlook的取值是-45-0。可是沒有對應的設置方法,因此猜想應該在其內部類Builder中存在相關設置方法
MapStatus.Builder:
構造方法,第二個帶參的構造應該會比較有用,要進行地圖狀態變化,確定要有一個參照,是在當前狀態基礎之上進行旋轉縮放等。
build()方法返回一個MapStatus對象,如同以前經常使用到的android中的Builder內部類同樣,在進行完一連串的設置以後,最後調用該方法獲得一個須要的MapStatus對象。
overlook()方法,設置地圖視角,傳入一個-45~0的float值
rotate()方法,設置逆時針旋轉角度
target()方法,設置地圖中心店
targetScreen()方法設置地圖中心點在屏幕的座標
zoom()方法,設置地圖的縮放級別。
經過MapStatus.Builder就能獲取一個MapStatus對象了,可是須要的倒是MapStausUpdate對象。
繼續看下一個類:
MapStatusUpdateFactory類:
MapStatusUpdate的工廠類,經過它能夠獲取到須要的MapStatusUpdate對象:
newMapStatus()方法,能夠根據傳入的MapStatus獲取一個MapStatusUpdate對象;
zoomIn()方法:返回一個放大地圖縮放級別的MapStatusUpdate對象
zoomOut()方法:返回一個縮小地圖縮放級別的MapStatusUpdate對象
zoomTo()方法:返回一個到指定縮放級別的MapStatusUpdate對象
下面根據這幾個類,試着進行地圖的旋轉、縮放、設置中心點及視角變化:
1)設置縮放級別:
修改佈局文件,在MapView下方添加幾個控件,用於控制地圖縮放:
1 <LinearLayout 2 3 android:orientation="horizontal" 4 5 android:layout_width="match_parent" 6 7 android:layout_height="wrap_content" 8 9 > 10 11 <EditText 12 13 android:id="@+id/et_level" 14 15 android:layout_height="wrap_content" 16 17 android:layout_width="0dp" 18 19 android:layout_weight="1" 20 21 android:inputType="number" 22 23 android:hint="@string/et_hint" 24 25 /> 26 27 <Button 28 29 android:id="@+id/btn_set" 30 31 android:layout_height="wrap_content" 32 33 android:layout_width="0dp" 34 35 android:layout_weight="1" 36 37 android:onClick="zoomTo" 38 39 android:text="@string/btn_set_text" 40 41 /> 42 43 <Button 44 45 android:id="@+id/btn_in" 46 47 android:layout_height="wrap_content" 48 49 android:layout_width="0dp" 50 51 android:layout_weight="1" 52 53 android:onClick="zoomIn" 54 55 android:text="@string/btn_text_in"/> 56 57 <Button 58 59 android:id="@+id/btn_out" 60 61 android:layout_height="wrap_content" 62 63 android:layout_width="0dp" 64 65 android:layout_weight="1" 66 67 android:onClick="zoomOut" 68 69 android:text="@string/btn_out_text" 70 71 /> 72 73 </LinearLayout>
修改MainActivity.java添加按鈕回調方法:
1 public class MainActivity extends Activity { 2 3 private static final String TAG = "MainActivity"; 4 5 private EditText et_level; 6 7 private Button btn_set, btn_in, btn_out; 8 9 private MapView mv; 10 11 private BaiduMap map; 12 13 @Override 14 15 protected void onCreate(Bundle savedInstanceState) { 16 17 super.onCreate(savedInstanceState); 18 19 SDKInitializer.initialize(getApplicationContext()); 20 21 setContentView(R.layout.activity_main); 22 23 mv = (MapView) findViewById(R.id.mv); 24 25 et_level = (EditText) findViewById(R.id.et_level); 26 27 map.setOnMapLoadedCallback(new OnMapLoadedCallback() { 28 29 @Override 30 31 public void onMapLoaded() { 32 33 mv.setScaleControlPosition(new Point(20,20)); 34 35 mv.setZoomControlsPosition(new Point(150,50)); 36 37 } 38 39 }); 40 41 } 42 43 public void zoomTo(View view){ 44 45 try { 46 47 String s_level = et_level.getText().toString(); 48 49 float level = Float.parseFloat(s_level); 50 51 MapStatusUpdate zt = MapStatusUpdateFactory.zoomTo(level); 52 53 map.animateMapStatus(zt); 54 55 } catch (NumberFormatException e) { 56 57 Toast.makeText(this, "請輸入正確的縮放級別", Toast.LENGTH_SHORT).show(); 58 59 } 60 61 } 62 63 public void zoomIn(View view){ 64 65 MapStatusUpdate zi = MapStatusUpdateFactory.zoomIn(); 66 67 map.animateMapStatus(zi); 68 69 } 70 71 public void zoomOut(View view){ 72 73 MapStatusUpdate zo = MapStatusUpdateFactory.zoomOut(); 74 75 map.animateMapStatus(zo); 76 77 } 78 79 @Override 80 81 protected void onResume() { 82 83 // TODO Auto-generated method stub 84 85 super.onResume(); 86 87 mv.onResume(); 88 89 } 90 91 @Override 92 93 protected void onPause() { 94 95 // TODO Auto-generated method stub 96 97 super.onPause(); 98 99 mv.onPause(); 100 101 } 102 103 @Override 104 105 protected void onDestroy() { 106 107 // TODO Auto-generated method stub 108 109 super.onDestroy(); 110 111 mv.onDestroy(); 112 113 } 114 115 }
運行效果:
2)設置地圖中心點:
map.animateMapStatus(MapStatusUpdateFactory.newLatLng(new LatLng(30.757, 103.9339)));
運行結果:
3)旋轉地圖:
修改佈局文件,添加一個旋轉按鈕:
1 <Button 2 3 android:id="@+id/btn_rot" 4 5 android:layout_width="0dp" 6 7 android:layout_height="wrap_content" 8 9 android:layout_weight="1" 10 11 android:onClick="rotate" 12 13 android:text="@string/btn_rot_text" 14 15 />
修改MainActivity.java,添加旋轉按鈕的回調:
1 public void rotate(View view){ 2 3 float r = map.getMapStatus().rotate; 4 5 MapStatus ms = new MapStatus.Builder(map.getMapStatus()).rotate(r+30).build(); 6 7 map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(ms)); 8 9 }
運行結果:
4)設置視角:
修改佈局文件:
1 <Button 2 3 android:id="@+id/btn_up" 4 5 android:layout_height="wrap_content" 6 7 android:layout_width="0dp" 8 9 android:layout_weight="1" 10 11 android:onClick="overlook" 12 13 android:text="@string/btn_up_text"/> 14 15 <Button 16 17 android:id="@+id/btn_down" 18 19 android:layout_height="wrap_content" 20 21 android:layout_width="0dp" 22 23 android:layout_weight="1" 24 25 android:onClick="overlook" 26 27 android:text="@string/btn_down_text" 28 29 />
修改MainActivity.java:添加修改視角的按鈕的回調:
1 public void overlook(View view){ 2 3 float f = map.getMapStatus().overlook; 4 5 MapStatus ms = null; 6 7 if(view.getId() == R.id.btn_up){ 8 9 ms = new MapStatus.Builder(map.getMapStatus()).overlook(f+10).build(); 10 11 }else{ 12 13 ms = new MapStatus.Builder(map.getMapStatus()).overlook(f-10).build(); 14 15 } 16 17 map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(ms)); 18 19 }
運行結果: