240일차 - 커뮤니티 앱개발 (8) : 코틀린 회원가입, 로그인

2021. 8. 26. 22:46Diary/201~300

1. Signup Activity

class SignupActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener {
    var temp_select_mbti:String = ""
    var temp_username:String = ""
    var temp_password:String = ""
    var temp_password_check:String = ""
    var temp_nickname:String = ""
    var username_count = 0
    var password_count = 0
    var mbti_count = 0
    var nickname_count = 0

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_signup)

        // API 셋팅
        val conn = Connect().connect("")
        val signup_api: SignupInterface = conn.create(SignupInterface::class.java)

        // ================================  스피너 ================================
        // 스피너 Array 불러오기
        val spinner: Spinner = findViewById(R.id.mbti_spinner)

        // 문자열 배열과 기본 스피너 레이아웃을 사용하여 ArrayAdapter 만들기
        ArrayAdapter.createFromResource(
            this,
            R.array.mbti_select_array,
            android.R.layout.simple_spinner_item
        ).also { adapter ->
            // 선택 목록이 나타날 때 사용할 레이아웃 지정
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)

            // 스피너에 어댑터 적용
            spinner.adapter = adapter
        }

        // 인터페이스 구현 지정, 아래 오버라이딩 가능
        spinner.onItemSelectedListener = this
        // ========================================================================

        // 화면 어디든 클릭 시, 키보드 내리기
        signup_all_layout.setOnClickListener {
            // 키보드 내리기
            val mInputMethodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            mInputMethodManager.hideSoftInputFromWindow(currentFocus?.windowToken, 0)
        }
        mbti_spinner.setOnTouchListener { _, _ ->
            // 키보드 내리기
            val mInputMethodManager =
                this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            mInputMethodManager.hideSoftInputFromWindow(currentFocus?.windowToken, 0)
            false
        }

        // 텍스트 변환 감지 : 아이디
        signup_username_input.addTextChangedListener(object : TextWatcher {
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int){ // 입력난에 변화가 있을 시 조치
                temp_username = signup_username_input.text.toString()

                // 아이디 체크
                val username_reg = PasswordCheck().check("^[0-9a-z].{1,15}\$", temp_username)

                if(username_reg != null) {
                    username_count = 1
                    signup_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                } else {
                    username_count = 0
                    signup_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))
                }
            }

            override fun afterTextChanged(arg0: Editable) { // 입력이 끝났을 때 조치
                temp_username = signup_username_input.text.toString()
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { // 입력하기 전에 조치
                temp_username = signup_username_input.text.toString()
            }
        })
        // 텍스트 변환 감지 : 비밀번호
        signup_password_input.addTextChangedListener(object : TextWatcher {
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int){ // 입력난에 변화가 있을 시 조치
                temp_password = signup_password_input.text.toString()

                // 패스워드 체크
                val password_reg = PasswordCheck().check(
                    "^([a-zA-Z!@#\$%^&*0-9]).{1,15}\$",
                    temp_password
                )

                if(password_reg != null) {
                    Log.d("TEST", "정규표현식 통과")
                    signup_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                } else {
                    Log.d("TEST", "정규표현식 통과 XXXXX")
                    signup_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))
                }

                if(temp_password_check != "" && temp_password != "") {
                    if(temp_password != temp_password_check) {
                        password_count = 0
                        signup_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))
                        signup_password_check_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))
                        Log.d("TEST", "비밀번호가 불일치 : $temp_password")
                    } else {
                        signup_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                        signup_password_check_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                        password_count = 1
                    }
                }

            }

            override fun afterTextChanged(arg0: Editable) { // 입력이 끝났을 때 조치
                temp_password = signup_password_input.text.toString()
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { // 입력하기 전에 조치
                temp_password = signup_password_input.text.toString()
            }
        })
        // 텍스트 변환 감지 : 비밀번호 확인
        signup_password_check_input.addTextChangedListener(object : TextWatcher {
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int){ // 입력난에 변화가 있을 시 조치
                temp_password_check = signup_password_check_input.text.toString()

                if(temp_password_check != "" && temp_password != "") {
                    if(temp_password != temp_password_check) {
                        password_count = 0
                        signup_password_check_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))

                        // 패스워드 체크
                        val password_reg = PasswordCheck().check(
                            "^([a-zA-Z!@#\$%^&*0-9]).{1,15}\$",
                            temp_password
                        )

                        if(password_reg != null) {
                            Log.d("TEST", "정규표현식 통과")
                            signup_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                        } else {
                            Log.d("TEST", "정규표현식 통과 XXXXX")
                            signup_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))
                        }

                        Log.d("TEST", "비밀번호가 불일치 : $temp_password")
                    } else {
                        signup_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                        signup_password_check_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                        password_count = 1
                    }
                }
            }

            override fun afterTextChanged(arg0: Editable) { // 입력이 끝났을 때 조치
                temp_password_check = signup_password_check_input.text.toString()
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { // 입력하기 전에 조치
                temp_password_check = signup_password_check_input.text.toString()
            }
        })
        // 텍스트 변환 감지 : 닉네임
        signup_nickname_input.addTextChangedListener(object : TextWatcher {
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int){ // 입력난에 변화가 있을 시 조치
                temp_nickname = signup_nickname_input.text.toString()

                // 닉네임 체크
                val nickname_reg = PasswordCheck().check("^([a-zA-Z0-9ㄱ-ㅎ|ㅏ-ㅣ|가-힣]).{1,12}\$", temp_nickname)

                if(nickname_reg != null) {
                    nickname_count = 1
                    signup_nickname_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                } else {
                    nickname_count = 0
                    signup_nickname_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))
                }
            }

            override fun afterTextChanged(arg0: Editable) { // 입력이 끝났을 때 조치
                temp_nickname = signup_nickname_input.text.toString()
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { // 입력하기 전에 조치
                temp_nickname = signup_nickname_input.text.toString()
            }
        })

        // 회원가입 버튼 클릭
        signup_submit_btn.setOnClickListener {
            // 키보드 내리기
            val mInputMethodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            mInputMethodManager.hideSoftInputFromWindow(currentFocus?.windowToken, 0)

            if(username_count == 0) {
                Snackbar
                    .make(signup_layout, "아이디가 올바르지 않습니다", 2000)
                    .setBackgroundTint(Color.parseColor("#292929"))
                    .setTextColor(Color.parseColor("#ffffff"))
                    .show()

                signup_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))

                return@setOnClickListener
            }
            if(password_count == 0) {
                Snackbar
                    .make(signup_layout, "비밀번호를 확인해주세요", 2000)
                    .setBackgroundTint(Color.parseColor("#292929"))
                    .setTextColor(Color.parseColor("#ffffff"))
                    .show()
                
                signup_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                signup_password_check_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                
                return@setOnClickListener
            }
            if(mbti_count == 0) {
                Snackbar
                    .make(signup_layout, "MBTI를 선택해주세요", 2000)
                    .setBackgroundTint(Color.parseColor("#292929"))
                    .setTextColor(Color.parseColor("#ffffff"))
                    .show()

                return@setOnClickListener
            }

            val password_aes = PasswordCheck().password_aes256(temp_password)
            Log.d("TEST", "비밀번호가 암호화 : $password_aes")

//            if(temp_password != temp_password_check) {
//                Log.d("TEST", "패스워드가 불일치 : $temp_select_mbti")
//                return@setOnClickListener
//            }

            // 회원가입 API 통신
            val parameter:HashMap<String, String> = HashMap()
            if(password_aes != null) {
                parameter["password"] = password_aes
            } else {
                return@setOnClickListener
            }

            parameter["username"] = temp_username
            parameter["nickname"] = temp_nickname
            parameter["user_type"] = temp_select_mbti
            parameter["message"] = "상태 메세지를 입력해주세요."

            signup_api.createUser(parameter).enqueue(object: Callback<SignupData> {
                override fun onResponse(call: Call<SignupData>, response: Response<SignupData>) {
                    val body = response.body()

                    if(body != null) {
                        if(body.code == "E0003") {
                            // 닉네임 중복 오류
                            Snackbar
                                .make(signup_layout, "중복된 닉네임이 존재합니다.", 2000)
                                .setBackgroundTint(Color.parseColor("#292929"))
                                .setTextColor(Color.parseColor("#ffffff"))
                                .show()

                            signup_nickname_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))

                        } else if(body.code == "E0004") {
                            // 아이디 중복 오류
                            Snackbar
                                .make(signup_layout, "중복된 아이디가 존재합니다.", 2000)
                                .setBackgroundTint(Color.parseColor("#292929"))
                                .setTextColor(Color.parseColor("#ffffff"))
                                .show()

                            signup_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                        } else if(body.code == "S0001") {
                            MoveActivity().login_move(this@SignupActivity, "signup_status", "success")
                        }
                    }


                    Log.d("TEST", "Signup - createUser 통신성공 바디 -> $body")
                }

                override fun onFailure(call: Call<SignupData>, t: Throwable) {
                    Log.d("TEST", "Signup - createUser 통신실패 에러 -> " + t.message)
                }
            })

        }
    }

    // 스피너 제어
    override fun onItemSelected(parent: AdapterView<*>, view: View?, pos: Int, id: Long) {
        Log.d("TEST", "onItemSelected onItemSelected onItemSelected")
        // 항목이 선택되었습니다. 다음을 사용하여 선택한 항목을 검색할 수 있습니다.
        // parent.getItemAtPosition(pos)
        val position = parent.getItemAtPosition(pos)

        temp_select_mbti = position.toString()

        if(temp_select_mbti == "MBTI를 선택해주세요"
            || temp_select_mbti == "ㅡㅡㅡISㅡㅡㅡ"
            || temp_select_mbti == "ㅡㅡㅡESㅡㅡㅡ"
            || temp_select_mbti == "ㅡㅡㅡINㅡㅡㅡ"
            || temp_select_mbti == "ㅡㅡㅡENㅡㅡㅡ") {

            mbti_count = 0
        } else {
            mbti_count = 1
        }

        Log.d("TEST", "position : $position")
    }

    override fun onNothingSelected(parent: AdapterView<*>) {
        Log.d("TEST", "onNothingSelected onNothingSelected onNothingSelected")
        // 다른 인터페이스 콜백
    }
}

 

2. Login Activity

class LoginActivity : AppCompatActivity() {
    var temp_login_username:String = ""
    var temp_login_password:String = ""
    var login_username_count = 0
    var login_password_count = 0

    // 권한 체크 : 저장소 읽기, 인터넷, 네트워크, 위치정보, GPS, 카메라, 저장소 읽기, 절전모드 방지
    val permission_list = arrayOf(
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.INTERNET,
        Manifest.permission.ACCESS_NETWORK_STATE,
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.CAMERA,
        Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.WAKE_LOCK,
    )

    var app_file_path: String? = null

    fun saveTokenFile(access: String) {
        val path = app_file_path
        Log.d("path",path.toString())
//        토큰 저장 경로
        val token_file = File("$path/token.token")
        Log.d("token",token_file.toString())

//        경로에 있는 파일에 토큰 저장
        token_file.bufferedWriter().use {
//            it.write("access_token: $access\nrefresh_token: $refresh\nusername: $username")
            it.write(access)
            Log.d("token/bufferedWriter-->",token_file.toString())
        }
        return
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        app_file_path = this.getExternalFilesDir(null).toString()

        // API 셋팅
        val conn = Connect().connect("")
        val login_api: LoginInterface = conn.create(LoginInterface::class.java)

        val get_signup_status = intent.getStringExtra("signup_status")

        // 회원가입 성공
        if(get_signup_status == "success") {
            Snackbar
                .make(login_all_layout, "회원가입을 환영합니다", 2000)
                .setBackgroundTint(Color.parseColor("#292929"))
                .setTextColor(Color.parseColor("#ffffff"))
                .show()
        }

        // 텍스트 변환 감지 : 아이디
        login_username_input.addTextChangedListener(object : TextWatcher {
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int){ // 입력난에 변화가 있을 시 조치
                temp_login_username = login_username_input.text.toString()

                // 아이디 체크
                val username_reg = PasswordCheck().check("^[0-9a-z].{1,15}\$", temp_login_username)

                if(username_reg != null) {
                    login_username_count = 1
                    login_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                } else {
                    login_username_count = 0
                    login_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))
                }
            }

            override fun afterTextChanged(arg0: Editable) { // 입력이 끝났을 때 조치
                temp_login_username = login_username_input.text.toString()
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { // 입력하기 전에 조치
                temp_login_username = login_username_input.text.toString()
            }
        })

        // 텍스트 변환 감지 : 비밀번호
        login_password_input.addTextChangedListener(object : TextWatcher {
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int){ // 입력난에 변화가 있을 시 조치
                temp_login_password = login_password_input.text.toString()

                // 패스워드 체크
                val password_reg = PasswordCheck().check(
                    "^([a-zA-Z!@#\$%^&*0-9]).{1,15}\$",
                    temp_login_password
                )

                if(password_reg != null) {
                    login_password_count = 1
                    login_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ffffff"))
                } else {
                    login_password_count = 0
                    login_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#66CDCDCD"))
                }

            }

            override fun afterTextChanged(arg0: Editable) { // 입력이 끝났을 때 조치
                temp_login_password = login_password_input.text.toString()
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { // 입력하기 전에 조치
                temp_login_password = login_password_input.text.toString()
            }
        })

        login_btn.setOnClickListener {
            if(login_username_count == 0) {
                login_status_message.text = "아이디가 올바르지 않습니다."
                login_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                return@setOnClickListener
            }
            if(login_password_count == 0) {
                login_status_message.text = "비밀번호가 올바르지 않습니다."
                login_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                return@setOnClickListener
            }

            // 회원가입 API 통신
            val parameter:HashMap<String, String> = HashMap()
            val password_aes = PasswordCheck().password_aes256(temp_login_password)
            if(password_aes != null) {
                parameter["password"] = password_aes
            } else {
                login_password_count = 0
                login_status_message.text = "비밀번호가 올바르지 않습니다."
                login_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                return@setOnClickListener
            }
            parameter["username"] = temp_login_username

            login_api.login(parameter).enqueue(object: Callback<LoginData> {
                override fun onResponse(call: Call<LoginData>, response: Response<LoginData>) {
                    val body = response.body()

                    Log.d("TEST", "Login - login 통신성공 바디 -> $body")

                    if(body != null) {
                        if(body.code == "E0005") {
                            login_status_message.text = "아이디 또는 비밀번호가 틀렸습니다"
                            login_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                            login_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                        } else {
                            val hash: HashMap<String, String> = HashMap()
                            saveTokenFile(body.data.access_token)
                            hash["access_token"] = body.data.access_token
                            hash["username"] = body.data.user_info.username
                            hash["nickname"] = body.data.user_info.nickname
                            hash["profile"] = body.data.user_info.profile
                            hash["user_type"] = body.data.user_info.user_type
                            hash["message"] = body.data.user_info.message

                            MoveActivity().chain_move(this@LoginActivity, hash)
                        }
                    } else {
                        login_status_message.text = "아이디 또는 비밀번호가 틀렸습니다"
                        login_username_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                        login_password_circle.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#ff0000"))
                    }

                }

                override fun onFailure(call: Call<LoginData>, t: Throwable) {
                    Log.d("TEST", "Login - login 통신실패 에러 -> " + t.message)
                }
            })

//            finish()
        }

        login_signup_btn.setOnClickListener {
            MoveActivity().signup_move(this)
        }
    }
}