카카오내비 SDK와 관련된 질문과 답변을 올리는 카테고리입니다.
KNSDK_UI 최초 실행시 맵 표시 안되는 현상이 계속발생되고 있습니다.
적용버전은 1.10.5 이며 맵은 별도로 생성하지 않았습니다. 개발은 튜토리얼 보고 진행했습니다. 내비 소스 첨부합니다.
확인부탁드립니다.
class NaviActivity: AppCompatActivity(),KNGuidance_GuideStateDelegate , KNGuidance_LocationGuideDelegate,KNGuidance_RouteGuideDelegate
,KNGuidance_SafetyGuideDelegate, KNGuidance_VoiceGuideDelegate, KNGuidance_CitsGuideDelegate, KNNaviView_GuideStateDelegate
{
lateinit var naviView:KNNaviView
// 경로 옵션 설정
val curRoutePriority = KNRoutePriority.KNRoutePriority_Recommand // 경로 안내에서 우선적 고려 항목
// private lateinit var fusedLocationClient: FusedLocationProviderClient
private var lan=""
private var lat=""
private var addr=""
private var name=""
private var id=""
override fun onDestroy() {
super.onDestroy()
KNSDK.sharedGuidance()?.stop()
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// return true//2022.02.21 백키 적용되도록 주석처리함.
guidanceGuideEnded(naviView.guidance)
}
return super.onKeyDown(keyCode, event)
}
private var curAvoidOptions:Int = KNRouteAvoidOption.KNRouteAvoidOption_MotorWay.value
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navi)
naviView = findViewById(R.id.navi_view)
var cartype = carTypeWithIdx(intent?.getStringExtra("CarType").toString()?:"6")
var CarHeight = intent.getStringExtra("CarHeight")?.toString()?:"-1"
var CarWeight = intent.getStringExtra("CarWeight")?.toString()?:"-1"
var CarWidth = intent.getStringExtra("CarWidth")?.toString()?:"-1"
var CarLength = intent.getStringExtra("CarLength")?.toString()?:"-1"
var KnRoutePriority = intent.getStringExtra("KNRoutePriority")?.toString()?:"0" //내비추천:0, 최소시간:1, 큰길우선:4
lan = intent.getStringExtra("lan").toString()
lat = intent.getStringExtra("lat").toString()
addr = intent.getStringExtra("address").toString()
name = intent.getStringExtra("name").toString()
id = intent.getStringExtra("pcode").toString()
naviView.bottomMenuComponent
naviView.carType = cartype/*0 [1종 소형차], 1 [2종 중형차] , 2 [3종 대형차] , 3 [4종 대형 화물차] , 4 [5종 특수 화물차 ], 5 [6종 경차], 6 [이륜차] */
naviView.fuelType=fuelTypeWithIdx(intent?.getStringExtra("FulType")?.toString()?:"0")/*0 [휘발류(가솔린)] , 1 [고급 휘발류] , 2 [경유(디젤)] , 3 [LPG (액화 석유 가스)] , 4 [전기] , 5 [하이브리드 전기 ], 6 [플러그인(Plug-in) 하이브리드 전기] , 7 [수소] */
var avoid =intent.getStringExtra("KNRouteAvoidOption")?.toString()?:""
var aAvoidOption: Int = 0;
if(avoid.length>0){
var obj: JSONObject? = null
try {
obj = JSONObject(avoid)
} catch (e: Exception) {
return
}
var len = obj.length()
var RoadEven = obj.get("KNRouteAvoidOption_RoadEvent")
selectAvoidOption(if (RoadEven.equals("Y")) true else false, KNRouteAvoidOption.KNRouteAvoidOption_RoadEvent)// 경로 회피 구간-유고 정보 구간회피 0x0001
var Farries = obj.get("KNRouteAvoidOption_Farries")
selectAvoidOption(if (Farries.equals("Y")) true else false, KNRouteAvoidOption.KNRouteAvoidOption_Farries)//페리 항로 구간 회피(페리포함): 0x0002
var Fare = obj.get("KNRouteAvoidOption_Fare")
selectAvoidOption(if (Fare.equals("Y")) true else false, KNRouteAvoidOption.KNRouteAvoidOption_Fare)//유료 도로 구간 회피(무료도로): 0x0004
var UTurn = obj.get("KNRouteAvoidOption_UTurn")
selectAvoidOption(if (UTurn.equals("Y")) true else false, KNRouteAvoidOption.KNRouteAvoidOption_UTurn)//유턴 구간 회피(유턴제외): 0x0010
var MotorWay = obj.get("KNRouteAvoidOption_MotorWay")
selectAvoidOption(if (MotorWay.equals("Y")) true else false, KNRouteAvoidOption.KNRouteAvoidOption_MotorWay)//자동차 전용 도로 구간 회피(자동차전용제외):0x0008 => 이륜차로 세팅되어 이값은 변경하면 안됨... .변경하려면 아래 CarType 도 함께 변경할 것.
var SZone = obj.get("KNRouteAvoidOption_SZone")
selectAvoidOption(if (SZone.equals("Y")) true else false, KNRouteAvoidOption.KNRouteAvoidOption_SZone)//교통 약자 보호 구간 회피(어린이안심): 0x0020
}
else{
val bikeMode = cartype== KNCarType.KNCarType_Bike
if(bikeMode)
selectAvoidOption(true,KNRouteAvoidOption.KNRouteAvoidOption_MotorWay )
}
// fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)//현재 위치정보
// status bar 영역까지 사용하기 위한 옵션
window?.apply{
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) {
setDecorFitsSystemWindows(false)
insetsController?.hide(WindowInsets.Type.systemBars() or WindowInsets.Type.navigationBars())
insetsController?.systemBarsBehavior= WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
else{
statusBarColor = Color.TRANSPARENT
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
}
}
val nowPos = (KNSDK.sharedGpsManager()?.lastValidGpsData?.pos ?: FloatPoint(314870f,542995f))
checkPermission();
// requestRoute();
}
/**
* 주행 경로를 요청합니다.
*/
fun requestRoute(){
Thread{
var point: DoublePoint = KNApplication.knsdk.convertWGS84ToKATEC(lan.toDouble(),lat.toDouble())//목적지
var curPoint:DoublePoint = KNSDK.sharedGpsManager()?.recentGpsData?.pos?:DoublePoint(
KN_DEFAULT_POS_X.toDouble(), KN_DEFAULT_POS_Y.toDouble())
// val nowPos = (KNSDK.sharedGpsManager()?.lastValidGpsData?.pos ?: FloatPoint(314870f,542995f))
// 출발지와 목적지를 설정합니다.//KATEC좌표계
val startPoi = KNPOI("현위치", curPoint.x.toInt(),curPoint.y.toInt(),"현위치")//val startPoi = KNPOI("현위치", (KNSDK.sharedGpsManager()?.lastValidGpsData?.pos?.x?.toInt():314870))// val startPoi = KNPOI("현위치", 309840,552483,"현위치")
val goalPoi = KNPOI(name, point.x.toInt(),point.y/*.toString().split(".")[0]*/.toInt(),addr)//val goalPoi = KNPOI("목적지", 321497,532896,"목적지")
KNApplication.knsdk.makeTripWithStart(
aStart = startPoi,
aGoal = goalPoi,
aVias = null
)
{ aError, aTrip ->
//경로 요청이 성공하면 aError는 Null이 됩니다.
if (aError == null) {
startGuide(aTrip)
}
}
}.start()
}
/**
* 주행 구성하기
*/
fun startGuide(trip:KNTrip?){
KNApplication.knsdk.sharedGuidance()?.apply{
// guidance delegate 등록
locationGuideDelegate = this@NaviActivity
routeGuideDelegate = this@NaviActivity
safetyGuideDelegate = this@NaviActivity
voiceGuideDelegate = this@NaviActivity
citsGuideDelegate = this@NaviActivity
guideStateDelegate= this@NaviActivity
naviView.initWithGuidance(
this,
trip,
curRoutePriority,// 경로 안내에서 우선적 고려 항목
curAvoidOptions // 회피옵션
)
naviView.guideStateDelegate=this@NaviActivity
}
}
//GuideStateDelegate - 경로 변경 시 호출. 교통 변화 또는 경로 이탈로 인한 재탐색 및 사용자 재탐색 시 전달
override fun guidanceCheckingRouteChange(aGuidance: KNGuidance) {
naviView.guidanceRouteChanged(aGuidance)
}
override fun guidanceDidUpdateIndoorRoute(aGuidance: KNGuidance, aRoute: KNRoute?) {
TODO("Not yet implemented")
}
// 주행 중 기타 요인들로 인해 경로가 변경되었을 때 호출
override fun guidanceDidUpdateRoutes(
aGuidance: KNGuidance,
aRoutes: List<KNRoute>,
aMultiRouteInfo: KNMultiRouteInfo?
) {
naviView.guidanceDidUpdateRoutes(aGuidance,aRoutes,aMultiRouteInfo)
}
// 길 안내 종료 시 호출
override fun guidanceGuideEnded(aGuidance: KNGuidance) {
naviView.guidanceGuideEnded(aGuidance)
this.finish()
}
//
override fun naviViewGuideEnded(){
this.finish()
}
override fun naviViewGuideState(state: KNGuideState) {
}
//KNGuidance_GuideStateDelegate 길 안내 시작 시 호출
override fun guidanceGuideStarted(aGuidance: KNGuidance) {
naviView.guidanceGuideStarted(aGuidance)
}
// 경로에서 이탈한 뒤 새로운 경로를 요청할 때 호출
override fun guidanceOutOfRoute(aGuidance: KNGuidance) {
naviView.guidanceOutOfRoute(aGuidance)
}
// 수신 받은 새 경로가 기존의 안내된 경로와 다를 경우 호출. 여러 개의 경로가 있을 경우 첫 번째 경로를 주행 경로로 사용하고 나머지는 대안 경로로 설정됨
override fun guidanceRouteChanged(
aGuidance: KNGuidance,
aFromRoute: KNRoute,
aFromLocation: KNLocation,
aToRoute: KNRoute,
aToLocation: KNLocation,
aChangeReason: KNGuideRouteChangeReason
) {
naviView.guidanceRouteChanged(aGuidance)
}
//수신 받은 새 경로가 기존의 안내된 경로와 동일할 경우 호출
override fun guidanceRouteUnchanged(aGuidance: KNGuidance) {
naviView.guidanceRouteUnchanged(aGuidance)
}
// 경로에 오류가 발생 시 호출
override fun guidanceRouteUnchangedWithError(aGuidnace: KNGuidance, aError: KNError) {
naviView.guidanceRouteUnchangedWithError(aGuidnace, aError)
}
//LocationGuideDelegate--위치 정보가 변경될 경우 호출. `locationGuide`의 항목이 1개 이상 변경 시 전달됨.
override fun guidanceDidUpdateLocation(
aGuidance: KNGuidance,
aLocationGuide: KNGuide_Location
) {
naviView.guidanceDidUpdateLocation(aGuidance,aLocationGuide)
}
// RouteGuideDelegate --경로 안내 정보 업데이트 시 호출. `routeGuide`의 항목이 1개 이상 변경 시 전달됨.
override fun guidanceDidUpdateRouteGuide(aGuidance: KNGuidance, aRouteGuide: KNGuide_Route) {
naviView.guidanceDidUpdateRouteGuide(aGuidance,aRouteGuide)
}
//SafetyGuideDelegate
// 주변의 안전 운행 정보 업데이트 시 호출
override fun guidanceDidUpdateAroundSafeties(
aGuidance: KNGuidance,
aSafeties: List<KNSafety>?
) {
naviView.guidanceDidUpdateAroundSafeties(aGuidance,aSafeties)
}
// 안전 운행 정보 업데이트 시 호출. `safetyGuide`의 항목이 1개 이상 변경 시 전달됨.
override fun guidanceDidUpdateSafetyGuide(
aGuidance: KNGuidance,
aSafetyGuide: KNGuide_Safety?
) {
naviView.guidanceDidUpdateSafetyGuide(aGuidance,aSafetyGuide)
}
//VoiceGuideDelegate
// 음성 안내 종료
override fun didFinishPlayVoiceGuide(aGuidance: KNGuidance, aVoiceGuide: KNGuide_Voice) {
naviView.didFinishPlayVoiceGuide(aGuidance,aVoiceGuide)
}
// 음성 안내 사용 여부
override fun shouldPlayVoiceGuide(
aGuidance: KNGuidance,
aVoiceGuide: KNGuide_Voice,
aNewData: MutableList<ByteArray>
): Boolean {
return naviView.shouldPlayVoiceGuide(aGuidance,aVoiceGuide,aNewData)
}
// 음성 안내 시작
override fun willPlayVoiceGuide(aGuidance: KNGuidance, aVoiceGuide: KNGuide_Voice) {
naviView.willPlayVoiceGuide(aGuidance, aVoiceGuide)
}
//CitsGuideDelegate
// CITS 정보 변경 시 호출
override fun didUpdateCitsGuide(aGuidance: KNGuidance, aCitsGuide: KNGuide_Cits) {
naviView.didUpdateCitsGuide(aGuidance,aCitsGuide)
}
//MainActivity에 있던 기능들
/**
* GPS 위치 권한을 확인합니다.
*/
fun checkPermission() {
when {
checkSelfPermission(
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED -> {
// GPS 퍼미션 체크
gpsPermissionCheck()
}
else -> {
// 길찾기 SDK 인증
knsdkAuth()
}
}
}
/**
* GPS 위치 권한을 요청합니다.
*/
fun gpsPermissionCheck() {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
1234)
}
/**
* GPS 위치 권한 요청의 실패 여부를 확인합니다.
*/
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
1234 -> {
if (grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 다시 권한 요청하는 곳으로 돌아갑니다.
checkPermission()
}
}
}
}
/**
* 길찾기 SDK 인증을 진행합니다.
*/
fun knsdkAuth() {
KNApplication.knsdk.apply {
initializeWithAppKey(
aAppKey = BuildConfig.REAL_APP_KEY, // 카카오디벨로퍼스에서 부여 받은 앱 키
aClientVersion = BuildConfig.VERSION_NAME, // 현재 앱의 클라이언트 버전
aAppUserId, // 사용자 id
aLangType = KNLanguageType.KNLanguageType_KOREAN, // 언어 타입
aCompletion = {
// Toast는 UI를 갱신하는 작업이기 때문에 UIThread에서 동작되도록 해야 합니다.
runOnUiThread {
if (it != null) {
Toast.makeText(applicationContext, "인증에 실패하였습니다", Toast.LENGTH_LONG).show()
} else {
Toast.makeText(applicationContext, "인증 성공하였습니다", Toast.LENGTH_LONG).show()
requestRoute();
}
}
})
}
}
private fun selectAvoidOption(v:Boolean, option: KNRouteAvoidOption) {
if (v) {
curAvoidOptions = curAvoidOptions or option.value
}
}
}