안드로이드 SMS_RETRIEVED 로 SMS 인증번호 가져오기(RECEIVE_SMS 포함 앱으로 구글 승인 3번 거절당함)
아~~ RECEIVE_SMS 권한으로 3번 심사를 거부당할 줄은 몰랐다.
RECEIVE_SMS 권한을 Manifest에 친절히 써서 디버깅하고 앱을 배포하기 전까지는 말이다.
요즘 앱의 대한 민감성이 상당히 높아졌는데, 그것을 캐치 하지 못했다. (배포할 때 ios만 유별난 줄 단단히 착각..)
그리고 깨달았다.
내 안드로이드 실력은 과거에 머물러 있음을..
아무튼 RECEIVE_SMS를 사용하려면 사용 명분을 명확하게 제출해야만 승인 받을 수 있다.
RECEIVE_SMS에서 단독으로 빠져나온? 다시 말하면
권한 등록을 하지 않고 SMS 인증번호를 가져올 수 있는 API가 따로 존재하고 있었다.
그것은 바로 SMS Verification API(Retriever API를 사용할 것임)
구글 sms-retriever 공식 홈이다. 들어가서 API가 어떤 원리로 작동되는지 Guide에서 찾아볼 수 있다.
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
SMS Verification APIs | Google Developers
Create streamlined phone verification flows on Android
developers.google.com
sms-retriever 가이드에도 나와 있듯이, sms 내용의 필수 조건이 존재한다.
1. <#> 이 있어야 한다.
2. 앱의 패키지가 담긴 해시 문자열 11자리가 있어야 한다.
그래야만 SmsRetriever의 onReceive override가 동작하게 된다.
(Perform SMS verification on the server 가이드에서 해시키 추출 방법을 확인할 수 있다.)
포스팅의 본론으로 들어가보자.
우선 build.gradle에서 play-services와 관련된 컴포넌트 상속이 필요하다.
1
2
|
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.4.0'
|
cs |
Sync를 하고 나면 SmsRetriever와 SmsRetrieverClient 등을 사용할 수 있다.
그다음 아래 내용을 확인한다.
Retriever를 사용하는 구문이다.
아래 구문만 있으면 앱에서 할 일은 끝난다.
- Kotlin
- Java
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_signup)
var context : Context = this
val pkgFilter = IntentFilter()
pkgFilter.addAction("com.google.android.gms.auth.api.phone.SMS_RETRIEVED")
val mBroadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
val extras = intent.extras
val status: Status? = extras!![SmsRetriever.EXTRA_STATUS] as Status?
when (status!!.statusCode) {
//SMS 수신을 성공한 경우
CommonStatusCodes.SUCCESS -> {
// SMS 내용 가져오기
val message = extras[SmsRetriever.EXTRA_SMS_MESSAGE] as String?
// 가져온 내용으로 Custom 하기
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
//타임아웃은 5분이며 타임아웃이 될 경우
CommonStatusCodes.TIMEOUT -> {
}
}
}
}
}
//context에 intentfilter와 Broadcast 리시버 등록하기
context.registerReceiver(mBroadcastReceiver, pkgFilter)
Objects.requireNonNull(context.registerReceiver(mBroadcastReceiver, pkgFilter))
// SmsRetrieverClient 설정하기
val client: SmsRetrieverClient = SmsRetriever.getClient(context)
// SmsRetriever를 수신 받기 위한 발신 task 실행
val task: Task<Void> = client.startSmsRetriever()
task.addOnSuccessListener {
// retriever 실행을 성공 하였을 경우의 custom 구문, 여기서 SMS 전송 프로세스를 시작한다.
//val appsign = AppSignatureHelper(context) //sms 보내기 준비
}
task.addOnFailureListener {
// retriever 실행을 실패 하였을 경우
}
}
|
cs |
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_signup);
Context context = getContext();
IntentFilter pkgFilter = new IntentFilter();
pkgFilter.addAction("com.google.android.gms.auth.api.phone.SMS_RETRIEVED");
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
switch(status.getStatusCode()) {
//SMS 수신을 성공한 경우
case CommonStatusCodes.SUCCESS:
// SMS 내용 가져오기
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
// 가져온 내용으로 Custom 하기
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
break;
//타임아웃은 5분이며 타임아웃이 될 경우
case CommonStatusCodes.TIMEOUT:
break;
}
}
}
};
//context에 intentfilter와 Broadcast 리시버 등록하기
context.registerReceiver(mBroadcastReceiver, pkgFilter);
Objects.requireNonNull(context.registerReceiver(mBroadcastReceiver, pkgFilter);
// SmsRetrieverClient 설정하기
SmsRetrieverClient client = SmsRetriever.getClient(context);
// SmsRetriever를 수신 받기 위한 발신 task 실행
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(aVoid -> {
// retriever 실행을 성공 하였을 경우의 custom 구문, 여기서 SMS 전송 프로세스를 시작한다.
//val appsign = AppSignatureHelper(context) //sms 보내기 준비
});
task.addOnFailureListener(e -> {
// retriever 실행을 실패 하였을 경우
});
} |
cs |
문자 내용 중 대괄호 안의 숫자 내용까지 추출해내고 싶다면,
아래 포스팅에서 바로 확인!! 쉽게 작성할 수 있다.
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
안드로이드 SMS 문자 내용 중 대괄호 안 숫자만 파싱하기(Parse)
답답하다 답답혀. 검색 능력이 안좋은건지, 너무 간단해서 없는 내용인건지, 도무지 찾고 싶어도 완벽히 찾을 수가 없던 SMS 내용 파싱해서 대괄호안에 숫자 빼서 쓰기... ㅠㅠ 결국은 완성 했고
thedevelopthebetter.tistory.com
원하는 대로 작성되지 않는다면 문의글도 굳굳!
깔끔!
포스팅을 읽고,
큰 도움이 되셨다면, 공감(♥)을 던져 주세요!
큰 힘이 되어 다음 포스팅 시에도 파이팅하겠습니다.