일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- bottom-up
- bronze2
- silver4
- 테마변경
- LV1
- map
- recyclerView 클릭이벤트
- stack
- toLong()
- Alert Dialog
- Silver5
- bronze4
- gradle설정
- 뷰클래스
- 프로그래머스
- 백준
- RecyclerView
- naver open api
- fragment에서 context사용
- Android
- 다크모드제한
- Kotlin
- silver3
- LIS
- 녹음기
- Top-Down
- 임시저장하기
- bronze3
- RETROFIT
- dp
- Today
- Total
유니 코드
[Android] smtp를 이용한 메일보내기 테스트(Kotlin) 본문
새로 시작한 프로젝트가 대학교 학생들을 대상으로 서비스할 예정이기때문에
회원가입시 학교 메일을 인증하여 학생인증을 하려고 했다
학교 메일을 입력하고 인증버튼을 누르면 해당 주소로 인증번호를 포함한 메일이 발송되고
인증번호를 입력하면 학생인증이 완료되는 시나리오를 생각했다
자료조사를 하다보니 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하니까 정상적으로 작동했다
조금 허무하긴 했지만 그래도 되는게 어디야,,,
혹시 위의 코드 그대로 따라했는데 안된다? 그럼 앱을 삭제하고 다시해보시길!
참고
'오늘의 공부는?! > Android' 카테고리의 다른 글
[Android] 뒤로가기 버튼 설정(Kotlin) (0) | 2022.07.23 |
---|---|
[Android] local.properties에 민감한 정보 안전하게 보관하기 (0) | 2022.07.12 |
[Android/Kotlin] 도서 리뷰 앱 - 상세 페이지 만들기 & 리뷰등록 (0) | 2022.07.01 |
[Android/Kotlin] 도서 리뷰 앱 - Android Room 사용 (0) | 2022.07.01 |