유니 코드

[Android] smtp를 이용한 메일보내기 테스트(Kotlin) 본문

오늘의 공부는?!/Android

[Android] smtp를 이용한 메일보내기 테스트(Kotlin)

꼬물쥰 2022. 7. 12. 18:20

새로 시작한 프로젝트가 대학교 학생들을 대상으로 서비스할 예정이기때문에

회원가입시 학교 메일을 인증하여 학생인증을 하려고 했다

학교 메일을 입력하고 인증버튼을 누르면 해당 주소로 인증번호를 포함한 메일이 발송되고

인증번호를 입력하면 학생인증이 완료되는 시나리오를 생각했다

자료조사를 하다보니 Gmail authentication의 JavaMail API를 사용하면 이메일을 보낼 수 있다는 걸 알게되었다

 

< 환경설정 >

해당 API를 사용하기 위해서 환경설정을 먼저 해주어야 한다

https://code.google.com/archive/p/javamail-android/downloads 

위의 링크에서 activation, additionnal, mail 3개의 jar 파일을 다운로드한다

 

다음과 같이 3개의 파일을 프로젝트경로 > app > libs 안에 추가해준다

이후 android studio에서 인터넷 접근을 위한 권한 설정을 해준다

매니페스트에 uses-permission을 추가해준다

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

비동기적으로 실행해야하기 때문에 코루틴 추가 및 libs에 넣은 라이브러리도 추가한 후 Sync하기

// 코루틴
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
// 메일 보내기
implementation files('libs/activation.jar')
implementation files('libs/additionnal.jar')
implementation files('libs/mail.jar')

 

< 코드 >

activity_mail.xml

<?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">

    <EditText
        android:id="@+id/editEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="메일 인증"
        android:textColor="@color/black"
        android:backgroundTint="#aaddff"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editEmail" />

</androidx.constraintlayout.widget.ConstraintLayout>

액티비티에는 메일주소를 입력할 editText와 메일전송 Button을 만들어주었다

 

GMailSender.kt : 메일 발송 함수

이때 비밀번호는 보안 비밀번호를 입력해야한다

보안 비밀번호는 여기서 확인할 수 있다

package com.example.sharedtaxitogether.mailAuth

import com.example.sharedtaxitogether.BuildConfig
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*
import javax.mail.*
import javax.mail.internet.InternetAddress
import javax.mail.internet.MimeMessage

class GMailSender: Authenticator() {
    // 발신 메일과 비밀번호
    val fromEmail = BuildConfig.GMAIL_ADDRESS // example@gmail.com
    val password = BuildConfig.GMAIL_PASSWD //보안 비밀번호 16자리

    var code = "-1"

    init{
        // 이메일 인증 코드 생성
        code = createEmailCode()
    }

    // 발신자 계정 확인
    override fun getPasswordAuthentication(): PasswordAuthentication {
        return PasswordAuthentication(fromEmail, password)
    }

    // 메일 보내기
    fun sendEmail(toEmail: String){
        CoroutineScope(Dispatchers.IO).launch {
            val props = Properties()
            props.setProperty("mail.transport.protocol", "smtp")
            props.setProperty("mail.host", "smtp.gmail.com")
            props["mail.smtp.auth"] = "true"
            props["mail.smtp.port"] = "465"
            props["mail.smtp.socketFactory.port"] = "465"
            props["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"
            props["mail.smtp.socketFactory.fallback"] = "false"
            props.setProperty("mail.smtp.quitwait", "false")

            // Google에서 지원하는 smtp 정보를 받아와 MimeMessage 객체에 전달
            val session = Session.getDefaultInstance(props, this@GMailSender)

            // message 객체 만들기
            val message = MimeMessage(session)
            message.sender = InternetAddress(fromEmail)                              // 보내는 사람 설정
            message.addRecipient(Message.RecipientType.TO, InternetAddress(toEmail)) // 받는 사람 설정
            message.subject = "메일 제목"                                     // 이메일 제목
            message.setText("$code \n\n 인증코드입니다")                        // 이메일 내용

            // 메일 전송
            Transport.send(message)
        }
    }

    // 메일 인증 코드 생성
    private fun createEmailCode(): String{
        val str = arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
        var code = ""
        for(i in 1..6)
            code += str[(Math.random() * str.size).toInt()]
        return code
    }
}

 

 

MainActivity.kt : 버튼 누르면 메일 보내도록 구현

package com.example.sharedtaxitogether

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import com.example.sharedtaxitogether.mailAuth.GMailSender

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val editEmail = findViewById<EditText>(R.id.editEmail)
        val btnSend = findViewById<Button>(R.id.btnSend)

        btnSend.setOnClickListener {
            val email = editEmail.text.toString()

            GMailSender().sendEmail(email)
            Toast.makeText(applicationContext, "이메일을 확인해주세요", Toast.LENGTH_SHORT).show()
        }
    }
}

 

여기까지하고 테스트를 해보면 입력한 메일 주소로 메일이 잘 오는 것을 확인 할 수 있다

 

메일이 정상적으로 보내지는 것을 테스트해봤으니 이제 남은 할 일은 다음과 같다

- 인증코드 확인

- 이메일/비번 유효성 검사

- 학교메일이 맞는지 확인


 

처음에는 버튼을 누르니까 아래 에러메시지가 뜨면서 강제종료가 되었다

java.net.SocketException: socket failed: EPERM (Operation not permitted)

javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465;

해결방법

그래서 여러 가지 찾아봤지만 해결되지 않아서 조금 쉬었다가 다시 찾아보는중 

애뮬레이터에서 해당 앱을 삭제하고 다시 install하니까 정상적으로 작동했다

조금 허무하긴 했지만 그래도 되는게 어디야,,,

혹시 위의 코드 그대로 따라했는데 안된다? 그럼 앱을 삭제하고 다시해보시길!

 

 

 

참고

https://episode1.tistory.com/entry/4-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%EC%97%90%EC%84%9C-%EC%83%81%EB%8C%80%EB%B0%A9%EC%97%90%EA%B2%8C-%EB%A9%94%EC%9D%BC%EB%B3%B4%EB%82%B4%EA%B8%B0

https://min-wachya.tistory.com/guestbook

https://min-wachya.tistory.com/m/168

Comments