인프런 커뮤니티 질문&답변

dddk11님의 프로필 이미지
dddk11

작성한 질문수

[2023 코틀린 강의 무료제공] 기초에서 수익 창출까지, 안드로이드 프로그래밍 A-Z

위치 가져오기 - 메인 액티비티 지오코딩 (2)

tvLocationTitle이 Null이에요 ㅠ

작성

·

491

·

수정됨

0

캡처.JPG

어떤 부분이 문제인지 혼자 머리 싸매고 고민해봐도 영 답이 없네요 ㅠ

밑에는 Logcat(location), LocationProvider,MainActivity 코드 내용 입니다!

 

2023-07-09 00:55:07.703 8921-8921 m.dk.airQualit com.dk.airQuality W DexFile /data/data/com.dk.airQuality/code_cache/.studio/instruments-234ebcbd.jar is in boot class path but is not in a known location

2023-07-09 00:55:07.725 8921-8921 m.dk.airQualit com.dk.airQuality W Accessing hidden method Landroid/app/LoadedApk$ReceiverDispatcher;->setUnregisterLocation(Ljava/lang/RuntimeException;)V (greylist-max-o, linking, denied)

2023-07-09 00:55:07.725 8921-8921 m.dk.airQualit com.dk.airQuality W Accessing hidden method Landroid/app/LoadedApk$ReceiverDispatcher;->getUnregisterLocation()Ljava/lang/RuntimeException; (greylist-max-o, linking, denied)

2023-07-09 00:55:07.725 8921-8921 m.dk.airQualit com.dk.airQuality W Accessing hidden method Landroid/app/LoadedApk$ServiceDispatcher;->getUnbindLocation()Ljava/lang/RuntimeException; (greylist-max-o, linking, denied)

2023-07-09 00:55:22.314 8996-8996 m.dk.airQualit com.dk.airQuality W DexFile /data/data/com.dk.airQuality/code_cache/.studio/instruments-234ebcbd.jar is in boot class path but is not in a known location

2023-07-09 00:55:22.341 8996-8996 m.dk.airQualit com.dk.airQuality W Accessing hidden method Landroid/app/LoadedApk$ReceiverDispatcher;->setUnregisterLocation(Ljava/lang/RuntimeException;)V (greylist-max-o, linking, denied)

2023-07-09 00:55:22.341 8996-8996 m.dk.airQualit com.dk.airQuality W Accessing hidden method Landroid/app/LoadedApk$ReceiverDispatcher;->getUnregisterLocation()Ljava/lang/RuntimeException; (greylist-max-o, linking, denied)

 

답변 3

0

실제로 특정단말(?) 저는 VM사용 안하였고 실제 단말로 개발중인데, 정말 null이 맞는것 같습니다.

아래는 디버깅모드에서 address를 확인해봤습니다.

저는 subLocality를 사용했습니다.

수고하세요.

0

Code With Joyce님의 프로필 이미지
Code With Joyce
지식공유자

안녕하세요, kbs님~ ^^

혹시 null 이 뜰 때 Toast 문구는 뭐라고 나오나요?

그리고 현재 if 문을 많이 써서 어디서 Null 이 Return 이 되는지를 정확히 알면 에러를 고치는 데에 도움이 될 것 같습니다. Log.d("Debug","여기 1"), Log.d("Debug","여기 2") 이런 식으로 분기마다 로그를 찍어서 어디서 null 이 반환되는지 알려주세요. 같이 에러를 해결해봐요~ㅎㅎ

 

감사합니다!

0

안녕하세요, 인프런 AI 인턴이에요. tvLocationTitle이 null인 문제를 알려주셨는데요, 로그캣에 있는 내용만으로는 정확한 원인을 파악하기 어렵습니다. 따라서, 코드 내용을 확인해야 정확한 도움을 드릴 수 있을 것 같아요. 코드 내용을 공유해주실 수 있을까요? 로그캣 이외에도 코드 부분을 확인하여 도움을 드리도록 하겠습니다. 감사합니다~

dddk11님의 프로필 이미지
dddk11
질문자

MainActivity,locationProvider 코드입니다.

class MainActivity : AppCompatActivity() {

    lateinit var binding : ActivityMainBinding
    lateinit var locationProvider : LocationProvider

    private val PERMISSON_REQUEST_CODE = 100

    val REQUIRED_PERMISSONS = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )

    lateinit var getGPSPermissionLauncher: ActivityResultLauncher<Intent>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        checkAllPermissions()
        updateUI()
    }

    private fun updateUI(){
        locationProvider = LocationProvider(this@MainActivity)

        val latitude: Double? = locationProvider.getLocationLatitude()
        val longitude: Double? = locationProvider.getLocationLongitude()

        if (latitude != null && longitude != null) {
            val address = getCurrentAddress(latitude, longitude)
            address?.let{
                binding.tvLocationTitle.text = "${it.thoroughfare}" //현재 위치
                binding.tvLocationSubtitle.text = "${it.countryName} ${it.adminArea}"//나라이름
            }
        } else {
            Toast.makeText(this, "위도, 경도를 가져올수 없습니다", Toast.LENGTH_LONG).show()
        }
    }

    private fun getCurrentAddress (latitude : Double, longitude : Double) : Address?{
        val geoCoder = Geocoder(this, Locale.KOREA)
        val addresses : List<Address>

        addresses = try {
            geoCoder.getFromLocation(latitude, longitude, 7)
        } catch (ioException: IOException) {
            Toast.makeText(this, "지오코더 서비스를 이용할수 없습니다.", Toast.LENGTH_LONG).show()
            return null
        } catch (illegalArgumentException: java.lang.IllegalArgumentException) {
            Toast.makeText(this, "잘못된 위도, 경도 입니다.", Toast.LENGTH_LONG).show()
            return null
        }
        if(addresses == null || addresses.size == 0){
            Toast.makeText(this, "주소가 발견되지 않았습니다.", Toast.LENGTH_LONG).show()
            return null
        }
        return addresses[0]
    }
    private fun checkAllPermissions() {
        if(!isLocationServicesAvailable()){
            showDialogForLocationServicesSetting()
        }else{
            isRunTimePermissionsGranted()
        }
    }

    private fun isLocationServicesAvailable(): Boolean {
        val locationManager = getSystemService(LOCATION_SERVICE) as LocationManager

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

    private fun isRunTimePermissionsGranted() {
        val hasFineLocationPermission = ContextCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
        val hasCoarseLocationPermission = ContextCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )

        if (hasFineLocationPermission != PackageManager.PERMISSION_GRANTED || hasCoarseLocationPermission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                this@MainActivity,
                REQUIRED_PERMISSONS,
                PERMISSON_REQUEST_CODE
            )
        }
    }
        override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<out String>,
            grantResults: IntArray
        ) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            if (requestCode === PERMISSON_REQUEST_CODE && grantResults.size == REQUIRED_PERMISSONS.size) {
                var checkResult = true

                for (result in grantResults) {
                    if (result != PackageManager.PERMISSION_GRANTED) {
                        checkResult = false
                        break;
                    }
                }
                if (checkResult) {
                    updateUI()

                }else {
                    Toast.makeText(this@MainActivity,"퍼미션이 거부되었습니다. 앱을 다시 실행하여 퍼미션을 허용하십시오", Toast.LENGTH_LONG).show()
                    finish()
                }
            }
        }

    private fun showDialogForLocationServicesSetting() {
        getGPSPermissionLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ){
            result ->
            if (result.resultCode == Activity.RESULT_OK) {
                if (isLocationServicesAvailable()) {
                    isRunTimePermissionsGranted()
                }else{
                    Toast.makeText(this@MainActivity,"위치 서비스를 사용할 수 없습니다.", Toast.LENGTH_LONG).show()
                    finish()
                }
            }
        }

        val builder: AlertDialog.Builder = AlertDialog.Builder(this@MainActivity)
        builder.setTitle("위치 서비스 비활성화")
        builder.setMessage("위치 서비스가 꺼져있습니다. 설정해야 앱을 사용할 수 있습니다.")
        builder.setCancelable(true)
        builder.setPositiveButton("설정", DialogInterface.OnClickListener{
            dialogInterface, i -> val callGPSSettingIntent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
            getGPSPermissionLauncher.launch(callGPSSettingIntent)
        })
        builder.setNegativeButton("취소", DialogInterface.OnClickListener{
            dialogInterface, i -> dialogInterface.cancel()
            Toast.makeText(this@MainActivity,"위치 서비스를 사용할 수 없습니다.", Toast.LENGTH_LONG).show()
            finish()
        })
        builder.create().show()
    }

}

class LocationProvider(val context: Context) {
    private var location: Location? = null
    private var locationManager: LocationManager? = null

    init{
        getLocation()
    }

    private fun getLocation() : Location?{
        try {
            locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager

            var gpsLocation: Location? = null
            var networkLocation: Location? = null

            var isGPSEnabled = locationManager!!.isProviderEnabled(LocationManager.GPS_PROVIDER)
            var isNetworkEnabled = locationManager!!.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

            if (!isGPSEnabled && !isNetworkEnabled) {
                return null
            }else{
                if (ActivityCompat.checkSelfPermission(
                    context,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                    context,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                return null
            }
                if (isNetworkEnabled) {
                    networkLocation = locationManager?.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
                }

                if (isGPSEnabled) {
                    gpsLocation = locationManager?.getLastKnownLocation(LocationManager.GPS_PROVIDER)
                }
                if (gpsLocation != null && networkLocation != null) {
                    if (gpsLocation.accuracy > networkLocation.accuracy) {
                        location = gpsLocation
                    }else{
//                        location = networkLocation
                        location = gpsLocation
                    }
                }else{
                    if (gpsLocation != null) {
                        location = gpsLocation
                    }
                    if (networkLocation != null) {
                        location = networkLocation
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return location
    }

    fun getLocationLatitude(): Double? {
        return location?.latitude
    }
    fun getLocationLongitude(): Double? {
        return location?.longitude
    }
}
dddk11님의 프로필 이미지
dddk11

작성한 질문수

질문하기