2015年9月18日 星期五

Android - 定位

若在你的APP中有使用到地圖的功能,或者是有需要取得使用者位置,你一定會需要定位的功能。

這篇提供簡單的用法,還有說明一些可能會遇到的問題和解法。

以下是完整的定位功能的程式碼,你可以在你任何想使用的時機呼叫,像是onCreate():

   private void locateUser() {  
     LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); // 取得裝置的定位服務  
     String bestProvider = LocationManager.GPS_PROVIDER; // 指定最佳定位是用 GPS 定位  
     Criteria criteria = new Criteria(); // Criteria 會依照裝置的定位設定依狀況幫你取得裝置位置,見備註1  
     bestProvider = locationManager.getBestProvider(criteria, true);  
     Location location = locationManager.getLastKnownLocation(bestProvider); // 取得最後定位到的位置,見備註2  
     if(location != null){  
       LatLng mylocation = new LatLng(location.getLatitude(), location.getLongitude());  
       Marker userMarker = mMap.addMarker(new MarkerOptions()  
         .position(mylocation)  
         .title("UserLocation"));  
       mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mylocation, 15), 1500, null); // 移動到目前位置  
 //      mMap.animateCamera(CameraUpdateFactory.newLatLngZoom("你的位置-LatLng", "畫面涵括範圍"), "移動到指定位置經過的時間", "callback function");  
     }  
   }  

結果長這樣

以上的實作過程大致是這樣:
取得裝置定位功能的服務 -> 指定你需要用什麼方式取得定位(GPS、3G網路、WiFi哪一種) -> 取得裝置位置(LatLng 經緯度的資料) -> 使用取得的位置資料做事情:移動到使用者位置、搜尋附近景點、提供推薦路線等。

在最後的地方,當你取得你的裝置位置資料 - location後,你應該要去判斷是不是空值,因為你有可能會取不到資料!原因可能是下面幾個原因:

1. 你的APP沒有要求位置的權限,應該可以在AS的logcat看到以下的訊息:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.idlefox.mymap/com.idlefox.mymap.MainActivity}: java.lang.IllegalArgumentException: invalid provider: null

所以請到AndroidMenifest.xml加入以下權限:
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>  
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>  

2. 裝置沒有開啟定位功能。

3. 就是抓不到。我之前就是在Sony手機上可以,可是在LG的手機就沒辦法順利抓到,有時要稍微等一下...

4. 還在想...

備註1:
     Criteria criteria = new Criteria(); // Criteria 會依照裝置的定位設定依狀況幫你取得裝置位置,見備註1  
     bestProvider = locationManager.getBestProvider(criteria, true);  

Criteria 是一個很理想定位服務的選擇器,因為定位資料可以透過GPS、網路功能取得,打開你Android手機內建的定位功能就知道。


所以很直覺的就會想說:「那我是不是還要指定取得位置資料要從哪一個方式取得?這樣是不是程式碼要一個一個去檢查,先檢查GPS,如果沒有再看有沒有網路的資料,沒有的話就GG?」
現在可以直接使用Criteria的服務,他會自己幫你選擇裝置內目前精度最好的定位資料。

備註2:
     Location location = locationManager.getLastKnownLocation(bestProvider); // 取得最後定位到的位置,見備註2  

其中你需要注意的地方是,這段程式只會被執行一次,因為你還沒有設定如果位置改變,或者經過多久,你就要重新取得裝置位置的"事件"。

而一般在做定位的APP也只需要在一進入時獲得一次位置資料就好,除非你要提供導航的功能。

github:Android Google Map 定位

沒有留言 :

張貼留言