Things take time

[Android] 문자 수신 처리 (브로드캐스트 리시버, BroadcastReceiver) 본문

Android(기능)

[Android] 문자 수신 처리 (브로드캐스트 리시버, BroadcastReceiver)

겸손할 겸 2017. 7. 2. 10:23

[문자 수신]

 

회원가입을 진행하다보면.. 핸드폰을 인증하고, 핸드폰에 인증문자가 오면 그 문자를 외웠다가 해당 칸에 입력하는 곳도 있지만, 자동적으로 그 번호를 입력해주는 앱들이 있다. 이 기능을 구현하는 예제다.

 

[로직]

 

문자를 수신하는 브로드캐스트 리시버(앱의 백그라운드에서 동작하는 것을 관리)에서 여러 브로드캐스트 중 '문자'에 대한 액션만을 캐치하여, 해당 문자내용을 분석하여 서버의 번호로 등록된 곳을 통해 문자가 왔다면, 그 문자 내용중 인증 번호를 추출하여 네이티브 앱에서 자동 입력하는 함수를 호출한다.

 

참고로 이 브로드캐스트는 이 브로드캐스트를 등록한 앱이 실행중일 때만 동작한다는 것을 잊지 말자.

앱이 켜지지 않았는데도 동작하는 것을 원하는것은 브로드캐스트가 아닌 서비스! (예 : 푸시)

 

[설정]

 

문자를 받는 것과 읽는 것에 대한 권한 체크가 필요하며, 이 권한들은 위험권한이기때문에 마시멜로 이상의 기기를 Target으로 하는 앱이라면 위험 권한 팝업까지 만들어야한다. 위험 권한 팝업은 여기선 만들었다 기준으로 진행한다.

 

매니페스트 파일에 아래의 권한 세개를 추가한다.

    <USES-PERMISSION android:name="android.permission.READ_SMS" />
    <USES-PERMISSION android:name="android.permission.RECEIVE_SMS" />
    <USES-PERMISSION android:name="android.permission.INTERNET" />

이 중 READ_SMS, RECEIVE_SMS는 위험 권한이다.

 

다음은 브로드캐스트 리시버를 등록해야한다. 매니페스트 내 <application> </application> 안에 등록한다.

<!-- SMS Receiver --> <receiver android:name="MySMSReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>

 

 

여기서 receiver의 name은 브로드캐스트 리시버를 상속받을 클래스 이름이므로 자유롭게 사용한다. 예제 기준 MySMSReceiver 클래스 코드다.

import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.SmsMessage; import android.util.Log; import android.widget.Toast; /** * Created by 겸 on 2017-07-02. */ public class MySMSReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.i("onReceive", "무언가 동작했습니다."); // 수신되었을 때 호출되는 콜백 메서드 // 매개변수 intent의 액션에 방송의 '종류'가 들어있고 필드에는 '추가정보' 가 들어있음 // SMS 메시지를 파싱합니다. Bundle bundle = intent.getExtras(); if (bundle != null) { // 수신된 내용이 있으면 // 실제 메세지는 Object타입의 배열에 PDU 형식으로 저장됨 // 문자 메시지는 pdus란 종류 값으로 들어있음 Object [] pdus = (Object[])bundle.get("pdus"); SmsMessage[] msgs = new SmsMessage[pdus.length]; for (int i = 0; i < msgs.length; i++) { // PDU 포맷으로 되어 있는 메시지를 복원합니다. msgs[i] = SmsMessage .createFromPdu((byte[]) pdus[i]); String sender = msgs[i].getOriginatingAddress(); String content = msgs[i].getMessageBody().toString(); Log.i("sender", sender); Log.i("content", content); if(sender.equals("01000000000")){ int startIdx = content.indexOf("["); int endIdx = content.indexOf("]"); String authNumber = content.substring(startIdx+1, endIdx); Log.i("authNumber", authNumber); } } } } }

 

여기서 receiver의 name은 브로드캐스트 리시버를 상속받을 클래스 이름이므로 자유롭게 사용한다. 예제 기준 MySMSReceiver 클래스 코드다.

 

코드안에 설명이 다있으므로..

 

간략히 예제기준으로, 보내는 핸드폰번호(sender)가 01000000000인 것을 캐치하고, 그 안에서 문자 내용(content)을 분석하여 '[' , ']'를 찾아 그 안에 들어있는 숫자를 찾아 그 숫자를 인증숫자로 보는 것이다.

 

예제 문자열 예시 : 인증 번호는 [1234] 입니다.

라면 1234가 authNumber에 저장되게 될 것이다.

 

그리고 mainActivity에 있는 특정 함수를 호출하게 되면, 그 함수에서 그 인증 번호 입력하는 란에 숫자를 입력하면 되는 것이고, 하이브리드라 웹뷰라면, 웹뷰 안의 자바스크립트 함수에 인증번호를 파라미터로 넘겨, 그 JS함수에서 인증 번호 입력하는 곳의 id의 value값을 입력하면 되는 것이다.