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이하로 낮추어준다.



5. SmsReceiver.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
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/

+ Recent posts