안녕하세요.

오늘은 DB다이렉트 자동차보험에서 T map 안전운전특약 가입을 했어요.

굳이 게시 안해도 되는 내용일 수도 있지만 이건 엄청난 혜택이기에 알려드려요.

T map에는 안전운행 점수가 있어요. 주행 시에 Tmap 어플을 키고 안전운전하면 

조건에 맞는 만큼 점수가 올라가요. 안 맞으면 내려가구요

100점 만점. 그 중에 저는 2700km를 T map 어플을 키면서 운전했구요

출발-도착지 설정만으로 운행했어요.

그래서 마침 생각난 T map 안전운전특약 가입이 생각나서 DB다이렉트에 전화했어요

상담연결은 오래 걸렸지만 T map 운전점수 확인하는 것은 금방 걸렸어요.

1. 전화연결을 한다.
2. 본인확인, 차 소유주 본인확인을 한다.(구두로)
3. 본인과 연결된 T map 안전점수 조회는 문자인증으로 확인한다.
4. 할인퍼센트에 따라 환급금과 앞으로 이체될 금액에 얼마를 할인받을 수 있는지 안내를 받는다.(전 보험금 분납이에요)
5. 통화 끝
6. 통화가 끝난 후 5분도 안돼서 입금이 된다.

전 정말 놀랐어요. 단지 어플 하나 점수를 확인하고

그 자리에서 바로 환급금과 앞으로 이체 될 보험금이 얼마나 할인을 받을 것인지가 결정되다니...

가장 놀란건 환급금이 바로 들어왔다는 것...

앞으로도 안전운전해요~

반응형
반응형

안녕하세요.

구글맵 도움없이 그냥 위도와 경도만 얻어오는 방법을 알아볼게요

그냥 간단히 30분정도면 알아낼 수 있을 것 같아서 구글링 했는데 몇 시간을 소비했어요

왜 이렇게 다들 무언가 붙혀놨거나 다닥다닥 때어놔서 설명 해놨는지 참... 


일단 위치정보를 사용해야 하기 때문에 매니페스트에 권한을 추가해줘요

AndroidManifest.xml

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


activitiy_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<Button
android:id="@+id/button"
android:text="현재위치 가져오기"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/TV_Result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
/>

</LinearLayout>


MainActivity.kt

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val lm = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        button?.setOnClickListener {
            val isGPSEnabled: Boolean = lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
            val isNetworkEnabled: Boolean = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
            //매니페스트에 권한이 추가되어 있다해도 여기서 다시 한번 확인해야함
            if (Build.VERSION.SDK_INT >= 23 &&
                    ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 0)
            } else {
                when { //프로바이더 제공자 활성화 여부 체크
                    isNetworkEnabled -> {
                        val location =
                            lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) //인터넷기반으로 위치를 찾음
                        getLongitude = location?.longitude!!
                        getLatitude = location.latitude
                        toast("현재위치를 불러옵니다.")
                    }
                    isGPSEnabled -> {
                        val location =
                            lm.getLastKnownLocation(LocationManager.GPS_PROVIDER) //GPS 기반으로 위치를 찾음
                        getLongitude = location?.longitude!!
                        getLatitude = location.latitude
                        toast("현재위치를 불러옵니다.")
                    }
                    else -> {

                    }
                }
                //몇초 간격과 몇미터를 이동했을시에 호출되는 부분 - 주기적으로 위치 업데이트를 하고 싶다면 사용
                // ****주기적 업데이트를 사용하다가 사용안할시에는 반드시 해제 필요****
                /*lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                        1000, //몇초
                        1F,   //몇미터
                        gpsLocationListener)
                lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                        1000,
                        1F,
                        gpsLocationListener)
                //해제부분. 상황에 맞게 잘 구현하자
                lm.removeUpdates(gpsLocationListener)*/
            }
        }
        lm.removeUpdates(gpsLocationListener)
    }

    //위에 *몇초 간격과 몇미터를 이동했을시에 호출되는 부분* 에 필요한 정보
    //주기적으로 위치 업데이트 안할거면 사용하지 않음
    val gpsLocationListener = object : LocationListener {
        override fun onLocationChanged(location: Location) {
            val provider: String = location.provider
            val longitude: Double = location.longitude
            val latitude: Double = location.latitude
            val altitude: Double = location.altitude
        }

        //아래 3개함수는 형식상 필수부분
        override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
        override fun onProviderEnabled(provider: String) {}
        override fun onProviderDisabled(provider: String) {}
    }
}

자세한 설명은 주석에 충분히 설명해놨어요

이렇게 간단한 것을 왜 이리 해맸는지...

반응형

안녕하세요.

이번에는 앱을 개발하면서 많이 쓰이는 리사이클러뷰에 대해 알아보려고 해요

이제는 ListView 보다는 유연하고 쉬운 RecyclerView를 권장해요

Anko 라이브러리에 있는 RecylcerView를 사용하면 쉽게 할 수 있지만

이제는 deprecated 되어서 더 이상 지원하지 않는다고 해요

https://github.com/Kotlin/anko

지원중단!

그래서 앞으로 새로 개발할거면 다른 라이브러리를 사용하거나(Splitties 등) 직접 구현하는게 좋아요

리사이클러뷰를 사용하려면 최소한 필요한 5가지가 있어요

Java 폴더에는 MainActivity, RecyclerViewAdapter.kt(파일명 마음대로), Item.kt(파일명 마음대로) 이 3가지가 필요하구요

layout폴더에는 activity_main.xml, showitem.xml(파일명 마음대로) 이 2가지가 필요해요

적어도 5가지는 만들어야 리사이클러뷰를 사용할 수 있어요

근데 저 파일들이 무슨 역할을 하느냐!! 일단 감잡을 수 있게 간단히만 설명할게요


MainActivity = 리사이클러뷰를 앱에 올려주는 역할을 해요

Item.kt = 리사이클러뷰에 표현할 데이터를 필요로 하는 곳에 알려주는 역할을 해요 

RecyclerViewAdapter.kt = 가장 중요한 부분. 리사이클러뷰를 전체적인 부분을 구현하는 역할을해요

activity_main.xml = 레이아웃에 리사이클러뷰 라는 '틀'만 만드는 역할이에요

showitem.xml = 아파트가 리사이클러뷰라고 한다면 아파트에 있는 집들은 showitem.xml 이걸로 표현할 수 있어요.

(완성돤 화면에서는
list의 첫번째 데이터
list의 두번째 데이터
라고 표현된 곳)

----------------------

activity_main.xml 안에  showitem.xml가 자식으로 들어간다고 생각하면 쉬워요.

----------------------


이제 본격적으로 알아보도록 해요 (변수를 형식적이게 안하고 구별해낼 수 있도록 특별하게 만들었습니다)

activitiy_main

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/idOfRecyclerView_from_acitivity_main"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/idOfRecyclerView_from_acitivity_main" ★ID를 잘 기억하세요. Mainactivity에 쓰입니다★
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

activitiy_main에서는 위 부분만 추가해주시면 되요

 


showitem.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_gravity="center"
        android:text="textView1"
        android:textSize="30sp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="textView2"
        android:textSize="30sp"
     />
</LinearLayout>

 

★텍스트뷰들의 ID를 잘 기억하세요. RecyclerViewAdapter.kt의 holder1 클래스에서 쓰입니다★


MainActivity.kt

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import java.util.*

class MainActivity : AppCompatActivity() {
    //리사이클뷰를 레이아웃에 올리기 위해 참조용 변수
    var recyclerView: RecyclerView? = null
    //Item.kt에 있는 변수들 참조용. Item.kt안에 변수가 여러개니 ArrayList.
    var list = arrayListOf<Item>(
        Item("list의 첫번째 데이터","list의 두번째 데이터"),
        Item("2list의 첫번째 데이터","2list의 두번째 데이터"),
        Item("3list의 첫번째 데이터","3list의 두번째 데이터"),
        Item("4list의 첫번째 데이터","4list의 두번째 데이터")
    )
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //이 변수에 layout폴더에 있는 activity_main에 있는 리사이클러뷰를 연결시켜준다.
        recyclerView = findViewById<View>(R.id.idOfRecyclerView_from_acitivity_main) as RecyclerView
        //리사이클러뷰 크기가 변하지 않게 함
        recyclerView!!.setHasFixedSize(true)
        //리사이클러뷰를 앱에 그려주기 위해 필요하다.
        val layoutManager = LinearLayoutManager(this)
        layoutManager.orientation = LinearLayoutManager.VERTICAL
        recyclerView!!.layoutManager = layoutManager

        //RecyclerViewAdapter.kt에 있는 클래스 a1를 연결한다.(어뎁터를 연결한다는 의미)
        val adapter = a1(applicationContext, list)
        recyclerView!!.adapter = adapter
    }
}

가능한 쉽게 이해되도록 주석도 써놨어요 하나하나 다 필요하고 서로서로 연결돼있는 부분이 많아요


RecyclerViewAdapter.kt

class a1(val context: Context, val b1: ArrayList<Item>): RecyclerView.Adapter<a1.holder1>(){

    //이 부분은 showitem.xml을 activity_main에 있는 리사이클러뷰에 실어주는 역할은 한다.
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): holder1 {
        val aa1 = LayoutInflater.from(context).inflate(R.layout.showitem, parent, false)
        //맨아래 holder1클래스에 aa1 정보를 넘겨준다
        return holder1(aa1)
    }

    //b1 사이즈를 알아내오는 역할을 합니다. 현재로써는 중요하게 알지 안아도 됩니다
    override fun getItemCount(): Int {
        return b1.size
    }

    override fun onBindViewHolder(holder: holder1, position: Int) {
        //b1 ArrayList에 담겨져있는 첫번째 데이터를 cc1에 담는 역할을 합니다
        holder.cc1.text = b1[position].firstItem
        //b1 ArrayList에 담겨져있는 두번째 데이터를 cc2에 담는 역할을 합니다
        //position은 순서를 알려주는 역할을 합니다.
        holder.cc2.text = b1[position].secondItem
    }

    //showitem.xml에 있는 텍스트뷰를 불러와서 cc1,cc2 변수에 담는 역할을 합니다
    class holder1(c1: View): RecyclerView.ViewHolder(c1) {
        val cc1 = c1.findViewById<TextView>(R.id.textView1)
        val cc2 = c1.findViewById<TextView>(R.id.textView2)
    }
}

이 부분도 마찬가지로 주석으로 잘 설명해놨어요

* 직접 설정해야할 변수옆에는 숫자까지 써놨어요 (Ex. 클래스명인 a1)

이게 작동하는 순서를 보여드리자면


첫번째 onCreateViewHolder 함수에서 activity_main의 리사이클뷰에 들어갈 공간을 만든다.

-> 이렇게 만들어진 공간을 holder1에서 받는다
-> holder1에서는 이 공간에 들어갈 showitem.xml의 정보를 불러와서 저장한다(골격을 잡는다)
-
> onBindViewHolder 함수에서 이 공간에  b1의 데이터를 담는다(진짜 데이터를 담는 구간)

 * b1이란??

MainActivity.kt 맨 아래에 adapter 연결을 하면 MainActivity.kt의 list에 있는 데이터가 a1로 넘어올때 저장되는 곳


위의 함수들을 입력하는게 어렵다 하시면

아래와 같이 하세요

여기는 개발자가 직접 설정해줘야하는 부분이에요 일단은 저렇게 '틀'만 잡아주면 되구요

저 상태에서 a1 { } 안에서 컨트롤+O 버튼을 눌러서 

위와 같이 필수 함수들을 추가시켜주시면 돼요.

*a1의 괄호안에 변수 설정할때 val context: Context는 항상 이렇게 쓴다고 기억하시면 돼요


Item.kt

class Item(var firstItem: String? = null,var secondItem: String? = null ) {

    fun firstItem(firstItem: String?){
        this.firstItem = firstItem
    }

    fun secondItem(secondItem: String?){
        this.secondItem = secondItem
    }
}

이 부분은 딱히 설명할 것이 없네요

그냥 리사이클뷰에 표현할 데이터를 세팅하는 부분 이라고 생각하시면 편해요


가능하면 진짜 쉽게 표현하려고 노력해봤는데 어떤가요?

저는 리사이클러뷰를 이해하기 위해 며칠을 만져보고 익히도록 계속 공부했어요

처음에는 잘 이해 안되겠지만 꾸준히 보면서 연습해보는게 가장 좋은 것 같아요

이해안되는 부분은 질문해주세요

반응형

안드로이드 스튜디오를 설치하고 공부하려는 도중에

예전에는 못보던 오류가 생겼어요.

무언가 다운로드해서 동기화해야 하는데 그러지 못하는 것이에요.

실패한 이유를 보니

New Gradle Sync is not supported due to containing Kotlin modules

라고 되있었어요!

해결방법은 JVM 버전을 올려주는 것으로 해결!

File->Settings-> KotlinCompiler

여기서 Targer JVM version 을 1.8로 설정해주시면 해결이 돼요.

다시 재밌게 안드로이드를 하러~!

반응형
import java.io.*
import java.lang.Math.pow
import java.util.*
import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.sqrt

fun main() {
    val br = BufferedReader(InputStreamReader(System.`in`))
    val bw = BufferedWriter(OutputStreamWriter(System.out))

    val testCase = br.readLine().toInt()
    for ( i in 1..testCase) {
        val st = StringTokenizer(br.readLine())
        val x1 = st.nextToken().toInt()
        val y1 = st.nextToken().toInt()
        val r1 = st.nextToken().toInt()
        val x2 = st.nextToken().toInt()
        val y2 = st.nextToken().toInt()
        val r2 = st.nextToken().toInt()

        val distance = sqrt((x2 - x1).toDouble().pow(2.0) + (y2 - y1).toDouble().pow(2.0))

        when {
            x1 == x2 && y1 == y2 && r1 == r2 -> bw.write("-1\n") //두 원 100%겹침
            distance == r1 + r2.toDouble() || abs(r1 - r2).toDouble() == distance -> bw.write("1\n") //두 원 외접or내접
            distance > r1 + r2 || x1 == x2 && y1 == y2 && r1 != r2 || distance < abs((r2 - r1)) -> bw.write("0\n") //두 원이 떨어져있거나 접하지 않으며 안 만남
            else -> bw.write("2\n") //나머지
        }
        bw.flush()
    }
    bw.close()
}
//이석원은 조규현과 백승환에게 상대편 마린(류재명)의 위치를 계산하라는 명령을 내렸다. 조규현과 백승환은 각각 자신의 터렛 위치에서 현재 적까지의 거리를 계산했다.
//
//조규현의 좌표 (x1, y1)와 백승환의 좌표 (x2, y2)가 주어지고, 조규현이 계산한 류재명과의 거리 r1과 백승환이 계산한 류재명과의 거리 r2가 주어졌을 때, 류재명이 있을 수 있는 좌표의 수를 출력하는 프로그램을 작성하시오.

 

단계10(수학2) 마지막문제 1002번이에요

코드만 보면 간단해요.

이 문제는 원의 관한 지식이 있어야 풀 수 있는 문제라서... 코드 구현이랑은 거리가

좀 먼 느낌... 수학적인 것에 시간을 더 쏟은 느낌이네요

수학에 관한 문제를 풀다보니 구현능력은 안 늘고 수학적인 지식만 늘어나는 느낌..

그래서 이제부터 저는 가능한 구현에 관한 문제만 풀려고 해요

수학문제를 풀려고 코딩하는게 아니니깐!

반응형
import java.io.*
import java.util.*
import kotlin.math.round
import kotlin.math.sqrt

fun main() {
    val br = BufferedReader(InputStreamReader(System.`in`))
    val bw = BufferedWriter(OutputStreamWriter(System.out))

    //테스트케이스
    val testCase = br.readLine().toInt()

    for ( i in 1..testCase ) {
        //X값과 Y값 구분
        val xy = StringTokenizer(br.readLine())
        val x = xy.nextToken().toInt()
        val y = xy.nextToken().toInt()
        //X값과 Y값을 뺀 값
        val yMinusX = y - x
        //yMinusX의 제곱근
        var zeGop = sqrt(yMinusX.toDouble())
        //yMinusX 제곱근을 반올림한 값
        var roundUp = round(zeGop)
        //y-x가 3이하면 그냥 출력
        //y-x가 4 이상부터는 제곱근이 제곱근의 반올림값보다 크면 제곱근 * 2
        //y-x가 4 이상부터는 제곱근이 제곱근의 반올림값보다 작으면 제곱근 * 2 - 1
        when {
            yMinusX <= 3 -> bw.write("$yMinusX\n")
            zeGop > roundUp -> bw.write("${roundUp.toInt() * 2}\n")
            zeGop <= roundUp -> bw.write("${roundUp.toInt() * 2 - 1}\n")
        }
        bw.flush()
    }
    bw.close()
}

단계9(수학1) 마지막문제 1011번이에요

일단 문제이해하는데에도 굉장히 오래걸렸어요

처음에 볼때는 그냥 Y 와 X를 뺀 값에서 반정도 날아가면 되지 않나 생각했는데

도착전에는 이동거리가 1이어야 하기 때문에 이 때문에 꼬인...

그냥 차근차근 표를 만들어서 보니 규칙이 나왔어요

또 제곱근에 힌트가 있다는 것도 접하고... 다음은 얼마나 어려울지 흑

반응형
import java.io.*
import kotlin.math.abs

fun main() {
    val br = BufferedReader(InputStreamReader(System.`in`))
    val bw = BufferedWriter(OutputStreamWriter(System.out))
    val n = br.readLine().toInt()

    bw.write("${d(n)}")
    bw.flush()
    bw.close()
}

fun d(n: Int): Int {
    var cnt = 0
    var arr = IntArray(3)
    var w = 0
    for ( i in 1..n) {
        if (i in 1..99)  cnt = i
        else if ( i == 1000 ) break
        else {
            w = 0
            var temp = i
            while (temp > 0) {
                arr[w] = temp % 10
                temp /= 10
                w++
            }
            if (arr[0] - arr[1] == arr[1] - arr[2]) cnt++
        }

    }
    return cnt
}
//어떤 양의 정수 X의 자리수가 등차수열을 이룬다면, 그 수를 한수라고 한다.
// 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.

단계7(함수) 마지막문제 1065번입니다

엄청 어려웠네요... 문제 이해하는데도 시간이 걸렸고

또 완벽하게 저 혼자 푼게아니고 도움을 받은거라...

수학재능이 부족한것인지 구현능력이 부족한건지

어려워~

반응형

+ Recent posts