2012年8月20日 星期一

第一支 Android App 上架,從無到有的全記錄 (3)

先再幫自己工商服務一下...

https://play.google.com/store/apps/details?id=com.lancelot.privatelocationdatabase

接著前兩篇的內容。

可以載入地圖之後,下一個要做的事,就是抓到我們的位置,還有,把地圖移到我們所在的位置上。

我們需要的是 LocationManager, LocationListener, 還有 MapController。

LocationManager 的作用是定位我們現在的位置,然後再將定位的結果傳喚給 LocationListener。不過呢,LocationListener 是一個抽象類別,需要我們自己去繼承實做,主要要實做 onLocationChanged 這個函式。

所以,我們先建立一個 GeoUpdateListener 類別。

public class GeoUpdateListener implements LocationListener {

    MapController m_MapController;
    GeoPoint m_geoCurrentLoc;
    MainActivity m_Activity;
   
    public GeoUpdateListener(MainActivity activity, MapController map_controller)
    {
        m_MapController = map_controller;
        m_Activity = activity;
    }
    public void onLocationChanged(Location location) {
        // TODO Auto-generated method stub
        int lat = (int) (location.getLatitude() * 1E6);
        int lng = (int) (location.getLongitude() * 1E6);
        m_geoCurrentLoc = new GeoPoint(lat, lng);
        m_MapController.animateTo(m_geoCurrentLoc);
    }

    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

}

onLocationChanged 的程式碼很簡單,就是把取得來的位置,經緯度轉換成 MapController 能用的整數格式,生成 GeoPoint 物件後,交給 MapController,MapController 就會把地圖移動到我們指定的位置上。

接著改 Main Activity。

加入幾個 Private 變數。

private MapController m_MapController;
private MapView m_MapView;
private LocationManager m_LocationManager;
private GeoUpdateListener m_GeoUpdateListener;

在 Main Activity 的 onCreate函式裡,加入 Location Manager, Geo Update Listener, 取得 Map View, Map Controller。

        m_MapView = (MapView)findViewById(R.id.mapview);
        m_MapView.setBuiltInZoomControls(true);
        //m_MapView.setSatellite(true);
       
        m_MapController = m_MapView.getController();
        m_MapController.setZoom(14); // Zoom 1 is world view
       
        m_GeoUpdateListener = new GeoUpdateListener(this, m_MapController);
       
        m_LocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        m_LocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000,
                0, m_GeoUpdateListener);
        // also need 3G GPS
        m_LocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000,
                0, m_GeoUpdateListener);

那,從 Code看。

Location Manager 要從 System Service 中取得。

位置的提供者,有兩種,從 GPS 來,以及從手機基地台定位而來。我們可以兩種都用。所以在 requestLocationUpdates 函式裡,會有兩種參數 GPS_PROVIDER & NETWORK_PROVIDER。

同時,我們也告訴Location Manager,位置更新的時候,請呼喚 GeoUpdateListener。

程式就改到這邊。

還有一個地方要更動一下。在 AndroidManifest.xml 裡,要加入兩個 Permission。

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

現在我們可以做測試了。

不過這次,我們想用模擬器來玩。

因為,這個 App 的 Build Target 是 Google API,所以,我們必須要建立一個 Google API 的 模擬器。

image

開啟模擬器之後,跑起 App。

image

但是這樣的東西好像沒有定位的功能呢,怎麼辦?

把 Eclipse IDE 上的 DDMS 打開,有個 Emulator Control 的分頁,可以找到 Location Control 的功能。

image

我們試試看,把 Longitude 改成 –122.08, Latitude 改成 37.42,

image

地圖就改到別的地方啦!!

沒有留言: