[AndroidStudio, GoogleMap, Firebase] KnockKnock 개발일지 - 0322 (안드로이드와 GoogleMap 연동 후 실시간 위치정보 Firebase에서 업데이트)

Hyebin Lee·2022년 3월 22일
0

오늘의 목표

  1. ✔안드로이드 스튜디오 프로젝트에 GoogleMap API 연동시키기
  2. ✔안드로이드 스튜디오에서 GoogleMap으로 실시간 정보 가져오기 + UI에 찍어내기
  3. ✔실시간 유저 위치 정보를 실시간으로 firebase에 업데이트 하기

참고한 링크

[안드로이드] 구글맵으로 GPS 현재위치 실시간 연동하기
[Android Studio] Google Maps🗾 빈화면 오류
Ensure that the "Google Maps Android API v2" is enabled. I am getting this error when I try to Implement Google Maps

오늘의 이슈

⛔ pedroSG94를 찾을 수 없음
⛔구글맵이 UI에 나타나지 않는 오류
⛔ 실시간 위치 지속적 감지 안됨 💥

안드로이드와 구글맵 연동

1. 의존성 추가

build.gradle에 다음과 같은 의존성을 추가한다.

 //구글맵
    implementation 'com.github.pedroSG94:AutoPermissions:1.0.3'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'

2. 구글 API 키 발급

https://console.cloud.google.com
이곳에서 구글 API 키를 발급받아야 한다.
구글 API 키를 발급받기 위해서는 먼저 프로젝트 생성을 해야하는데 AWS와 같은 클라우드 플랫폼과 달리 구글 클라우드는 매우 간편하게 프로젝트를 생성할 수 있어서 1초만에 마무리 되었다!
그냥 프로젝트 명만 써주면 프로젝트 등록 끝~~@
그 다음에 사용자 인증 정보에 가서 사용자 인증 정보 만들기 를 클릭한 뒤 API 키를 복사하여 발급받으면 된다.

3. Manifest설정

아래의 내용을 AndroidManifest.xml에 추가한다.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<application
	android: ...
    ...
    >
<uses-library android:name="com.google.android.maps" />
        <uses-library
            android:name="org.apache.http.legacy"
            android:required="false" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="위에서 받은 API값"/>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

⛔ pedroSG94를 찾을 수 없음


pedro를 찾을 수 없다는 오류가 났다.
검색해보니 pedro는 maven { url 'https://jitpack.io' } 이 있어야 하는데 설정 파일에서 해당 코드를 쓰지 않아서 나는 오류였다.
따라서 setting.gradle에서

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
        maven { url 'https://jitpack.io' }
    }
}

다음과 같은 코드를 추가했고 더 이상 오류가 나지 않았다.

안드로이드 구현

  • .xml 파일
 <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment"/>

위와 같이 fragment에 class를 googleMap으로 주어 설정할 수 있다.

  • .activity 파일

1. 구글맵을 띄울 fragment 구글맵 연동시키기

SupportMapFragment mapFragment;

 try {
            MapsInitializer.initialize(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
 mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                Log.i("MyLocTest", "지도 준비됨");
                map = googleMap;
                if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: 권한 승인 요청하기
                    return;
                }
                map.setMyLocationEnabled(true);
            }
        });

2. 내 위치 정보 가져오기 (LocationManager 활용)

LocationManager manager;
gpsListener = new GPSListener(); // 실시간 위치 정보 감지 

LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


 if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if(location !=null{
 					double latitude = location.getLatitude();
                    double longitude = location.getLongitude();}}
 else if (manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {

                location = manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (location != null) {
                    double latitude = location.getLatitude();
                    double longitude = location.getLongitude();}}
                

3. 실시간 정보 업데이트 기능 구현 (GPSListener 활용)

 class GPSListener implements LocationListener {

        // 위치 확인되었을때 자동으로 호출됨 (일정시간 and 일정거리)
        @Override
        public void onLocationChanged(Location location) {
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
			//실시간 위치 정보로 할 기능 구현 
            showCurrentLocation(latitude, longitude); //📌 구글맵에 표시하기 
            Log.i("MyLocTest", "onLocationChanged() 호출되었습니다.");
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    }

4. 실시간 위치 정보 요청 메서드


 long minTime = 0;        // 0초마다 갱신 - 바로바로갱신
 float minDistance = 0;
            
 manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTime, minDistance, gpsListener);

5. 구글맵에 경도 위도 정보로 위치 표시하기

private void showCurrentLocation(double latitude, double longitude) {
        LatLng curPoint = new LatLng(latitude, longitude);
        map.animateCamera(CameraUpdateFactory.newLatLngZoom(curPoint, 15));
        showMyLocationMarker(curPoint);
    }

    private void showMyLocationMarker(LatLng curPoint) {
        if (myLocationMarker == null) {
            myLocationMarker = new MarkerOptions(); // 마커 객체 생성
            myLocationMarker.position(curPoint);
            myLocationMarker.title("최근위치 \n");
            myLocationMarker.snippet("*GPS로 확인한 최근위치");
           // myLocationMarker.icon(BitmapDescriptorFactory.fromResource((R.drawable.mylocation)));
            myMarker = map.addMarker(myLocationMarker);
        } else {
            myMarker.remove(); // 마커삭제
            myLocationMarker.position(curPoint);
            myMarker = map.addMarker(myLocationMarker);
        }

        // 반경추가
        if (circle1KM == null) {
            circle1KM = new CircleOptions().center(curPoint) // 원점
                    .radius(1000)       // 반지름 단위 : m
                    .strokeWidth(1.0f);    // 선너비 0f : 선없음
            //.fillColor(Color.parseColor("#1AFFFFFF")); // 배경색
            circle = map.addCircle(circle1KM);

        } else {
            circle.remove(); // 반경삭제
            circle1KM.center(curPoint);
            circle = map.addCircle(circle1KM);
        }


    }

⛔구글맵이 UI에 나타나지 않는 오류

구글맵이 나타나야할 fragment 위치에 구글맵이 나타나지 않았다...😭

안드로이드 스튜디오 run 로그를 확인해보니 다음과 같은 에러메세지가 떠있었다.

오류 내용을 보면 Google Maps Android API v2가 활성화되어있는지 확인하라는 것인데,
1. Google API 키
2. SHA-1 인증서 디지털 지문
3. 패키지 이름 (com.으로 시작)
이다.

전부 구글 클라우드에서 맞게 설정했는데도 오류가 나서 미칠 노릇이였다 ㅠㅠㅠㅠ
검색에 검색을 하다 발견한 사실,,, 구글맵이 유료화가 되었다는 것...ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ


구글 API 서비스에서 라이브러리에서 구글맵을 사용 선택한 계정만이
API Key로 안드로이드에서 구글맵 사용을 할 수 있었던 것이다 ㅎㅎ
이를 위해서는 결제 계정 등록이 필요하고..ㅎㅎ

그런데 내가 원래 학교 계정으로 구글 클라우드 계정 쓰고 있었는데 설상가상으로 학교 계정은 왠지 모르지만 결제카드 등록이 안돼서 결국 내 개인계정으로 프로젝트 새로 팜..ㅎㅎ


드디어 구글맵이 UI에 띄워졌다...후

위치정보 firebase와 연동하기

GPS 클래스에서 firebase의 값을 update 하는 부분을 추가했다!
requestLocationUpdates 할 때마다 firebase 도 같이 업데이트 되도록 아래 코드는 requestLocationUpdates가 실행되는 부분에 작성하였다.

private void updateUserLocation(double latitude, double longitude) {
        UserLocation data = new UserLocation(userid,latitude,longitude);

        mDatabase.child("userlocation").child(userid).setValue(data)
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        // Write was successful!
                        Log.d("Firebase","UserLoctaion update success");
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        // Write failed
                        Log.d("Firebase","UserLoctaion update failed");
                    }
                });

    }

⛔ 실시간 위치 지속적 감지 안됨 💥

그 결과 firebase에는 값이 제대로 담겼지만,,,
한 가지 문제가 발생했다..
원래 requestLocationUpdates 가 자동으로 10초마다( 설정한 시간) 실행이 되는 줄 알았는데 로그 찍어보니까 처음 한 번 위치 불러올때만 실행되고 지속적인 위치변화 감지는 하고 있지 않았다.
따라서 firebase에도 한 번 위치 정보가 들어갈 뿐 위치 변화가 지속적으로 update 되지는 않았다.....
내가 requestLocationUpdates 개념을 잘 몰라서 그런거 같은데 ㅠㅠ 이거 찾아봐서 내일 보완해야 할 것 같다.

0개의 댓글