Posts match “ 目前位置 ” tag:

需求

今天要來講Android如何定位取得目前位置後,並且在Google Map上顯示,這是一個看似蠻簡單的範例,但是定位在StackOverflow上面一堆寫法,看了眼花撩亂,這邊是我最後可以完美運作的版本。

思路

  • Google Map如何導入在專案內就請自行參考Google Map Android API - Get Started
  • 手機的GPS和網路皆可以定位,有時候使用者不一定會開啟GPS,所以我們採用兩個定位方式依序取得位置。
  • 在取得定位並且設定好Google Map後,我們就可以把目前位置顯示在地圖上了,就這麼簡單而已。

你也許會問,為何我需要使用GPS和網路定位?
原因有三個:

  1. 使用者不一定會開GPS或網路。
  2. GPS跟Network的精準度也不一。
  3. 兩者取得位置的速度兩者也不同。

程式碼實作

  1. res/layout/activity_main.xml加入MapView

    <com.google.android.gms.maps.MapView
        android:id="@+id/mapview"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        map:cameraZoom="13"
        />
    
  2. Activity新增兩個Instance Variable,並且在onCreate()初始化Google Map。

@Bind(R.id.mapview)
MapView mMapView;
private GoogleMap mGoogleMap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    /* 其他既有程式略 */
    ButterKnife.bind(this); /* 使用ButterKnife做View Injection */
    mMapView.onCreate(savedInstanceState); /* 初始化MapView */
    mGoogleMap = mMapView.getMap();
    int googlePlayStatus = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (googlePlayStatus != ConnectionResult.SUCCESS) {
        GooglePlayServicesUtil.getErrorDialog(googlePlayStatus, this, -1).show();
        finish();
    } else {
        /* 設定地圖 */
        if (mGoogleMap != null) {
            mGoogleMap.setMyLocationEnabled(true); 
            mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
            mGoogleMap.getUiSettings().setAllGesturesEnabled(true);
        }
    }
}
  1. 新增LocationListener的Instance Variable,目的用來監聽取得更新位置後的動作。
private LocationListener mLocationListener = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        if (location != null) {
            Logger.d(String.format("%f, %f", location.getLatitude(), location.getLongitude()));
            drawMarker(location);
            mLocationManager.removeUpdates(mLocationListener);
        } else {
            Logger.d("Location is null");
        }
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {
    }

    @Override
    public void onProviderEnabled(String s) {
    }
  
    @Override
    public void onProviderDisabled(String s) {
    }
};
  1. 重頭戲來了,取得目前位置的實作,我們由網路和GPS來取得定位,因為GPS精準度比網路來的更好,所以先使用網路定位、後續再用GPS定位,如果兩者皆無開啟,則跳無法定位的錯誤訊息。
private void getCurrentLocation() {
    boolean isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    boolean isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    Location location = null;
    if (!(isGPSEnabled || isNetworkEnabled))
        Snackbar.make(mMapView, R.string.error_location_provider, Snackbar.LENGTH_INDEFINITE).show();
    else {
        if (isNetworkEnabled) {
            mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                    LOCATION_UPDATE_MIN_TIME, LOCATION_UPDATE_MIN_DISTANCE, mLocationListener);
            location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }

        if (isGPSEnabled) {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                    LOCATION_UPDATE_MIN_TIME, LOCATION_UPDATE_MIN_DISTANCE, mLocationListener);
            location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        }
    }
    if (location != null)
        drawMarker(location);
}

/* 在Google Map上放上目前位置的地標圖示。 */
private void drawMarker(Location location) {
    if (mGoogleMap != null) {
        mGoogleMap.clear();
        LatLng gps = new LatLng(location.getLatitude(), location.getLongitude());
        mGoogleMap.addMarker(new MarkerOptions()
                .position(gps)
                .title("Current Position"));
        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(gps, 12));
    }
}

最後完整程式碼大家可以自行取用,謝謝各位。
我是大白,有任何問題歡迎在FB訊息敲來問我,請大家多多支持。