1. Broadcast Receiver
브로드캐스팅(Broadcasting)이란 여러 사람에게 동시에 데이터를 전달한다는 뜻이다.
안드로이드는 여러 애플리케이션 구성 요소에게 메시지를 전달하고 싶은 경우 브로드캐스팅을 사용한다.
앱에서 브로드캐스팅 메시지를 받고 싶다면 Broadcast Receiver를 만들어 등록하면 된다.
Broadcast Receiver는 Intent Filter를 포함하며, Manifest 파일에 등록함으로써 인텐트를 받을 준비를 한다.
Broadcast Receiver를 이용해서 처리하면 백그라운드에서 동작하기 때문에 사용자는 알 수 없다.(UI가 없다.)
2. 실행 결과 화면
3. AndroidManifest.xml
File - New - Other - Broadcast Receiver 클릭하면 매니페스트 파일에 <receiver> 태그가 자동 등록된다.
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 | <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tistory.qlyh8.pracitice"> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".SmsReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver> </application> </manifest> | cs |
브로드캐스팅 메시지는 인텐트 객체로 만들어져 전달된다.
<receiver> 태그 안에 <intent-filter> 태그를 이용해 어떤 브로드캐스팅 메시지를 받고 싶은지 지정할 수 있다.
<intent-filter> 태그 안에 들어있는 <action> 태그는 SMS_RECEIVED 라는 name 속성값을 가지고 있다.
SMS를 담고 있는 인텐트는 이와 동일한 액션 정보를 갖고 있어 브로드캐스트 수신자는 SMS를 담고 있는 인텐트를 받을 수 있게 된다.
SMS 수신 권한을 등록한다.
4. app/build.gradle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | android { compileSdkVersion 26 defaultConfig { applicationId "com.tistory.qlyh8.pracitice" minSdkVersion 15 targetSdkVersion 22 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } | cs |
SMS 수신 권한은 위험 권한이라서 앱 실행 시에 사용자에게 권한 승인을 받아야 한다.
실행 시에 권한 승인을 받는 코드를 넣기 힘들다면 build.gradle 파일에서 targetSdkVersion을 22이하로 낮추어준다.
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | package com.tistory.qlyh8.pracitice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.telephony.SmsMessage; import android.util.Log; import java.text.SimpleDateFormat; import java.util.Date; public class SmsReceiver extends BroadcastReceiver { private static final String TAG = "SmsReceiver"; private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 메시지를 수신하면 이 메소드가 자동으로 호출된다. @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive() 호출됨."); Bundle bundle = intent.getExtras(); // 번들 형태로 인텐트를 받아온다. SmsMessage smsMessage[] = ParseSms(bundle); if(smsMessage.length > 0){ String sender = smsMessage[0].getDisplayOriginatingAddress(); Log.d(TAG, "Sender: " + sender); // 발신번호 String contents = smsMessage[0].getMessageBody(); Log.d(TAG, "Contents: " + contents); // 메세지 내용 Date receivedDate = new Date(smsMessage[0].getTimestampMillis()); Log.d(TAG, "Received Date: " + receivedDate); // 발신시간 SendToActivity(context, sender, contents, receivedDate); } } private SmsMessage[] ParseSms(Bundle bundle){ Object object[] = (Object[]) bundle.get("pdus"); // pdus 안에 SMS 데이터와 관련된 내용이 들어가 있다. SmsMessage smsMessage[] = new SmsMessage[object.length]; for(int i = 0 ; i < object.length ; i++){ // 마시멜로우 버전 이상인지 확인 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) smsMessage[i] = SmsMessage.createFromPdu((byte[]) object[i], bundle.getString("format")); else smsMessage[i] = SmsMessage.createFromPdu((byte[]) object[i]); } return smsMessage; } private void SendToActivity(Context context, String sender, String contents, Date receivedDate) { Intent intent = new Intent(context, MainActivity.class); // 화면이 없는데서 화면을 띄워주기 위한 플래그 설정 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.putExtra("sender", sender); intent.putExtra("contents", contents); intent.putExtra("receivedDate", format.format(receivedDate)); context.startActivity(intent); } } | cs |
6. activity_main.xml
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 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout 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="com.tistory.qlyh8.pracitice.SmsActivity" android:orientation="vertical" android:padding="10dp" android:gravity="center"> <EditText android:id="@+id/editText1" android:layout_width="250dp" android:layout_height="wrap_content" android:hint="수신번호"/> <EditText android:id="@+id/editText2" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:hint="메시지 내용"/> <EditText android:id="@+id/editText3" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:hint="수신시간"/> <Button android:id="@+id/button" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:text="확인"/> </LinearLayout> | cs |
7. MainActivity.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 48 49 | package com.tistory.qlyh8.pracitice; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; public class MainActivity extends AppCompatActivity { EditText editText1, editText2, editText3; Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sms); editText1 = findViewById(R.id.editText1); editText2 = findViewById(R.id.editText2); editText3 = findViewById(R.id.editText3); button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); // 화면 닫기 } }); Intent intent = getIntent(); processIntent(intent); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); processIntent(intent); } private void processIntent(Intent intent){ if(intent != null){ editText1.setText(intent.getStringExtra("sender")); editText2.setText(intent.getStringExtra("contents")); editText3.setText(intent.getStringExtra("receivedDate")); } } } | cs |
출처: https://www.edwith.org/boostcourse-android/lecture/17069/
'Android' 카테고리의 다른 글
프래그먼트 (Fragment) - 1. XML 레이아웃에 프래그먼트 추가하기 (0) | 2018.05.30 |
---|---|
워험권한 (Dangerous Permission) (0) | 2018.05.28 |
액티비티 구성요소 - 서비스 (Service) (0) | 2018.05.19 |
액티비티 수명주기 (Activity Lifecycle) - (2) (0) | 2018.05.19 |
액티비티 수명주기 (Activity Lifecycle) - (1) (0) | 2018.05.19 |