2011-11-27

在 Android 裡取得目前的位置(LocationManager)

取得位置的主要 class 是 LocationManager,位置的來源有兩種可能: GPS 或網路(3G 或 WIFI),使用前必須將 GPS 或者網路打開,以我的手機舉例,設定在「設定 > 位置與安全性 > 使用無線網路或者使用 GPS 衛星定位」。

main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  >
    <TextView  
        android:id="@+id/tv"
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      />
</LinearLayout>
LocationActivity
public class LocationActivity extends Activity implements LocationListener {

    private static final String TAG = "LocationActivity";
    private LocationManager locationMgr;
    private TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this.insert2tv("onCreate...");
        // 主角
        this.locationMgr = (LocationManager) this.getSystemService(LOCATION_SERVICE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 取得位置提供者,不下條件,讓系統決定最適用者,true 表示生效的 provider
        String provider = this.locationMgr.getBestProvider(new Criteria(), true);
        if (provider == null) {
            this.insert2tv("沒有 location provider 可以使用");
            return;
        }
        this.insert2tv("取得 provider - " + provider);

        this.insert2tv("requestLocationUpdates...");
        // 註冊 listener,兩個 0 不適合在實際環境使用,太耗電
        this.locationMgr.requestLocationUpdates(provider, 0, 0, this);

        this.insert2tv("getLastKnownLocation...");
        Location location = this.locationMgr.getLastKnownLocation(provider);
        if (location == null) {
            this.insert2tv("未取過 location");
            return;
        }
        this.insert2tv("取得上次的 location");
        this.onLocationChanged(location);
    }

    @Override
    protected void onPause() {
        super.onPause();
        this.insert2tv("removeUpdates...");
        this.locationMgr.removeUpdates(this);
    }

    @Override
    public void onLocationChanged(Location location) {
        this.insert2tv("onLocationChanged...");
        String msg = "經度: " + location.getLongitude() + ", 緯度: "
                + location.getLatitude();
        this.insert2tv(msg);
    }

    private void insert2tv(String msg) {
        if (this.tv == null) {
            this.tv = (TextView) this.findViewById(R.id.tv);
        }
        this.tv.setText(this.tv.getText().toString() + "\n" + msg);
        Log.d(LocationActivity.TAG, msg);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        this.insert2tv("onStatusChanged...");
        // 當 location provider 改變時
    }

    @Override
    public void onProviderEnabled(String provider) {
        this.insert2tv("onProviderEnabled...");
        // 當 location provider 有效時
    }

    @Override
    public void onProviderDisabled(String provider) {
        this.insert2tv("onProviderDisabled...");
        // 當 location provider 無效時
    }
}
最後在 AndroidManifest.xml 裡加上 android.permission.ACCESS_FINE_LOCATION 權限就可以了。

LocationManager 要安裝到手機上才會運作。

實機測試發現,我的 GPS 收不到位置,用 WIFI 的網路方式可以。

2011/11/28 補充
當天稍晚 GPS 就可以收到更新了,也許是第一次使用 GPS 的關係。

沒有留言:

張貼留言