반응형

GoogleApiClient와 FusedLocationApi를 사용하여 구글맵에 현재 위치를 표시하는 예제입니다.



최종 업데이트 -  2017. 11.27



Deprecated된 FusedLocationApi를 대체하는 FusedLocationProviderClient를 사용하도록 한 포스팅이 추가되었습니다.


Android Google Map에 현재 위치 표시하기( FusedLocationProviderClient 사용)

http://webnautes.tistory.com/1249





1. 구현된 내용


2. 실행 과정 설명


3. 프로그램 흐름


4. 소스 코드


5. 관련 포스팅

   5.1. Google Maps Android API 사용 방법 및 예제

   5.2. Places API Web Service를 사용하여 Android Google Map에 현재 위치 주변의 음식점 표시하기

   5.3. GenyMotion 가상머신에 Google Apps설치하여 Google Maps Android API 테스트 하기




1. 구현된 내용


현재 구현된 내용은 다음과 같습니다.

  • 현재 위치를 지도 상에 마커로 표시해줍니다.

  • 디바이스의 위치 서비스(GPS)가 비활성화 되어 있는 경우 사용자가 활성화하도록 요구합니다.

  • 디바이스의 운영체제 버전이 안드로이드 6.0일 경우에는 위치 관련 퍼미션을 런타임에 요구합니다.

  • 카메라 줌(zoom)을 onMapReady() 메소드에만 지정해주기 때문에 이후에는 사용자가 원하는 줌으로 지도를 볼 수 있습니다.

  • 현재 위치가 변경되면 계속 카메라가 이동하여 현재 위치를 중심으로 지도를 보여주게 됩니다.

  • 사용자가 지도상의 위치를 이동하면  현재 위치 버튼을 누르기 전까지 현재 위치 중심으로 지도 이동이 중단됩니다.  




2. 실행 과정 설명


처음 실행하면 지도의 초기위치를 서울로 이동시키고 위치 정보 사용을 위한 퍼미션 허가를 사용자에게 요청합니다.  

Android 6.0 미만 운영체제를 사용하는 안드로이드 디바이스에서는 보이지 않습니다.




처음 실행하면 안드로이드 디바이스가 현재 위치를 찾는데 시간이 걸립니다.

적절한 조치를 안해주면 아프리카 대륙 옆에 있는 바다가 보입니다.



여러가지 방법이 있지만 저는 서울로 초기위치를 이동시켜주는 방법을 사용했습니다.

onMapReady() 메소드에서 서울로 카메라를 이동시켜줍니다.

그래서 앱에서 GPS가 사용 못하더라도 서울을 보여주게 됩니다.


다른 방법은 마지막에 안드로이드폰이 위치를 인식했던 정보를 가져오는 방법이 있습니다.

아래 링크를 참고하세요..

https://developer.android.com/training/location/retrieve-current.html




위치 서비스가 비활성화되어 있는 경우 활성화 여부를 사용자에게 물어봅니다.





설정을 선택했다면, 위치 정보 설정이 보입니다.

활성화시키고 백버튼을 눌러 앱으로 돌아오면  





현재 위치에 코드에서 추가한 파란색 마커와 구글맵에서 현재 위치를 표시하는데 사용되는 파란색 동그라미가 표시됩니다.





마커를 터치하면 현재 위치의 주소와 좌표가 표시됩니다.





안드로이드 디바이스를 움직이면 현재 위치가 달라짐에 따라 파란색 마커의 위치가 이동하게 됩니다.




2017. 11. 27

현재 위치 마커를 런처 아이콘으로 변경해봤습니다.




아이콘 출처 - https://goo.gl/images/SsXHza




3. 프로그램 흐름


앱을 실행시키면 다음 순서대로 메소드들이 실행됩니다.

(런타임 퍼미션, GPS 활성화를 제외한 상태입니다.)


D/googlemap_example: onCreate

D/googlemap_example: onStart: mGoogleApiClient connect

D/googlemap_example: onMapReady :

D/googlemap_example: onConnected : 퍼미션 가지고 있음

D/googlemap_example: onConnected : call startLocationUpdates

D/googlemap_example: startLocationUpdates : call FusedLocationApi.requestLocationUpdates




이제 일정시간마다 현재 위치를 업데이트합니다.


D/googlemap_example: onLocationChanged :

D/googlemap_example: setCurrentLocation :  mGoogleMap moveCamera 37.7110829 126.906244

D/googlemap_example: onLocationChanged :

D/googlemap_example: setCurrentLocation :  mGoogleMap moveCamera 37.7110829 126.906244

D/googlemap_example: onLocationChanged :

D/googlemap_example: setCurrentLocation :  mGoogleMap moveCamera 37.7110829 126.906244

D/googlemap_example: onLocationChanged :

D/googlemap_example: setCurrentLocation :  mGoogleMap moveCamera 37.7110829 126.906244




백버튼을 눌러서 앱종료시 다음 순서대로 메소드가 실행됩니다.


D/googlemap_example: onStop : call stopLocationUpdates

D/googlemap_example: stopLocationUpdates : call FusedLocationApi.removeLocationUpdates

D/googlemap_example: onStop : mGoogleApiClient disconnect




4. 소스 코드


다음 포스팅을 기반으로 수정합니다.  중복되는 내용은 빠져있습니다.



Google Maps Android API 사용 방법 및 예제

http://webnautes.tistory.com/647

 





1. 매네페스트 파일 AndroidManifest.xml<manifest> 태그 하위요소로 <uses-permission> 태그를 사용하여 위치정보 접근을 위한 퍼미션을 추가해줍니다.



<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.tistory.webnautes.googlemapsandroidapiexample">

   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
   
   <application
       android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"



   

2.  MainActivity.java를 다음 내용으로 변경합니다.




package com.tistory.webnautes.googlemapsandroidapiexample;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.IOException;
import java.util.List;
import java.util.Locale;


public class MainActivity extends AppCompatActivity
       implements OnMapReadyCallback,
       GoogleApiClient.ConnectionCallbacks,
       GoogleApiClient.OnConnectionFailedListener,
       LocationListener {


   private GoogleApiClient mGoogleApiClient = null;
   private GoogleMap mGoogleMap = null;
   private Marker currentMarker = null;

   private static final String TAG = "googlemap_example";
   private static final int GPS_ENABLE_REQUEST_CODE = 2001;
   private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 2002;
   private static final int UPDATE_INTERVAL_MS = 1000;  // 1초
   private static final int FASTEST_UPDATE_INTERVAL_MS = 500; // 0.5초

   private AppCompatActivity mActivity;
   boolean askPermissionOnceAgain = false;
   boolean mRequestingLocationUpdates = false;
   Location mCurrentLocatiion;
   boolean mMoveMapByUser = true;
   boolean mMoveMapByAPI = true;
   LatLng currentPosition;

   LocationRequest locationRequest = new LocationRequest()
           .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
           .setInterval(UPDATE_INTERVAL_MS)
           .setFastestInterval(FASTEST_UPDATE_INTERVAL_MS);


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

       getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
               WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
       setContentView(R.layout.activity_main);


       Log.d(TAG, "onCreate");
       mActivity = this;


       mGoogleApiClient = new GoogleApiClient.Builder(this)
               .addConnectionCallbacks(this)
               .addOnConnectionFailedListener(this)
               .addApi(LocationServices.API)
               .build();


       MapFragment mapFragment = (MapFragment) getFragmentManager()
               .findFragmentById(R.id.map);
       mapFragment.getMapAsync(this);
   }


   @Override
   public void onResume() {

       super.onResume();

       if (mGoogleApiClient.isConnected()) {

           Log.d(TAG, "onResume : call startLocationUpdates");
           if (!mRequestingLocationUpdates) startLocationUpdates();
       }


       //앱 정보에서 퍼미션을 허가했는지를 다시 검사해봐야 한다.
       if (askPermissionOnceAgain) {

           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
               askPermissionOnceAgain = false;

               checkPermissions();
           }
       }
   }


   private void startLocationUpdates() {

       if (!checkLocationServicesStatus()) {

           Log.d(TAG, "startLocationUpdates : call showDialogForLocationServiceSetting");
           showDialogForLocationServiceSetting();
       }else {

           if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                   && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

               Log.d(TAG, "startLocationUpdates : 퍼미션 안가지고 있음");
               return;
           }


           Log.d(TAG, "startLocationUpdates : call FusedLocationApi.requestLocationUpdates");
           LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this);
           mRequestingLocationUpdates = true;

           mGoogleMap.setMyLocationEnabled(true);

       }

   }



   private void stopLocationUpdates() {

       Log.d(TAG,"stopLocationUpdates : LocationServices.FusedLocationApi.removeLocationUpdates");
       LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
       mRequestingLocationUpdates = false;
   }



   @Override
   public void onMapReady(GoogleMap googleMap) {

       Log.d(TAG, "onMapReady :");

       mGoogleMap = googleMap;


       //런타임 퍼미션 요청 대화상자나 GPS 활성 요청 대화상자 보이기전에
       //지도의 초기위치를 서울로 이동
       setDefaultLocation();

       //mGoogleMap.getUiSettings().setZoomControlsEnabled(false);
       mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
       mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
       mGoogleMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener(){

           @Override
           public boolean onMyLocationButtonClick() {

               Log.d( TAG, "onMyLocationButtonClick : 위치에 따른 카메라 이동 활성화");
               mMoveMapByAPI = true;
               return true;
           }
       });
       mGoogleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

           @Override
           public void onMapClick(LatLng latLng) {

               Log.d( TAG, "onMapClick :");
           }
       });

       mGoogleMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {

           @Override
           public void onCameraMoveStarted(int i) {

               if (mMoveMapByUser == true && mRequestingLocationUpdates){

                   Log.d(TAG, "onCameraMove : 위치에 따른 카메라 이동 비활성화");
                   mMoveMapByAPI = false;
               }

               mMoveMapByUser = true;

           }
       });


       mGoogleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {

           @Override
           public void onCameraMove() {


           }
       });
   }


   @Override
   public void onLocationChanged(Location location) {

       currentPosition
               = new LatLng( location.getLatitude(), location.getLongitude());


       Log.d(TAG, "onLocationChanged : ");

       String markerTitle = getCurrentAddress(currentPosition);
       String markerSnippet = "위도:" + String.valueOf(location.getLatitude())
               + " 경도:" + String.valueOf(location.getLongitude());

       //현재 위치에 마커 생성하고 이동
       setCurrentLocation(location, markerTitle, markerSnippet);

       mCurrentLocatiion = location;
   }


   @Override
   protected void onStart() {

       if(mGoogleApiClient != null && mGoogleApiClient.isConnected() == false){

           Log.d(TAG, "onStart: mGoogleApiClient connect");
           mGoogleApiClient.connect();
       }

       super.onStart();
   }

   @Override
   protected void onStop() {

       if (mRequestingLocationUpdates) {

           Log.d(TAG, "onStop : call stopLocationUpdates");
           stopLocationUpdates();
       }

       if ( mGoogleApiClient.isConnected()) {

           Log.d(TAG, "onStop : mGoogleApiClient disconnect");
           mGoogleApiClient.disconnect();
       }

       super.onStop();
   }


   @Override
   public void onConnected(Bundle connectionHint) {


       if ( mRequestingLocationUpdates == false ) {

           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

               int hasFineLocationPermission = ContextCompat.checkSelfPermission(this,
                       Manifest.permission.ACCESS_FINE_LOCATION);

               if (hasFineLocationPermission == PackageManager.PERMISSION_DENIED) {

                   ActivityCompat.requestPermissions(mActivity,
                           new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                           PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);

               } else {

                   Log.d(TAG, "onConnected : 퍼미션 가지고 있음");
                   Log.d(TAG, "onConnected : call startLocationUpdates");
                   startLocationUpdates();
                   mGoogleMap.setMyLocationEnabled(true);
               }

           }else{

               Log.d(TAG, "onConnected : call startLocationUpdates");
               startLocationUpdates();
               mGoogleMap.setMyLocationEnabled(true);
           }
       }
   }


   @Override
   public void onConnectionFailed(ConnectionResult connectionResult) {

       Log.d(TAG, "onConnectionFailed");
       setDefaultLocation();
   }


   @Override
   public void onConnectionSuspended(int cause) {

       Log.d(TAG, "onConnectionSuspended");
       if (cause == CAUSE_NETWORK_LOST)
           Log.e(TAG, "onConnectionSuspended(): Google Play services " +
                   "connection lost.  Cause: network lost.");
       else if (cause == CAUSE_SERVICE_DISCONNECTED)
           Log.e(TAG, "onConnectionSuspended():  Google Play services " +
                   "connection lost.  Cause: service disconnected");
   }


   public String getCurrentAddress(LatLng latlng) {

       //지오코더... GPS를 주소로 변환
       Geocoder geocoder = new Geocoder(this, Locale.getDefault());

       List<Address> addresses;

       try {

           addresses = geocoder.getFromLocation(
                   latlng.latitude,
                   latlng.longitude,
                   1);
       } catch (IOException ioException) {
           //네트워크 문제
           Toast.makeText(this, "지오코더 서비스 사용불가", Toast.LENGTH_LONG).show();
           return "지오코더 서비스 사용불가";
       } catch (IllegalArgumentException illegalArgumentException) {
           Toast.makeText(this, "잘못된 GPS 좌표", Toast.LENGTH_LONG).show();
           return "잘못된 GPS 좌표";

       }


       if (addresses == null || addresses.size() == 0) {
           Toast.makeText(this, "주소 미발견", Toast.LENGTH_LONG).show();
           return "주소 미발견";

       } else {
           Address address = addresses.get(0);
           return address.getAddressLine(0).toString();
       }

   }


   public boolean checkLocationServicesStatus() {
       LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

       return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
               || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
   }


   public void setCurrentLocation(Location location, String markerTitle, String markerSnippet) {

       mMoveMapByUser = false;


       if (currentMarker != null) currentMarker.remove();


       LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());

       MarkerOptions markerOptions = new MarkerOptions();
       markerOptions.position(currentLatLng);
       markerOptions.title(markerTitle);
       markerOptions.snippet(markerSnippet);
       markerOptions.draggable(true);


       currentMarker = mGoogleMap.addMarker(markerOptions);


       if ( mMoveMapByAPI ) {

           Log.d( TAG, "setCurrentLocation :  mGoogleMap moveCamera "
                   + location.getLatitude() + " " + location.getLongitude() ) ;
           // CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(currentLatLng, 15);
           CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLng(currentLatLng);
           mGoogleMap.moveCamera(cameraUpdate);
       }
   }


   public void setDefaultLocation() {

       mMoveMapByUser = false;


       //디폴트 위치, Seoul
       LatLng DEFAULT_LOCATION = new LatLng(37.56, 126.97);
       String markerTitle = "위치정보 가져올 수 없음";
       String markerSnippet = "위치 퍼미션과 GPS 활성 요부 확인하세요";


       if (currentMarker != null) currentMarker.remove();

       MarkerOptions markerOptions = new MarkerOptions();
       markerOptions.position(DEFAULT_LOCATION);
       markerOptions.title(markerTitle);
       markerOptions.snippet(markerSnippet);
       markerOptions.draggable(true);
       markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
       currentMarker = mGoogleMap.addMarker(markerOptions);

       CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(DEFAULT_LOCATION, 15);
       mGoogleMap.moveCamera(cameraUpdate);

   }


   //여기부터는 런타임 퍼미션 처리을 위한 메소드들
   @TargetApi(Build.VERSION_CODES.M)
   private void checkPermissions() {
       boolean fineLocationRationale = ActivityCompat
               .shouldShowRequestPermissionRationale(this,
                       Manifest.permission.ACCESS_FINE_LOCATION);
       int hasFineLocationPermission = ContextCompat.checkSelfPermission(this,
               Manifest.permission.ACCESS_FINE_LOCATION);

       if (hasFineLocationPermission == PackageManager
               .PERMISSION_DENIED && fineLocationRationale)
           showDialogForPermission("앱을 실행하려면 퍼미션을 허가하셔야합니다.");

       else if (hasFineLocationPermission
               == PackageManager.PERMISSION_DENIED && !fineLocationRationale) {
           showDialogForPermissionSetting("퍼미션 거부 + Don't ask again(다시 묻지 않음) " +
                   "체크 박스를 설정한 경우로 설정에서 퍼미션 허가해야합니다.");
       } else if (hasFineLocationPermission == PackageManager.PERMISSION_GRANTED) {


           Log.d(TAG, "checkPermissions : 퍼미션 가지고 있음");

           if ( mGoogleApiClient.isConnected() == false) {

               Log.d(TAG, "checkPermissions : 퍼미션 가지고 있음");
               mGoogleApiClient.connect();
           }
       }
   }

   @Override
   public void onRequestPermissionsResult(int permsRequestCode,
                                          @NonNull String[] permissions,
                                          @NonNull int[] grantResults) {

       if (permsRequestCode
               == PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION && grantResults.length > 0) {

           boolean permissionAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;

           if (permissionAccepted) {


               if ( mGoogleApiClient.isConnected() == false) {

                   Log.d(TAG, "onRequestPermissionsResult : mGoogleApiClient connect");
                   mGoogleApiClient.connect();
               }



           } else {

               checkPermissions();
           }
       }
   }


   @TargetApi(Build.VERSION_CODES.M)
   private void showDialogForPermission(String msg) {

       AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
       builder.setTitle("알림");
       builder.setMessage(msg);
       builder.setCancelable(false);
       builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               ActivityCompat.requestPermissions(mActivity,
                       new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                       PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
           }
       });

       builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               finish();
           }
       });
       builder.create().show();
   }

   private void showDialogForPermissionSetting(String msg) {

       AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
       builder.setTitle("알림");
       builder.setMessage(msg);
       builder.setCancelable(true);
       builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {

               askPermissionOnceAgain = true;

               Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                       Uri.parse("package:" + mActivity.getPackageName()));
               myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
               myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
               mActivity.startActivity(myAppSettings);
           }
       });
       builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               finish();
           }
       });
       builder.create().show();
   }


   //여기부터는 GPS 활성화를 위한 메소드들
   private void showDialogForLocationServiceSetting() {

       AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
       builder.setTitle("위치 서비스 비활성화");
       builder.setMessage("앱을 사용하기 위해서는 위치 서비스가 필요합니다.\n"
               + "위치 설정을 수정하실래요?");
       builder.setCancelable(true);
       builder.setPositiveButton("설정", new DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int id) {
               Intent callGPSSettingIntent
                       = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
               startActivityForResult(callGPSSettingIntent, GPS_ENABLE_REQUEST_CODE);
           }
       });
       builder.setNegativeButton("취소", new DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int id) {
               dialog.cancel();
           }
       });
       builder.create().show();
   }


   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);

       switch (requestCode) {

           case GPS_ENABLE_REQUEST_CODE:

               //사용자가 GPS 활성 시켰는지 검사
               if (checkLocationServicesStatus()) {
                   if (checkLocationServicesStatus()) {

                       Log.d(TAG, "onActivityResult : 퍼미션 가지고 있음");


                       if ( mGoogleApiClient.isConnected() == false ) {

                           Log.d( TAG, "onActivityResult : mGoogleApiClient connect ");
                           mGoogleApiClient.connect();
                       }
                       return;
                   }
               }

               break;
       }
   }


}





5. 관련 포스팅


5.1. Google Maps Android API 사용 방법 및 예제

Google Maps Android API를 사용하는 기본적인  방법과 사용시 발생할 수 있는 문제점에 대해 다룹니다.

http://webnautes.tistory.com/647




5.2. Places API Web Service를 사용하여 Android Google Map에 현재 위치 주변의 음식점 표시하기


Places API Web Service를 이용하여 현재 위치 주변의 음식점 정보를 안드로이드의 구글맵에 표시하는 내용을 다룹니다.

http://webnautes.tistory.com/1080



5.3. GenyMotion 가상머신에 Google Apps설치하여 Google Maps Android API 테스트 하기


Genymotion에서 Google Map API을 가지고 작성한 Android 앱을 테스트하는 방법을 소개합니다.

http://webnautes.tistory.com/1064



반응형

포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

여러분의 응원으로 좋은 컨텐츠가 만들어집니다.
지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

유튜브 구독하기


제가 쓴 책도 한번 검토해보세요.

  1. 이전 댓글 더보기
  2. tnt 2018.09.30 23:17

    안녕하세요, 포스팅 보면서 앱 개발 프로젝트 진행중에 도움을 받고 있습니다. :)
    위에 알려주신 코드를 그대로 실행해보았는데, 에뮬레이터서는 현재 위치가 아닌 다른 지점에 마커가 표시됩니다.
    애뮬레이터에서는 gps확인이 불가능하다는 말을 들어서 안드로이드 폰에서 실행시켰더니,
    위치서비스 활성화를 묻는것 까지는 되는데, gps를 키고나면 앱이 중지되었다고 하면서 꺼지네요.
    애뮬레이터는 nexus 5 android7.1.1(Nougat) API25를 사용했고, 실 기기는 G7 android8.0.0 API26을 사용했습니다.
    google map api사용에 대한 글부터 포스팅 내용을 따라했기때문에 설정해야하는 요소들은 모드 했구요, 코드 변경한 부분도 없는데, 오류가 나니 어떻게 해야 할 지 모르겠습니다. ㅜㅜ

    아래는 로그캣의 에러부분입니다.
    2018-09-30 23:06:12.461 30626-30626/? E/adbd: failed to connect to socket 'localabstract:com.example.tntnr.project_woogie': Connection refused
    2018-09-30 23:06:16.476 3551-3551/? E/FMFRW_QctFmRadio: fmServiceGetFMState <<< mReceiver is null.
    2018-09-30 23:06:16.627 1360-1457/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:06:16.630 1352-1571/? E/TMR: acquire_thermal_recovery: rsrc=0, target_freq=1766400
    2018-09-30 23:06:16.630 1352-1571/? E/TMR: acquire_thermal_recovery: rsrc=1, target_freq=2803200
    2018-09-30 23:06:17.090 4817-4817/com.example.tntnr.project_woogie E/zygote64: The String#value field is not present on Android versions >= 6.0
    2018-09-30 23:06:17.336 1360-1457/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:06:17.336 1360-1457/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:06:17.367 616-616/? E/SELinux: avc: denied { find } for interface=vendor.lge.hardware.configstore::IConfigStore pid=4817 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:hal_lge_configstore_hwservice:s0 tclass=hwservice_manager
    2018-09-30 23:06:17.395 4817-4817/com.example.tntnr.project_woogie E/LocationManager: [LGNSS] Disable_PrivacyLocation_Information [tOperator : KT ] , [privacy_check : 0]
    2018-09-30 23:06:17.397 4817-4817/com.example.tntnr.project_woogie E/LocationManager: [LGNSS] Enable_EncryptLocation_Information [tOperator : KT ]
    2018-09-30 23:06:17.397 4817-4817/com.example.tntnr.project_woogie E/LocationManager: [LGNSS] This device should be enabled encrypt location info - KT
    2018-09-30 23:06:17.448 2817-2817/? E/QC_RIL_OEM_HOOK: LDU setting is
    2018-09-30 23:06:17.590 1394-2674/? E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1"
    2018-09-30 23:06:17.927 812-869/? E/ANDR-PERF-OPTSHANDLER: perf_lock_rel: updated /sys/class/scsi_host/host0/../../../clkscale_enable with 1
    return value 2
    2018-09-30 23:06:18.613 1394-2674/? E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1"
    2018-09-30 23:06:18.716 1352-1571/? E/TMR: release_thermal_recovery: tmr_state[0]->stored_freq=-1, tmr_state[0]->current_freq=-1
    2018-09-30 23:06:18.716 1352-1571/? E/TMR: release_thermal_recovery: tmr_state[1]->stored_freq=-1, tmr_state[1]->current_freq=-1
    2018-09-30 23:06:19.011 1394-2674/? E/IzatSvc_ComboNetworkProvider: Exiting with error proc line 441 "1"
    2018-09-30 23:06:19.049 4817-4817/com.example.tntnr.project_woogie E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.tntnr.project_woogie, PID: 4817
    com.google.maps.api.android.lib6.common.apiexception.b: Failed to decode image. The provided image must be a Bitmap.
    at com.google.maps.api.android.lib6.impl.n.a(:com.google.android.gms.dynamite_mapsdynamite@13280048@13.2.80 (040400-211705629):20)
    at com.google.maps.api.android.lib6.impl.o.b(:com.google.android.gms.dynamite_mapsdynamite@13280048@13.2.80 (040400-211705629):11)
    at com.google.maps.api.android.lib6.impl.cy.<init>(:com.google.android.gms.dynamite_mapsdynamite@13280048@13.2.80 (040400-211705629):18)
    at com.google.maps.api.android.lib6.impl.bc.a(:com.google.android.gms.dynamite_mapsdynamite@13280048@13.2.80 (040400-211705629):60)
    at com.google.android.gms.maps.internal.l.a(:com.google.android.gms.dynamite_mapsdynamite@13280048@13.2.80 (040400-211705629):491)
    at fh.onTransact(:com.google.android.gms.dynamite_mapsdynamite@13280048@13.2.80 (040400-211705629):10)
    at android.os.Binder.transact(Binder.java:608)
    at com.google.android.gms.internal.maps.zza.transactAndReadException(Unknown Source:7)
    at com.google.android.gms.maps.internal.zzg.addMarker(Unknown Source:9)
    at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source:2)
    at com.example.tntnr.project_woogie.MainActivity.setCurrentLocation(MainActivity.java:396)
    at com.example.tntnr.project_woogie.MainActivity.onLocationChanged(MainActivity.java:239)
    at com.google.android.gms.internal.location.zzay.notifyListener(Unknown Source:4)
    at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(Unknown Source:8)
    at com.google.android.gms.common.api.internal.ListenerHolder$zza.handleMessage(Unknown Source:16)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6759)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)
    2018-09-30 23:06:19.098 1360-1457/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:06:19.098 1360-1457/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:06:19.586 1360-1457/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:06:19.592 1352-1571/? E/TMR: acquire_thermal_recovery: rsrc=0, target_freq=1766400
    2018-09-30 23:06:19.592 1352-1571/? E/TMR: acquire_thermal_recovery: rsrc=1, target_freq=2803200
    2018-09-30 23:06:19.596 1394-2674/? E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1"
    2018-09-30 23:06:19.653 26494-26494/? E/PBSessionCacheImpl: sessionId[116523382576842359] not persisted.
    2018-09-30 23:06:20.072 2817-2817/? E/QC_RIL_OEM_HOOK: LDU setting is
    2018-09-30 23:06:20.253 812-869/? E/ANDR-PERF-OPTSHANDLER: perf_lock_rel: updated /sys/class/scsi_host/host0/../../../clkscale_enable with 1
    return value 2
    2018-09-30 23:06:21.621 1352-1571/? E/TMR: release_thermal_recovery: tmr_state[0]->stored_freq=-1, tmr_state[0]->current_freq=-1
    2018-09-30 23:06:21.621 1352-1571/? E/TMR: release_thermal_recovery: tmr_state[1]->stored_freq=-1, tmr_state[1]->current_freq=-1
    2018-09-30 23:06:24.418 2033-7679/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:06:24.598 1394-2674/? E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1"
    2018-09-30 23:06:25.143 1394-2674/? E/IzatSvc_ComboNetworkProvider: Exiting with error proc line 441 "1"
    2018-09-30 23:06:36.949 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:06:49.693 2033-3657/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:06:49.693 2033-3743/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:07:20.747 1360-1458/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:07:21.221 2033-2845/? E/BatteryStatsService: no controller energy info supplied
    2018-09-30 23:07:24.432 2033-16493/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:07:24.596 1394-2674/? E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1"
    2018-09-30 23:07:25.197 2410-2410/? E/LockDragLayerEffect: getWeather() WeatherInformation is null.
    2018-09-30 23:07:25.310 2410-2410/? E/LockDragLayerEffect: getWeather() WeatherInformation is null.
    2018-09-30 23:07:25.338 2723-2920/? E/VoicePrintService: [svc] isGrantTrusted... false false
    2018-09-30 23:07:25.355 1360-1457/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:07:25.356 1360-1457/? E/PowerRM: found 42, mode set to 0
    2018-09-30 23:07:25.359 2410-2587/? E/KeyguardModel: package: not found!
    2018-09-30 23:07:25.360 2410-2587/? E/KeyguardModel: package: not found!
    2018-09-30 23:07:25.360 2410-2587/? E/KeyguardModel: package: not found!
    2018-09-30 23:07:37.053 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:07:40.655 2033-2845/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:07:42.074 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:08:15.428 2033-2317/? E/WifiStateMachine: CheckDhcpInfoCacheList : DhcpClient.CMD_PRE_DHCP_ACTION[ConnectingState]
    2018-09-30 23:08:15.779 5007-5007/? E/LGABClient: [DmNotiService.java] [onCreate()] : [142] : DmNotiService.onCreate()
    2018-09-30 23:08:15.856 2033-2336/? E/ConnectivityService: RemoteException caught trying to send a callback msg for NetworkRequest [ LISTEN id=2209, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED] ]
    2018-09-30 23:08:22.131 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:08:22.893 2033-3838/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:08:22.895 2033-7679/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:08:24.422 2033-3743/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:08:24.602 1394-2674/? E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1"
    2018-09-30 23:08:27.651 16500-16647/? E/memtrack: Couldn't load memtrack module
    2018-09-30 23:08:32.151 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:08:42.161 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:08:52.179 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:08:57.186 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:09:03.399 11944-11974/? E/flk_pushAgent: 2018-09-30 23:09:03:399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2018-09-30 23:09:03.406 11944-11974/? E/flk_pushAgent: 2018-09-30 23:09:03:406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2018-09-30 23:09:05.094 2033-2088/? E/BatteryStatsService: no controller energy info supplied
    2018-09-30 23:09:05.098 2033-2088/? E/BatteryStatsService: no controller energy info supplied
    2018-09-30 23:09:05.140 2033-14435/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:09:05.147 2033-14435/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:09:08.460 11944-11944/? E/flk_pushAgent: 2018-09-30 23:09:08:459 ###############################################################################
    2018-09-30 23:09:08.460 11944-11944/? E/flk_pushAgent: 2018-09-30 23:09:08:460 서비스 진입 이유 : PUSH_ACTION_ALARM_CHECK 서비스 기동
    2018-09-30 23:09:08.460 11944-11944/? E/flk_pushAgent: 2018-09-30 23:09:08:460 ###############################################################################
    2018-09-30 23:09:22.223 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored
    2018-09-30 23:09:24.431 2033-7679/? E/NotificationService: Suppressing notification from package by user request.
    2018-09-30 23:09:24.602 1394-2674/? E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1"
    2018-09-30 23:09:27.230 1616-1616/? E/MSM-irqbalance: IRQ 82 not found in internal structure or should be ignored

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.10.01 00:40 신고

      다음 부분을 봐서는 마커를 위해 사용한 이미지 때문에 발생한 에러 같습니다.

      Process: com.example.tntnr.project_woogie, PID: 4817
      com.google.maps.api.android.lib6.common.apiexception.b: Failed to decode image. The provided image must be a Bitmap.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.10.01 12:10 신고

      아래 줄을 지워보세요.

      markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher));

    • tnt 2018.10.01 19:32

      !!덕분에 오류 해결되었어요!! 게시물에 도움 많이 받고있습니다. 오류를 좀더 꼼꼼하게 살펴봐야겠어요ㅜ 감사합니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.10.01 20:05 신고

      축하드려요

  3. 레옹 2018.10.01 22:00

    감사합니다

    궁금사항 하나 더 있습니다.

    지금 갤노트3 안드버전5.0으로 돌리는데, 앱이 죽으면서

    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.teamnova4th.nathan.travelnote, PID: 32309
    java.lang.NullPointerException: IBitmapDescriptorFactory is not initialized
    at com.google.android.gms.common.internal.Preconditions.checkNotNull(Unknown Source)
    at com.google.android.gms.maps.model.BitmapDescriptorFactory.zzf(Unknown Source)
    at com.google.android.gms.maps.model.BitmapDescriptorFactory.defaultMarker(Unknown Source)
    at com.teamnova4th.nathan.travelnote.LocationActivity.setDefaultLocation(LocationActivity.java:450)
    at com.teamnova4th.nathan.travelnote.LocationActivity.onConnectionFailed(LocationActivity.java:339)
    at com.google.android.gms.common.internal.GmsClientEventManager.onConnectionFailure(Unknown Source)
    at com.google.android.gms.common.api.internal.zzav.zzc(Unknown Source)
    at com.google.android.gms.common.api.internal.zzaj.zze(Unknown Source)
    at com.google.android.gms.common.api.internal.zzaj.zza(Unknown Source)
    at com.google.android.gms.common.api.internal.zzan.zzaq(Unknown Source)
    at com.google.android.gms.common.api.internal.zzbe.zzc(Unknown Source)
    at com.google.android.gms.common.api.internal.zzbf.handleMessage(Unknown Source)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:145)
    at android.app.ActivityThread.main(ActivityThread.java:5942)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

    에러메세지가 나는데ㅡ
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
    여기부분부터 에러가 나네요. 비트맵 초기화를 할수 없다고 뜨는데,
    혹시 안드 버전이 낮아서 그런건지요??

  4. 좋은 글 감사합니다 2018.10.09 23:50

    메인 액티비티에 위 대로 따라하니 잘 됩니다
    그런데 메인액티비티에 버튼 하나 만들고, 그 버튼을 누르면 화면전환과 함께 서브액티비티가 열리고
    서브액티비티에서 위 기능(현재 위치 표시)을 수행하고 싶은데 자꾸 팅깁니다.
    아래는 로그캣입니다. xml에 제가 발견하지 못한 오타가 있는것일까요...?
    --------- beginning of crash
    10-09 10:46:49.808 2730-2730/com.example.nj_ba.termproject E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.nj_ba.termproject, PID: 2730
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.nj_ba.termproject/com.example.nj_ba.termproject.googlemapActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.MapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.MapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference
    at com.example.nj_ba.termproject.googlemapActivity.onCreate(googlemapActivity.java:24)
    at android.app.Activity.performCreate(Activity.java:7009)
    at android.app.Activity.performCreate(Activity.java:7000)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6494) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.10.09 23:57 신고

      아마도 화면이 회전되면 프래그먼트가 초기화(?) 되는 현상 같습니다...프래그먼트 화면 회전 관련 자료를 찾아보세요.

  5. bumi 2018.10.13 21:06

    선생님 안녕하세요~
    포스팅한 글 보고 열심히 따라하다가 다음과 같은 에러가 뜨면서 막히는데 어떻게 해야되는지 모르겠습니다.
    도움 부탁드립니다 ㅠ-ㅠ

    10-13 11:54:53.666 13558-13558/com.example.qjagm.googlemapsandriodapiexample E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.qjagm.googlemapsandriodapiexample, PID: 13558
    com.google.maps.api.android.lib6.common.apiexception.b: Failed to decode image. The provided image must be a Bitmap.
    at com.google.maps.api.android.lib6.impl.p.a(:com.google.android.gms.dynamite_mapsdynamite@14367084@14.3.67 (100700-216465562):10)
    at com.google.maps.api.android.lib6.impl.q.a(:com.google.android.gms.dynamite_mapsdynamite@14367084@14.3.67 (100700-216465562):5)
    at com.google.maps.api.android.lib6.impl.dd.<init>(:com.google.android.gms.dynamite_mapsdynamite@14367084@14.3.67 (100700-216465562):15)
    at com.google.maps.api.android.lib6.impl.bf.a(:com.google.android.gms.dynamite_mapsdynamite@14367084@14.3.67 (100700-216465562):373)
    at com.google.android.gms.maps.internal.l.a(:com.google.android.gms.dynamite_mapsdynamite@14367084@14.3.67 (100700-216465562):312)
    at fn.onTransact(:com.google.android.gms.dynamite_mapsdynamite@14367084@14.3.67 (100700-216465562):4)
    at android.os.Binder.transact(Binder.java:667)
    at com.google.android.gms.internal.maps.zza.transactAndReadException(Unknown Source:7)
    at com.google.android.gms.maps.internal.zzg.addMarker(Unknown Source:9)
    at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source:2)
    at com.example.qjagm.googlemapsandriodapiexample.MainActivity.setCurrentLocation(MainActivity.java:397)
    at com.example.qjagm.googlemapsandriodapiexample.MainActivity.onLocationChanged(MainActivity.java:240)
    at com.google.android.gms.internal.location.zzay.notifyListener(Unknown Source:4)
    at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(Unknown Source:17)
    at com.google.android.gms.common.api.internal.ListenerHolder$zaa.handleMessage(Unknown Source:5)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.10.13 21:11 신고

      다음 줄을 삭제해보세요.


      markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher));

  6. bumi 2018.10.14 15:11

    정말 감사합니다!!

  7. 안드로이드doit 2018.11.15 23:15

    혹시 마커를 지정한 좌표값은 어디에 저장이 되는건가요 ? 따로불러올수있는 방법이 따로 있나요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2018.11.15 23:41 신고

      GoogleMap 객체에 마커를 추가하는 addMarker 메소드와 GoogleMap 객체에 추가된 모든 마커를 지우는 clear 메소드만 있는 듯보입니다. 따로 관리해야하지 않을까 싶습니다.

    • 안드로이드doit 2018.11.16 10:53

      감사합니다!

  8. Favicon of https://youngest-programming.tistory.com BlogIcon 프로그래밍막내 2019.04.20 09:59 신고

    포스팅 잘봤습니다 제가 아직 입문자라그런지 코드가 좀 복잡한거같네요 ㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.20 10:05 신고

      런타임 퍼미션관련 코드 때문에 복잡합니다.
      다음 글을 참고해보세요.


      안드로이드 런타임 퍼미션(Runtime Permission) 예제
      https://webnautes.tistory.com/1225

  9. Yeda 2019.04.30 22:14

    안녕하세요. 이 포스트를 보고 MainActivity 이름을 MapsActivity로 진행한 것외에는 그대로 복사하여 안드로이드 스튜디오에 작성하였습니다. 빌드와 SYNC에서의 문제는 발생하지 않고 에뮬레이터의 기본 화면을 띄우는데 까지 성공하였습니다. 그런데 에뮬레이터에 apk가 설치되고 해당 어플이 실행될 때 화면을 비춰주지않고 멈추는 현상이 계속됩니다.
    로그캣의 내용은 다음과 같습니다.
    2019-04-30 22:12:36.644 538-538/com.exam.examy E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.exam.examy, PID: 538
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.exam.examy/com.exam.examy.MapsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.MapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.MapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference
    at com.exam.examy.MapsActivity.onCreate(MapsActivity.java:111)
    at android.app.Activity.performCreate(Activity.java:7009)
    at android.app.Activity.performCreate(Activity.java:7000)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6494) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
    2019-04-30 22:12:38.586 538-590/com.exam.examy W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
    2019-04-30 22:12:38.592 538-590/com.exam.examy I/DynamiteModule: Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:4
    2019-04-30 22:12:38.592 538-590/com.exam.examy I/DynamiteModule: Selected remote version of com.google.android.gms.googlecertificates, version >= 4
    2019-04-30 22:12:38.599 538-590/com.exam.examy W/zygote: Unsupported class loader
    2019-04-30 22:12:38.600 538-590/com.exam.examy W/zygote: Skipping duplicate class check due to unsupported classloader


    여러 번 시도했음에도 불구하고 멈추는 현상에 결국 댓글을 남기게 되었습니다. 자그만한 도움이라도 좋으니 답변해주시기를 바라고 기다리겠습니다..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.04.30 22:21 신고

      현재위치가 아닌 지도만 보여주는 다음 코드로 일단 테스트해보세요.

      https://webnautes.tistory.com/647

  10. hjy 2019.05.01 19:38

    사용자가 몇미터 이동시마다 현재위치를 받아와 경로에 마커를 찍어주고 싶으면 어떻게 해야하나요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.01 20:25 신고

      다음 포스트를 참고하여 이동한 거리를 계산해주면 됩니다.

      https://webnautes.tistory.com/1165

  11. iamsad 2019.05.04 13:35

    org.gradle.execution.MultipleBuildFailures: Build completed with 1 failures.
    at org.gradle.initialization.DefaultGradleLauncher$ExecuteTasks.run(DefaultGradleLauncher.java:386)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.initialization.DefaultGradleLauncher.runTasks(DefaultGradleLauncher.java:247)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:159)
    at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:134)
    at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:58)
    at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:55)
    at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:82)
    at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:75)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:183)
    at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
    at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:75)
    at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:55)
    at org.gradle.tooling.internal.provider.runner.ClientProvidedBuildActionRunner.run(ClientProvidedBuildActionRunner.java:55)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:58)
    at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
    at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:49)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:44)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:315)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:305)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:101)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:44)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:49)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:46)
    at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:78)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:46)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
    at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
    at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:78)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:52)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:59)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:36)
    at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
    at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
    at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
    at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:81)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    at java.base/java.lang.Thread.run(Thread.java:834)
    Caused by: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformDexWithInstantRunSlicesApkForDebug'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:95)
    at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:91)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:57)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:119)
    at org.gradle.api.internal.tasks.execution.ResolvePreviousStateExecuter.execute(ResolvePreviousStateExecuter.java:43)
    at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:93)
    at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:45)
    at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:94)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:56)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:67)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:315)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:305)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:101)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)
    at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
    ... 6 more
    Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.io.FileNotFoundException: C:\andproject\app\build\intermediates\instant_run_split_apk_resources\debug\instantRunSplitApkResourcesDebug\out\slice_7\resources_ap
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:600)
    at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:678)
    at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:722)
    at com.android.ide.common.internal.WaitableExecutor.waitForTasksWithQuickFail(WaitableExecutor.java:149)
    at com.android.build.gradle.internal.transforms.InstantRunSliceSplitApkBuilder.transform(InstantRunSliceSplitApkBuilder.java:246)
    at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:239)
    at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:235)
    at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102)
    at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:230)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
    at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:47)
    at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)
    at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$2.run(ExecuteActionsTaskExecuter.java:284)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:273)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:258)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:67)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:145)
    at org.gradle.internal.execution.impl.steps.ExecuteStep.execute(ExecuteStep.java:49)
    at org.gradle.internal.execution.impl.steps.CancelExecutionStep.execute(CancelExecutionStep.java:34)
    at org.gradle.internal.execution.impl.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:69)
    at org.gradle.internal.execution.impl.steps.TimeoutStep.execute(TimeoutStep.java:49)
    at org.gradle.internal.execution.impl.steps.CatchExceptionStep.execute(CatchExceptionStep.java:33)
    at org.gradle.internal.execution.impl.steps.CreateOutputsStep.execute(CreateOutputsStep.java:50)
    at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:43)
    at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:29)
    at org.gradle.internal.execution.impl.steps.CacheStep.executeWithoutCache(CacheStep.java:134)
    at org.gradle.internal.execution.impl.steps.CacheStep.lambda$execute$3(CacheStep.java:83)
    at java.base/java.util.Optional.orElseGet(Optional.java:369)
    at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:82)
    at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:36)
    at org.gradle.internal.execution.impl.steps.PrepareCachingStep.execute(PrepareCachingStep.java:33)
    at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:38)
    at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:23)
    at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96)
    at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89)
    at java.base/java.util.Optional.map(Optional.java:265)
    at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:52)
    at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36)
    at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:34)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:91)
    ... 35 more
    Caused by: java.lang.RuntimeException: java.io.FileNotFoundException: C:\andproject\app\build\intermediates\instant_run_split_apk_resources\debug\instantRunSplitApkResourcesDebug\out\slice_7\resources_ap
    at java.base/java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1453)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
    Caused by: java.io.FileNotFoundException: C:\andproject\app\build\intermediates\instant_run_split_apk_resources\debug\instantRunSplitApkResourcesDebug\out\slice_7\resources_ap
    at com.android.build.gradle.internal.transforms.InstantRunSliceSplitApkBuilder.lambda$null$1(InstantRunSliceSplitApkBuilder.java:233)
    at java.base/java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1448)
    ... 5 more

    빌드 에러 나는데 혹시 이유아시나해서.. 여쭈어 봅니다 ㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.05.04 13:44 신고

      코드문제가 아니라 빌드가 꼬인거 같네요. 메뉴에서 File > Sync Project with Gradle Files를 선택해보세요..

  12. android 2019.06.03 16:17

    안녕하세요 좋은 코드 감사합니다. 알려주신대로 그대로 복붙해서 실행했는데 다음과 같은 오류가 뜨고
    애뮬레이터실행 시 현재 위치는 뜨지 않고 미국위치가 떠요 어떻게 해결해야 할까요?



    2019-06-03 16:13:12.192 7167-7167/? E/BeaconBle: Scan couldn't start for Places
    2019-06-03 16:13:17.061 6799-9133/? E/ActivityThread: Failed to find provider info for com.google.android.apps.gsa.testing.ui.audio.recorded
    2019-06-03 16:13:19.318 1708-1801/? E/storaged: getDiskStats failed with result NOT_SUPPORTED and size 0
    2019-06-03 16:13:20.223 1700-1700/? E/installd: Failed to delete /data/app/vmdl1445751964.tmp: No such file or directory
    2019-06-03 16:13:20.919 9216-9224/? E/example.mapsho: Failed to send jdwp-handshake response.: Broken pipe
    2019-06-03 16:13:22.151 1695-1825/? E/SurfaceFlinger: ro.sf.lcd_density must be defined as a build property
    2019-06-03 16:13:22.389 1695-1824/? E/SurfaceFlinger: ro.sf.lcd_density must be defined as a build property
    2019-06-03 16:13:35.630 1845-1858/? E/memtrack: Couldn't load memtrack module
    2019-06-03 16:13:50.292 1845-1858/? E/memtrack: Couldn't load memtrack module
    2019-06-03 16:14:19.320 1708-1801/? E/storaged: getDiskStats failed with result NOT_SUPPORTED and size 0

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.06.03 17:59 신고

      에뮬레이터에서는 실제 GPS를 가져오지 못합니다.

      GPS 좌표를 수동으로 입력해주거나

      스마트폰으로 테스트해보세요.

  13. Favicon of http://naver.com BlogIcon 제로 2019.07.01 15:01

    혹시 애뮬레이터도 되나요??

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.07.01 15:04 신고

      에뮬레이터도 됩니다.

      안드로이드 스튜디오의 에뮬레이터를 사용시에는 플레이스토어 사용가능한 이미지를 선택해서 해야합니다.

      지니모션의 경우에는 상단에 GApps를 추가하는 버튼을 클릭한 후 진행해야 합니다.

  14. Favicon of http://naver.com BlogIcon 제로 2019.07.01 15:13

    에뮬레이터로 햇는데 위치를 못받아오고 애뮬레이터에 설정된 gps로만 계속가더라고요

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.07.01 18:34 신고

      에뮬레이터에서 GPS를 가상으로 설정하여 현재 위치를 이동시키는 겁니다.

      실제 GPS를 받아오려면 안드로이드 폰을 사용할 수 밖에 없습니다.

  15. 11살 아인슈타인 2019.08.16 19:45

    안녕하세요! 따라하다가 잘 안 되는 점이 있어서 여쭤보려고 합니다
    구글맵도 잘 뜨고, 위치 사용 허용 메세지도 잘 뜨는데 현재 위치가 안 떠요..
    그래서 위에 주신 코드를 사용해봤는데 mActivity에서 에러가 납니다..
    저는 메인액티비티 말고 맵액티비티에서 구글맵을 만들었는데 FragmentActivity를 extend해야해서 AppcompatActivity를 빼고 FragmentActivity를 넣었는데 혹시 그게 문제일까요?

    오류 :
    Incompatible types.
    Required:
    android.support.v7.app.AppCompatActivity
    Found:
    com.example.welcomesungshin.MapsActivity

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.08.16 20:11 신고


      AppCompatActivity를 사용하지 않아서 발생한 에러로 보입니다.

    • 11살 아인슈타인 2019.08.16 20:15

      그래서 FragmentActivity를 빼고 AppcompatActivity를 써봤는데 지도가 안 켜지고 메인화면으로 가버려요..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.08.16 20:36 신고



      로그캣에 다른 에러가 보이지 않나요?

    • 11살 아인슈타인 2019.08.16 21:19

      몇 군데 수정했더니 지도가 잘 떠요!
      근데 마커는 뜨는데 현재위치를 못잡아요ㅠㅠ
      (실제 구글맵에서는 위치가 정확히 잡혀요)
      실제 기기에서는 현재위치 위도랑 경도가 둘 다 0으로 떠서 마커가 바다에 있고, 애뮬레이터에서는 현재위치가 google plex에 떠요..
      초기 위치를 서울로 설정하니까 서울에 뜨기는 하는데 정확한 위치를 잡을 방법은 없나요,,?
      로그캣에는 2019-08-16 21:15:11.418 11700-11707/? E/art: Failed sending reply to debugger: Broken pipe
      2019-08-16 21:15:11.375 11700-11700/? E/Zygote: v2
      2019-08-16 21:15:11.376 11700-11700/? E/Zygote: accessInfo : 0
      이런 오류가 떠요..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.08.17 08:48 신고

      포스트의 "3. 프로그램 흐름"처럼 로그에 메시지가 순서대로 보이는지 확인해보세요.

  16. Favicon of https://kkkapuq.tistory.com BlogIcon 주닝! 2019.10.09 18:16 신고

    안녕하세요, 올려주신 예제 감사합니다.
    실행시켜보니 오류가 이렇게 떠서 여쭤봅니다 ㅠ

    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.MapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference
    at com.example.ev_map.MainActivity.onCreate(MainActivity.java:99)


    99라인에 있는 내용은 mapFragment.getMapAsync(this);

    입니다.

    혹시 androidx로 넘어가면서 SupportMapFragment와 관련된 문제인가요..?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.10.09 19:17 신고

      이전 포스트의 기존에 MapFragment를 사용하던 것을 SupportMapFragment로 변경했는데
      본 포스트에서는 수정을 해놓지 않아서 발생한 오류로 보입니다.
      확인해보고 수정해놓아야 겠군요..


      다음 부분을
      MapFragment mapFragment = (MapFragment) getFragmentManager()
      .findFragmentById(R.id.map);
      mapFragment.getMapAsync(this);


      아래처럼 수정해서 동작시켜보세요.
      SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
      .findFragmentById(R.id.map);
      mapFragment.getMapAsync(this);


  17. 학생 2019.10.20 11:24

    안녕하세요
    다름이아니고 내위치버튼(우측상단버튼) 클릭햇을때 현재위치를 찾게하는 부분을 코드에서 어딘지 알고싶습니다.
    좀더 구체적으로는 버튼눌럿을때 조건문같은게 있는것인지 보기위해서요

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.10.20 14:44 신고

      코드에서 처리해주는 루틴이 없습니다.
      버튼이 클릭되면 다음 메소드가 호출됩니다.

      https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.OnMyLocationButtonClickListener.html#onMyLocationButtonClick()

  18. 함준댕 2019.11.17 20:52

    안녕하세요. 실행 중에
    error: package android.support.annotation does not exist
    error: cannot find symbol class ActivityCompat
    error: package android.support.v4.content does not exist
    error: package android.support.v7.app does not exist
    error: package android.support.v7.app does not exist
    error: cannot find symbol class AppCompatActivity
    error: cannot find symbol class AppCompatActivity
    error: cannot find symbol class NonNull
    error: cannot find symbol class NonNull
    error: method does not override or implement a method from a supertype
    error: cannot find symbol variable super
    error: cannot find symbol method getWindow()
    error: cannot find symbol method setContentView(int)
    error: incompatible types: MainActivity cannot be converted to Context
    error: cannot find symbol method getFragmentManager()
    error: method does not override or implement a method from a supertype
    error: cannot find symbol variable super
    error: cannot find symbol variable ActivityCompat
    error: cannot find symbol variable ActivityCompat
    error: method does not override or implement a method from a supertype
    error: cannot find symbol variable super
    error: method does not override or implement a method from a supertype
    error: cannot find symbol variable super
    error: cannot find symbol variable ContextCompat
    error: cannot find symbol variable ActivityCompat
    error: incompatible types: MainActivity cannot be converted to Context
    error: no suitable method found for makeText(MainActivity,String,int)
    method Toast.makeText(Context,CharSequence,int) is not applicable
    (argument mismatch; MainActivity cannot be converted to Context)
    method Toast.makeText(Context,int,int) is not applicable
    (argument mismatch; MainActivity cannot be converted to Context)
    error: no suitable method found for makeText(MainActivity,String,int)
    method Toast.makeText(Context,CharSequence,int) is not applicable
    (argument mismatch; MainActivity cannot be converted to Context)
    method Toast.makeText(Context,int,int) is not applicable
    (argument mismatch; MainActivity cannot be converted to Context)
    error: no suitable method found for makeText(MainActivity,String,int)
    method Toast.makeText(Context,CharSequence,int) is not applicable
    (argument mismatch; MainActivity cannot be converted to Context)
    method Toast.makeText(Context,int,int) is not applicable
    (argument mismatch; MainActivity cannot be converted to Context)
    error: cannot find symbol variable LOCATION_SERVICE
    error: cannot find symbol variable ActivityCompat
    error: cannot find symbol variable ContextCompat
    error: method does not override or implement a method from a supertype
    error: package AlertDialog does not exist
    error: package AlertDialog does not exist
    error: cannot find symbol variable ActivityCompat
    error: cannot find symbol method finish()
    error: package AlertDialog does not exist
    error: package AlertDialog does not exist
    error: cannot find symbol method finish()
    error: package AlertDialog does not exist
    error: package AlertDialog does not exist
    error: cannot find symbol method startActivityForResult(Intent,int)
    이러한 에러가 발생하는 데, 아직 초짜인 지라 오류의 원인이 파악 되지 않아 댓글 남깁니다.
    감사합니다.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.11.17 22:44 신고

      androidx에서 사용가능하도록 패키지 이름이 바뀌지 않아서 그렇습니다.

      특별한 이유가 없는 한
      이 포스트 대신 다음 포스트를 사용하는게 좋을 듯합니다.


      Android Google Map에 현재 위치 표시하기( FusedLocationProviderClient 사용)
      https://webnautes.tistory.com/1249

    • 함준댕 2019.11.19 12:50

      답글 감사 드립니다.
      다음 진행 과정 인 현재위치에서 남은 경로 계산하기를 진행하려면 위의 코드를 기반으로 작성해야 하는 데 혹시 다음 포스트의 코드를 기반으로도 똑같이 남은 경로를 계산하는 코드를 알 수 있을까요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2019.11.19 21:32 신고

      해당 코드를 사용하여 작성된 것은 아직없습니다.

  19. 교오옹 2020.01.16 10:55

    안녕하세요
    덕분에 많은 도움을 받고 있습니다!
    현재 위치를 나타내는 아이콘을 바꿀 수 있는 방법이 있을까요? 마커의 모양을 바꾸고 크기를 늘려서 가려볼까도 했지만 아이콘위에 마커가 생겨서 그렇게는 안돼더라구요

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.01.16 23:08 신고

      현재 위치를 나타내는 아이콘을 프로그래밍적으로 바꿀 수 있는 방법이 없는 듯 보입니다.

  20. 도와주세요ㅜ 2020.02.14 21:48

    혹시 마커로 표시한 현재 위치가 건물내에 있는지 도로에 있는지 구분할 수 있는 방법이 있을까요?

  21. Help 2020.04.25 15:14

    안녕하세요 지도api예제와 이어서 현재위치 표시하기까지 잘 따라하였습니다! 핸드폰을 연결하여 테스트하는데 “퍼미션이 거부되었습니다. 설정에서 퍼미션을 허용해야합니다” 라고 뜨면서 지도가 뜨질않아요ㅠㅠ 어떻게 해야할가요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.04.25 15:26 신고

      앱을 삭제하고 다시 설치해보세요

    • Help 2020.04.25 15:30

      이번에는 앱을 중지하였다고 떠요ㅠㅠㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.04.25 15:31 신고

      로그캣을 보고 원인을 찾아야 하는데 여의치않으면 코드를 다시 붙여넣기해보세요

    • Help 2020.04.25 15:33

      제가 코드 마지막 부분에 다른 화면으로 intent 하는 코드를 넣었는데 그게 원인일 수도 있나요??

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.04.25 15:34 신고

      주석처리하고 실행해보면 알수 있습니다

    • Help 2020.04.25 15:41

      그래도 여전히 앱을 중지하였다고 뜨네요ㅠ 혹시 몇일전에 복사해뒀던 코드랑 조금 다른부분이 있는데 수정하신건가용???

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.04.25 15:46 신고

      최근에 수정한적이 없습니다.

+ Recent posts