Wook No.1
SMS Retriever API로 인증 문자 확인 본문
기존에 android.permission.RECEIVE_SMS 를 사용하게 되면 그 권한을 무슨 목적으로 사용 하는지를 명확하게 신청해 달라는 경고로 리젝 사유가 됨.
그래서 제공된 SMS Retriever API를 사용해서 인증문자 확인 할수 있음.
1. 인증문자 140 bytes 이하만 가능
2. 인증문자 시작은 <#> 으로 시작해야함.
3. 마지막 문자는 11자리의 hash를 포함해야함.
https://developers.google.com/identity/sms-retriever/overview
Hash 확인 코드
fun appSignatures() {
val appCodes = mutableListOf<String>()
try {
val signatures = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES).signingInfo.apkContentsSigners
} else {
@Suppress("DEPRECATION")
packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures
}
for (signature in signatures) {
val hash = hash(packageName, signature.toCharsString())
hash?.let {
appCodes.add(String.format("%s", it))
}
}
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
}
fun hash(packageName: String, signature: String): String? {
val appInfo = "$packageName $signature"
try {
val messageDigest = MessageDigest.getInstance("SHA-256")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
messageDigest.update(appInfo.toByteArray(StandardCharsets.UTF_8))
}
var hashSignature = messageDigest.digest()
hashSignature = Arrays.copyOfRange(hashSignature, 0, 9)
var base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING or Base64.NO_WRAP)
base64Hash = base64Hash.substring(0, 11)
return base64Hash
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
}
return null
}
Gradle 설정
dependencies {
implementation 'com.google.android.gms:play-services-auth:18.0.0'
}
BroadcastReceiver 코드
class SMSBroadcastReceiver : BroadcastReceiver() {
private var prevMessage : String? = null
private var otpReceiveListener : OtpReceiveListener? = null
fun setOnOtpListener(listener: OtpReceiveListener) {
otpReceiveListener = listener
}
override fun onReceive(context: Context, intent: Intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
val extras = intent.extras
val status = extras.get(SmsRetriever.EXTRA_STATUS) as Status
when(status.statusCode) {
CommonStatusCodes.SUCCESS -> {
var message: String = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
if(message == prevMessage) {
return
}
prevMessage = message
var otp = getOnlyDigit(message)
otpReceiveListener?.onOtpReceived(otp)
}
CommonStatusCodes.TIMEOUT -> {
otpReceiveListener?.onOtpTimeOut()
}
}
}
}
// 해당 번호에 길이 맞게 정규식 적용
private fun getOnlyDigit(str: String?): String? {
// 인증번호가 5자이거나 6자일 경우
var digitStr = ""
Pattern.compile("\\d{6}").matcher(str).run {
if(find()) {
digitStr = group(0)
}
}
if(digitStr.isNullOrBlank()) {
Pattern.compile("\\d{5}").matcher(str).run {
if(find()) {
digitStr = group(0)
}
}
}
return digitStr
}
interface OtpReceiveListener {
fun onOtpReceived(otp: String?)
fun onOtpTimeOut()
}
}
'Android' 카테고리의 다른 글
안드로이드 풀스크린에서 키보드 겹치는 이슈 (0) | 2021.06.30 |
---|---|
기존 XML Layout을 data binding Layout으로 Convert (0) | 2021.06.28 |
SNS 로그인(애플) #3 (0) | 2021.06.21 |
SNS 로그인(애플) #2 (0) | 2021.06.21 |
SNS 로그인(애플) #1 (0) | 2021.06.17 |
Comments