개발하는 두더지

[Android] 구글맵(GoogleMap) 현재위치 따라가기 본문

Java,Android

[Android] 구글맵(GoogleMap) 현재위치 따라가기

덜지 2017. 5. 18. 16:22

Fragment위의 구글맵에서 현재 위치에 마커표시 하는 방법을 알아보겠습니다.


GoogleMap SDK 설치 및 API KEY 발급받기 (  http://duzi077.tistory.com/120 ) 참조


Fragment 구현 ( http://duzi077.tistory.com/119 ) 참조


구글맵 띄우기 ( http://duzi077.tistory.com/121 ) 참조





Google Maps Android API, Google Places API for Android, fused location provider 을 이용해야 합니다.


단말기의 위치정보를 이용하여 구글 맵에서 현재 위치를 표시하는 가이드를 살펴보겠습니다.

소스코드는 제일 하단에 있습니다. ( Activity 구현하시는 분은 가이드를 참고해주시고, Fragment로 구현하시는 분은 하단 소스코드를 참고하시면 됩니다.)



1. Google API Client 생성


Google Play services API Client 인스턴스를 생성해야합니다. 그 인스턴스로 fused location provider 와 Google Places API에 연결할 수 있습니다.

private GoogleApiClient mGoogleApiClient;



Activity 의 onCreate() 에 객체를 초기화 합니다.

@Override
protected void onCreate(Bundle savedInstanceState) {
   
super.onCreate(savedInstanceState);

   
// Do other setup activities here too, as described elsewhere in this tutorial.

   
// Build the Play services client for use by the Fused Location Provider and the Places API.
   
// Use the addApi() method to request the Google Places API and the Fused Location Provider.
    mGoogleApiClient
= new GoogleApiClient.Builder(this)
           
.enableAutoManage(this /* FragmentActivity */,
                   
this /* OnConnectionFailedListener */)
           
.addConnectionCallbacks(this)
           
.addApi(LocationServices.API)
           
.addApi(Places.GEO_DATA_API)
           
.addApi(Places.PLACE_DETECTION_API)
           
.build();
    mGoogleApiClient
.connect();
}

Fragment의 경우 getActivity() 를 쓰면  Activity의 this 처럼 사용할 수 있습니다.





2.  위치 권한 요청


디바이스의 위치를 받기위해 반드시 위치 권한을 요청해야 합니다. 


manifest 에 추가합니다.


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   
package="com.example.currentplacedetailsonmap">
   
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>




3. 앱에 런타임 퍼미션 요청


private void getDeviceLocation() {
   
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
            android
.Manifest.permission.ACCESS_FINE_LOCATION)
           
== PackageManager.PERMISSION_GRANTED) {
        mLocationPermissionGranted
= true;
   
} else {
       
ActivityCompat.requestPermissions(this,
               
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION
);
   
}
   
// A step later in the tutorial adds the code to get the device location.
}



4. 콜백 메서드 오버라이드

@Override
public void onRequestPermissionsResult(int requestCode,
                                       
@NonNull String permissions[],
                                       
@NonNull int[] grantResults) {
    mLocationPermissionGranted
= false;
   
switch (requestCode) {
       
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
           
// If request is cancelled, the result arrays are empty.
           
if (grantResults.length > 0
                   
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                mLocationPermissionGranted
= true;
           
}
       
}
   
}
    updateLocationUI
();
}




5. xml에 구글 맵 추가


<fragment xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:id="@+id/map"
   
android:name="com.google.android.gms.maps.SupportMapFragment"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
tools:context="com.example.currentplacedetailsonmap.MapsActivityCurrentPlace" />


6. 레이아웃 설정


@Override
protected void onCreate(Bundle savedInstanceState) {
   
super.onCreate(savedInstanceState);
    setContentView
(R.layout.activity_maps);
}



7. 구글맵 콜백 인터페이스 추가하고 onMapReady() 오버라이드


public class MapsActivityCurrentPlace extends AppCompatActivity
       
implements OnMapReadyCallback,
               
GoogleApiClient.ConnectionCallbacks,
               
GoogleApiClient.OnConnectionFailedListener {
   
/**
     * Manipulates the map when it's available.
     * This callback is triggered when the map is ready to be used.
     */

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

       
// Do other setup activities here too, as described elsewhere in this tutorial.

       
// Turn on the My Location layer and the related control on the map.
        updateLocationUI
();

       
// Get the current location of the device and set the position of the map.
        getDeviceLocation
();
   
}
}



8. onConnected() 함수 구현

/**
 * Builds the map when the Google Play services client is successfully connected.
 */

@Override
public void onConnected(Bundle connectionHint) {
   
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
           
.findFragmentById(R.id.map);
    mapFragment
.getMapAsync(this);
}



9. 위치 권한 설정 여부에따라 구글맵에 디바이스의 위치를 설정


private void updateLocationUI() {
   
if (mMap == null) {
       
return;
   
}

   
/*
     * Request location permission, so that we can get the location of the
     * device. The result of the permission request is handled by a callback,
     * onRequestPermissionsResult.
     */

   
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
            android
.Manifest.permission.ACCESS_FINE_LOCATION)
           
== PackageManager.PERMISSION_GRANTED) {
        mLocationPermissionGranted
= true;
   
} else {
       
ActivityCompat.requestPermissions(this,
               
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION
);
   
}

   
if (mLocationPermissionGranted) {
        mMap
.setMyLocationEnabled(true);
        mMap
.getUiSettings().setMyLocationButtonEnabled(true);
   
} else {
        mMap
.setMyLocationEnabled(false);
        mMap
.getUiSettings().setMyLocationButtonEnabled(false);
        mLastKnownLocation
= null;
   
}
}



10. 디바이스의 위치정보를 얻어서 맵 이동하기

private void getDeviceLocation() {
   
/*
     * Before getting the device location, you must check location
     * permission, as described earlier in the tutorial. Then:
     * Get the best and most recent location of the device, which may be
     * null in rare cases when a location is not available.
     */

   
if (mLocationPermissionGranted) {
        mLastKnownLocation
= LocationServices.FusedLocationApi
               
.getLastLocation(mGoogleApiClient);
   
}

   
// Set the map's camera position to the current location of the device.
   
if (mCameraPosition != null) {
        mMap
.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition));
   
} else if (mLastKnownLocation != null) {
        mMap
.moveCamera(CameraUpdateFactory.newLatLngZoom(
               
new LatLng(mLastKnownLocation.getLatitude(),
                        mLastKnownLocation
.getLongitude()), DEFAULT_ZOOM));
   
} else {
       
Log.d(TAG, "Current location is null. Using defaults.");
        mMap
.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
        mMap
.getUiSettings().setMyLocationButtonEnabled(false);
   
}
}



11. 현재 위치 얻기

private void showCurrentPlace() {
   
if (mMap == null) {
       
return;
   
}

   
if (mLocationPermissionGranted) {
       
// Get the likely places - that is, the businesses and other points of interest that
       
// are the best match for the device's current location.
       
@SuppressWarnings("MissingPermission")
       
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
               
.getCurrentPlace(mGoogleApiClient, null);
        result
.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
           
@Override
           
public void onResult(@NonNull PlaceLikelihoodBuffer likelyPlaces) {
               
int i = 0;
                mLikelyPlaceNames
= new String[mMaxEntries];
                mLikelyPlaceAddresses
= new String[mMaxEntries];
                mLikelyPlaceAttributions
= new String[mMaxEntries];
                mLikelyPlaceLatLngs
= new LatLng[mMaxEntries];
               
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
                   
// Build a list of likely places to show the user. Max 5.
                    mLikelyPlaceNames
[i] = (String) placeLikelihood.getPlace().getName();
                    mLikelyPlaceAddresses
[i] = (String) placeLikelihood.getPlace().getAddress();
                    mLikelyPlaceAttributions
[i] = (String) placeLikelihood.getPlace()
                           
.getAttributions();
                    mLikelyPlaceLatLngs
[i] = placeLikelihood.getPlace().getLatLng();

                    i
++;
                   
if (i > (mMaxEntries - 1)) {
                       
break;
                   
}
               
}
               
// Release the place likelihood buffer, to avoid memory leaks.
                likelyPlaces
.release();

               
mMap.addMarker(new MarkerOptions()
               
.title(LikelyPlaceNames[0])

                .position(new LatLng(LikelyLatLngs[0].latitude, LikelyLatLngs[0].longitude));

                .snippet(LikelyAddresses[0]);

            }
       
});
   
} else {
       
// Add a default marker, because the user hasn't selected a place.
        mMap
.addMarker(new MarkerOptions()
               
.title(getString(R.string.default_info_title))
               
.position(mDefaultLocation)
               
.snippet(getString(R.string.default_info_snippet)));
   
}
}




전체 소스 코드



fragment_fragment1.xml

Fragment1.java

Comments