[Firebase] 5. 파이어베이스(Firebase) 실시간 데이터베이스. 가장 가까운 곳에 있는 유저 찾기 (1)

in #kr-dev6 years ago


안녕하세요! @gbgg입니다.
이번 포스팅에서는 가장 가까운 위치에 있는 유저를 찾기위한 사전작업을 진행해볼까 합니다.
GPS, WiFI를 통해 현재 위치의 경도, 위도를 알아낸 뒤 이 값으로 현재 위치 값을 표시해 보겠습니다.
다음 포스팅에서는 경도, 위도, 주소값을 파이어베이스 데이터베이스에 저장하고 가장 가까운 거리에 있는 유저를 찾아보겠습니다.

제가 전문가가 아니다보니 부족한 점이나 잘못된 부분이 있을 수 있습니다. 피드백 주시면 즉시 반영하겠습니다.


실시간 데이터베이스
개발할 앱/웹 등이 정보를 제공하거나 받아와야 할 경우, 또는 데이터를 주고 받아야 할 경우 등등 데이터베이스 기능은 개발에 있어 필수라고 생각합니다. 파이어베이스에서는 다양한 백엔드 서비스를 제공하고 있는데 그 중 가장 대표적인 기능이 '실시간 데이터베이스' 입니다.

이번 포스팅에서는 GPS, WIFI를 통해 현재 위치의 위도와 경도를 알아낸 뒤 이 데이터들도 주소값까지 추출해보겠습니다.

이번 포스팅은 다음 포스팅에서의 거리 측정 작업을 위한 안드로이드 앱 개발 포스팅입니다. 파이어베이스에 관한 내용은 없습니다.


준비물
1. Google 계정
2. Android Studio 1.5 이상

앱 개발을 위해 안드로이드 스튜디오를 설치하였습니다.
위 링크로 들어가셔서 다운받으시면 됩니다.


시스템 구성도

먼저 어떤식으로 가까운 유저를 찾아낼 지 간략하게 구성도로 표시해보겠습니다.

파이어베이스에서 데이터를 전송한다기보다는 앱에서 호출한다고 볼 수 있습니다. 다만 이해를 위해 위와 같이 표시해 보았습니다.

앱에서 현재 유저의 위도, 경도, 주소 값을 업데이트하여 특정 child에 전송합니다.
이 값들은 파이어베이스의 한 child에 쌓여있고 앱에서 자신의 토큰값을 가진 child의 위도 경도 값과 다른 모든 유저들의 위도 경도 값을 대조하여 가장 가까운 유저를 찾아냅니다.
찾아낸 유저의 토큰값으로 해당 유저정보를 가져오고 거리를 표시합니다.

유저와의 거리 측정은 생각보다 많은 어플리케이션에서 사용됩니다.
근처 맛집을 찾아주는 앱, 주변 사용자를 찾아주는 채팅 앱 등등 많은 앱에서 상호간의 거리를 측정하여 위치와 정보를 표시하는 등 다양하게 사용되고 있습니다.

이러한 기능들을 파이어베이스를 통해 아주아주 간단하게 구현해 보겠습니다.
구현에 앞서 앱에서 위도와 경도, 주소값을 알아내야합니다. 그 부분부터 진행해보겠습니다.


앱 디자인

가장 먼저 위도와 경도를 표시할 EditText 2개와 버튼 두개를 생성해보겠습니다.
지난 포스팅에서 진행했던 부분 아래에 추가하였습니다. 파란색으로 드래그해둔 부분만 생성하시면 됩니다.


위도, 경도 찾기

위도와 경도를 찾기 위해서는 인터넷과 위치정보서비스 두 가지 권한이 필요합니다.

좌측에 있는 메뉴에서 [AndroidManifest.xml] 을 클릭합니다.

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

위 두가지 퍼미션을 추가합니다.

API 23: Android 6.0 (Marshmallow)버젼 이상에서 작업 시 'Call requires permission which may be rejected by user' 에러가 발생할 수 있습니다.

이럴 땐 위 사진 처럼 아래 퍼미션도 추가해주면 됩니다.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>


좌측에 있는 메뉴에서 [MainActivity.java] 를 클릭합니다.

위 앱디자인에서 생성한 버튼 view들을 연결하기 위해 Button 2개와 EditText 2개, 위도 경도값 저장을 위한 Double형 변수 2개를 선언합니다.

    private Button sendbt_location;
    private Button sendbt_location2;
    private EditText editdt_latitude;
    private EditText editdt_longitude;

    private Double longitude = null;
    private Double latitude = null;

onCreate 아래에 View 4개를 연결하겠습니다.
뷰 이름은 각각 editdt_latitude, editdt_longitude, sendbt_location, sendbt_location2로 설정하였습니다.

editdt_latitude = (EditText) findViewById(R.id.editText3);
editdt_longitude = (EditText) findViewById(R.id.editText4);
sendbt_location = (Button) findViewById(R.id.button4);
sendbt_location2 = (Button) findViewById(R.id.button5);

sendbt_location 에 대한 클릭 리스너를 생성한 뒤 위치 갱신을 위한 메소드를 입력합니다.

위치 공급자는 네트워크로, 메소드명은 'locationListener'로 설정하겠습니다.

sendbt_location.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                
                LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

                lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,100,1, locationListener);

            }
        });

locationListener에 대한 클래스를 생성하였습니다.

location에 관한 이벤트는 위와 같이 여러가지가 있습니다. 이 중 위도와 경도만 사용하였습니다.

처음에 생성한 Double형 변수에 longitude = location.getLongitude(); 값을 저장합니다.
editdt_latitude.setText("" + longitude); EditText에는 setText를 사용하여 값을 넣어보겠습니다.

private LocationListener locationListener = new LocationListener() {

        @Override
        public void onLocationChanged(Location location) {

            longitude = location.getLongitude();
            latitude = location.getLatitude();

            editdt_latitude.setText("" + longitude);
            editdt_longitude.setText("" + latitude);
        }

        @Override
        public void onProviderDisabled(String provider) {}

        @Override
        public void onProviderEnabled(String provider) {}

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

    };

이제 위도와 경도 값은 EditText에 표시됩니다. 이 값을 사용하여 주소 값을 가져오려면 우선 갱신을 멈춰야합니다.

lm.removeUpdates(locationListener); 이 명령어를 넣으면 위치갱신이 중단됩니다.
위치 갱신을 중단한 후 getLocation 메소드를 호출하여 주소값을 가져와보겠습니다.

버튼2에 대한 리스너를 생성하고 다음과 같이 입력합니다.

sendbt_location2.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
                lm.removeUpdates(locationListener);
                getLocation(latitude,longitude);
            }
        });


lat, lng 인자값을 갖는 getLocation 를 생성합니다.

Geocoder geocoder = new Geocoder(this, Locale.KOREAN);

구글에서 제공하는 GeoCoding 서비스는 좌표(위도, 경도)를 주소로 변환하거나 반대로 주소를 좌표(위도,경도)로 변환시켜주는 서비스입니다.
이 서비스를 사용하기 위해 Geocoder 객체를 생성합니다.

List<Address> addresses = geocoder.getFromLocation(lat, lng, 1);
getFromLocation(위도, 경도, 얻을 값의 개수)

다음과 같이 입력합니다.

    public void getLocation(double lat, double lng){
        String addressString = null;
        Geocoder geocoder = new Geocoder(this, Locale.KOREAN);

        try {
            List<Address> addresses = geocoder.getFromLocation(lat, lng, 1);
            if (addresses.size() > 0) {
                addressString = addresses.get(0).toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(addressString);
    }

결과

자! 완료되었습니다.
위,경도받기 버튼을 누르면 EditText에 위도와 경도 값이 표시되고
주소 받기 버튼을 누르면 addressString 변수에 주소값이 전달됩니다.


위도와 경도 값을 받은 결과입니다.
주소받기 버튼을 클릭하면 갱신이 중단됩니다.


addressString 값을 표기한 결과입니다.
아파트 동호수까지 상세하게 나오길래 어쩔수 없이 모자이크처리 했습니다;;


Firebase 실시간 데이터베이스
이번 포스팅에서 얻은 데이터들을 이제 파이어베이스와 연동하여 가장 가까운 유저를 찾아보겠습니다.

다음 포스팅에서 찾아뵙겠습니다! @gbgg


지난 포스팅
[Firebase] 1. 혁신적인 백엔드플랫폼 파이어베이스(Firebase)
[Firebase] 2. 파이어베이스(Firebase) 실시간 데이터베이스에 데이터 쓰기 (app)
[Firebase] 3. 파이어베이스(Firebase) 실시간 데이터베이스 불러오기, 리스트에 내용 표시하기
[Firebase] 4. 파이어베이스(Firebase) 실시간 데이터베이스. Token값으로 UserProfile 관리하기

Sort:  

오 안녕하세요! 저도 앱개발쪽 공부하고있습니다 :)
좋은글 잘보고갑니다!

오 안녕하세요! 앱개발하시는 분이시군요!
팔로우하고 자주 찾아뵙겠습니다 ㅎㅎ 감사합니다.

Very good appl you.

thank you! :)

흥미로운데 제가 지금 상황이 상황인지라 나중에 다시 보겠습니다.

아침에 해장은 잘 하셨습니까!ㅋㅋㅋ

짱짱맨 호출로 왔습니다!
한주 수고하세요
코인거래소인 고팍스에서 멋진 이벤트중이네요!
https://steemit.com/kr/@gopaxkr/100-1-1

항상 감사합니다! ^^

와우
전문가시네요
전 기계치 ㅠㅠ
링크 복사해서 남편에게 보여주께요^^

감사합니다 ㅎㅎ 전 jsj1215님 글솜씨는 발끝도 못따라갑니다 ㅋㅋㅋ

음... 솔직히 아무리 봐도 다시봐도 모르겠네요....ㅠㅠ
맨처음 그림으로 설명해 주셔서 기본개념은 알겠는데...
이렇게 하는게 우선 자신 위치 정보 제공 동의 한 사람에 한해서 수집되는 게 맞죠? 아니면 무작위로 수집되고 제공한 사람만 열람 가능 하게 하는 건지....

넵 자신이 개인정보 동의한 사람만 데이터가 넘어가고 그렇게 모인 데이터들로 가까운사람을 찾아냅니다!ㅎㅎ

문과출신인 전 와~~~~~~~~~~~~ 하고 볼뿐이네요 ㅎㅎㅎㅎ
팔로우하고갈게요 ^^

맞팔할게요 읽어주셔서 감사합니다!! ㅎㅎ

와우^^ 포스팅이 알찬내용들 입니다
잘모르지만 찬찬히 읽고 제나름데로 포스팅해서 배워나가야 할것같습니다^^ 정말 잘보고 갑니다
또 방문자주 드리겠습니다

감사합니다! 저도 자주 방문하겠습니다 :)

ㅎㅎㅎ어렵네요 정말 ㅎ저런걸 어찌하면 잘할수있는거죠
초보인 저는 그냥 머리속이 하얗게되는데요 ㅎㅎㅎ 대단한능력이신거같아요 ㅎㅎㅎ 저도 저런 능력있으면 좋겠지만 ㅎㅎ 머리가 살짝 나쁜관계로 마냥 부러워만하고갑니다

저도 따로 배운게 아니라서 아직 초보랍니다 ㅠㅠ 잘 봐주셔서 감사합니다 ㅎㅎ :)

Coin Marketplace

STEEM 0.17
TRX 0.15
JST 0.028
BTC 62025.78
ETH 2417.09
USDT 1.00
SBD 2.49