티스토리 뷰

프로젝트를 기획할 때 구현하고자 했던 기능들을 전부 구현하고 프로젝트 막바지가 되었는데

살짝 욕심이 생겨서 지도 기능을 하나 더 구현해보고자 여기저기 찾아봤습니다.

 

api를 가져다가 사용하면 된다고 생각하여 쉽게 구현하겠지 생각했는데

같은 오류에 부딪혀서 카카오와 구글 맵 둘 다 실패를 겪었습니다.

 

여기서 부딪힌 오류는 지도를 불러오지 못한다는 내용이었는데

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.SupportMapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference

해당 종류의 오류가 계속 발생했습니다.

 

이때 해결방법으로 가장 많았던 내용은

 

        SupportMapFragment mapFragment = (SupportMapFragment) this.getChildFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

지도 프래그먼트를 불러올 때 해당 코드로 변경을 해보라는 것이었지만 

 

getChildFragmentManger() 를 불러올 수 없어 다시 한번 벽에 부딪혔습니다 ㅠㅠ

시간이 얼마 남지 않아서 이대로 포기해야 하나 싶었지만 

 

오늘 다시 한번 시도한 끝에 결국 구현을 할 수 있었습니다.

 



import android.annotation.TargetApi;
        import android.content.Context;
        import android.content.Intent;
        import android.content.pm.PackageManager;
        import android.location.Location;
        import android.location.LocationManager;
        import android.os.Build;
        import android.os.Bundle;
        import android.util.Log;
        import android.widget.Toast;

        import androidx.appcompat.app.AppCompatActivity;
        import androidx.core.app.ActivityCompat;
        import androidx.core.content.ContextCompat;

        import com.google.android.gms.maps.CameraUpdateFactory;
        import com.google.android.gms.maps.GoogleMap;
        import com.google.android.gms.maps.OnMapReadyCallback;
        import com.google.android.gms.maps.SupportMapFragment;
        import com.google.android.gms.maps.model.LatLng;
        import com.google.android.gms.maps.model.MarkerOptions;

public class MapActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private long backpressedTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

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

        if (permissionCheck == PackageManager.PERMISSION_DENIED) { //포그라운드 위치 권한 확인

            //위치 권한 요청
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 0);
        }


        int permissionCheck2 = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_BACKGROUND_LOCATION);

        if (permissionCheck == PackageManager.PERMISSION_DENIED) { //백그라운드 위치 권한 확인
            //위치 권한 요청
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 0);
        }

    }
    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * <p>
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // 구글에서 등록한 api와 엮어주기

        // 시작위치를 서울 시청으로 변경

        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Location loc_currnt = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

        LatLng currnt = new LatLng(loc_currnt.getLatitude(), loc_currnt.getLongitude());

        googleMap.moveCamera(CameraUpdateFactory.newLatLng(currnt));

        googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));

        MarkerOptions markerOptions = new MarkerOptions();

        markerOptions.position(currnt);

        markerOptions.title("내 위치");

        markerOptions.snippet("내 위치");

        googleMap.addMarker(markerOptions);


//        //맵 로드 된 이후
//
//        googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
//
//            @Override
//
//            public void onMapLoaded() {
//
//                Toast.makeText(MapActivity.this, "Map로딩성공", Toast.LENGTH_SHORT).show();
//
//
//            }
//
//        });

        //카메라 이동 시작

        googleMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {

            @Override

            public void onCameraMoveStarted(int i) {

                Log.d("set>>", "start");

            }

        });

        // 카메라 이동 중

        googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {

            @Override

            public void onCameraMove() {

                Log.d("set>>", "move");

            }

        });

        // 지도를 클릭하면 호출되는 이벤트

        googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

            @Override

            public void onMapClick(LatLng latLng) {

                // 기존 마커 정리

//                googleMap.clear();


                // 클릭한 위치로 지도 이동하기

                googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));


                // 신규 마커 추가

//                MarkerOptions newMarker = new MarkerOptions();
//
//                newMarker.position(latLng);
//
//                googleMap.addMarker(newMarker);

            }

        });

    }


    @TargetApi(Build.VERSION_CODES.M)

    private void checkPermission() {

        String[] permissions = {

                // Manifest는 android를 import

                android.Manifest.permission.ACCESS_COARSE_LOCATION,

                android.Manifest.permission.ACCESS_FINE_LOCATION

        };


        int permissionCheck = PackageManager.PERMISSION_GRANTED;

        for (String permission : permissions) {

            permissionCheck = this.checkSelfPermission(permission);

            if (permissionCheck == PackageManager.PERMISSION_DENIED) {

                break;

            }

        }


        if (permissionCheck == PackageManager.PERMISSION_DENIED) {

            this.requestPermissions(permissions, 1);

        }

    }

    @Override
    public void onBackPressed() {

        if (System.currentTimeMillis() > backpressedTime + 2000) {
            backpressedTime = System.currentTimeMillis();
            Toast.makeText(this, "한번 더 누르면 종료됩니다.", Toast.LENGTH_SHORT).show();
        } else if (System.currentTimeMillis() <= backpressedTime + 2000) {
            Intent intent = new Intent(MapActivity.this, Main2Activity.class);
            startActivity(intent);
            overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
            finish();
        }
    }
}

코드는 해당 방식으로 구현했습니다.

 

지도로 이동하기 전 권한 설정을 통해서 

권한이 부여되었으면 설정 한 지도의 마커등이 표기되는 방식입니다.

처음 위치는 현재 자신의 위치를 GPS를 통해 불러와 설정해주었습니다.

 

급하게 구현해서 아직 부족한 부분이 많긴 하지만 

첫발은 땐거 같아 그래도 다행이라고 생각이 들었습니다.

 

이후 해결할 문제는 

현재 권한을 부여하지 않았을 때 해당 화면으로 이동을 못하게 하려 했는데

권한이 없어도 화면으로는 이동되지만 코드에 구현한 내용들을 불러오지 못하고 있는 문제가 있습니다.

 

또한 지금은 테스트로 몇개의 마커만 지정해놓았지만 

지도 기능이 실용적이 되려면 구글맵에 있는 모든 복지센터와 주민센터 같은 

위치정보를 긁어오는 노가다가 필요할 거 같습니다 ㅠ..

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함