구글맵 사용하기

2020. 12. 9. 12:09 안드로이드/개발 TIP

이전에 구글맵은 LocationManager를 이용하여 gps와 network를 비교하며 사용했다.

이 과정이 복잡하고 처리도 늦어 구글에서 대대적인 개혁을 했으니.

바로 GoogleApiClient를 이용하여 서비스 한다. 


이전의 처리방법

LocationManager locationManager = (LocationManager) context.getSystemService(Activity.LOCATION_SERVICE);

boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGpsEnabled && !isNetworkEnabled) {
gpsAlert(context);
} else {
if(isNetworkEnabled) {
provider = LocationManager.NETWORK_PROVIDER;
locationManager.requestLocationUpdates(provider, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, netListener);
}
if(isGpsEnabled) {
provider = LocationManager.GPS_PROVIDER;
locationManager.requestLocationUpdates(provider, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, gpsListener);
}
}

......중략


그럼 어떻게 바뀌었고 어떻게 사용해야할까?


추가적 설명은 구글 document를 참조

https://developers.google.com/android/guides/setup


  • A compatible Android device that runs Android 2.3 or higher and includes Google Play Store.
  • 진저브레드 이상부터 지원되며 구글플레이스토어가 있어야 합니다.
  • The Android emulator with an AVD that runs the Google APIs platform based on Android 4.2.2 or higher.
  • 안드로이드 AVD를 이용한 에뮬레이터는 키캣이상 버전에서 작동됩니다.


GoogleApiAvailability api = GoogleApiAvailability.getInstance();
int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this);
if (code == ConnectionResult.SUCCESS) {
return true;
} else {
api.getErrorDialog(this, code, 0).show();
return false;
}

우선 GoogleApi를 사용할 수 있는지부터 체크해야한다.


SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.widget_google_map);
mapFragment.getMapAsync(this);

이전에 구글맵은 동기식으로 처리했지만 이제는 OnMapReadyCallback을 이용하여 비동기로 처리할 수 있다.


@Override
public void onMapReady(GoogleMap map) {
googleMap = map;

googleMap.getUiSettings().setMapToolbarEnabled(false);
googleMap.getUiSettings().setRotateGesturesEnabled(false);
googleMap.getUiSettings().setZoomControlsEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.setTrafficEnabled(false);
googleMap.setMyLocationEnabled(true);
googleMap.setOnCameraChangeListener(cameraChangeListener);
}
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(context.getApplicationContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionCallbacks)
.addOnConnectionFailedListener(connectionFailedListener)
.build();

다음으로 GoogleApiClient를 build시킨다.

정상적으로 build한 후에는 mGoogleApiClient.connect로 연결시킨다.


LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

setInteval : 위치가 update되는 주기

setFastestInterval : 위치 획득 후 update되는 주기

Priority는 4가지의 설정값이 있다.

PRIORITY_HIGH_ACCURACY : 배터리소모를 고려하지 않으며 정확도를 최우선으로 고려

PRIORITY_LOW_POWER : 저전력을 고려하며 정확도가 떨어짐

PRIORITY_NO_POWER : 추가적인 배터리 소모없이 위치정보 획득

PRIORITY_BALANCED_POWER_ACCURACY : 전력과 정확도의 밸런스를 고려. 정확도 다소 높음setSmallestDisplacement : 최소 거리 이동시 갱신 가능.


LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
PendingResult result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
if (result != null) {
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult locationSettingsResult) {
listener.onResult(locationSettingsResult);
}
});
}
}

Gps가 꺼져있다면 LocationSettingsRequest로 설정창을 띄울 수 있다.


private LocationSetListener locationSettingsListener = new LocationSetListener() {
@Override
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
GpsManager.getInstance().startLocationUpdates();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
if (status.hasResolution()) {
status.startResolutionForResult(activity, 1000);
}
} catch (IntentSender.SendIntentException e) {

}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
ToastUtil.getInstance().show("unavailiable");
break;
}
}
};

여기서 status.startResolutionForResult(activity, 1000) 는 기본설정창이며 이 부분을 Custom하게 대체할 수 있다.


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((resultCode == Activity.RESULT_OK) && (requestCode == 1000)) {
GpsManager.getInstance().startLocationUpdates();
}
}
onActivityResult로 넘어온 값은 정상적으로 넘어온 값인지를 판단하여 현재 위치를 불러오는 로직을 짜면된다.



- 위치찾는 method 

LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationListener);

- 위치찾기 중지 method

LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationListener);


private LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
GpsManager.getInstance().stopLocationUpdates();
if(null != location) {
double x = location.getLatitude();
double y = location.getLongitude();
moveCamera(x, y);
}
}
};

private void moveCamera(double x, double y){
LatLng latLng = new LatLng(x, y);
cameraPosition = new CameraPosition.Builder().target(latLng).zoom(zoom).build();
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}

requestLocationUpdates를 이용하여 넘어온 location으로 현재 위치로 이동을 시켜주면 된다.


자원이 낭비되는 것을 막기 위해 pause시에는 removeLocationUpdates 해준다.

또한 activity 종료시에는 google client를 disconnect 해준다.



출처: https://akaisun.tistory.com/19?category=622886 [아카이의 개발창고]