순서대로 그림하고 설명 같이 보면됨
1.
intent.getExtras(); 라고 하면 그 안에 번들(Bundle)이라는 객체가 있어요.
안에 데이터가 있다.
번들을 통해서 데이터를 뽑아 낼거다.
그런데 어떤게 나오냐면
SmsMessage가 여러개 나올 수가 있다. (그래서 배열로 만듬 -> SmsMessage[])
// pdus란? SmsMessage데이터를 처리하는 국제표준 프로토콜이라고 있는데,
// SMTP라고 있는데, 그 안에 데이터가 이런 이름으로 들어 가 있다.
// 그걸 안드로이드 내부의 모듈이 처리를 해서 나한테 던져주는 거다.
// pdus 안에 SmsMessage데이터 관련된 내용이 들어가 있다고 생각하면 된다.
그걸을 Object[] 배열로 받아 볼거다.
그러면 객체(Object)가 여러개가 들어 갈 것이다
2.
Build.VERSION.SDK_INT <- 단말에 설치된 OS 버전 상태를 말하는 거다.
Build.VERSION.SDK_CODES.M <- 마시멜로 가리키는거임. (버전:마시멜로)
bundle.getString("format");
format이라는 정보가 같이 인텐트에 들어가 있어요.
그래서 format이라는 정보를 가져와서,
SmsMessage.createFromPdu((byte[]) objs[i],format); <- 여기다가 넣어준다.
return messages; 라고 한다면
parseSmsMessage()메소드에 들어온 Bundle객체 안에 즉, 인텐트 안에 부가데이터로 들어가 있던 데이터(pdus)를 이용해서,
SmsMessage객체로 변환해서 던져 준다는 거다.
3. 데이터 뽑아내는 방법
그러면 SmsMessage[] messages =parseSmsMessage(bundle); 안에
뭐가 들어가 있냐 하면?
sms데이터가 들어가 있다.
그래서, 이제 아주 쉽게
그 데이터를 뽑아 낼 수 있게 된다.
뽑아 내는 방법
String sender = messages[0].getOriginatingAddress(); // (상대방 번호 = 발신 번호)
String contents = messages[0].getMessageBody().toString(); // 메시지내용
Date receivedDate = new Date(messages[0].getTimestampMillis()); // 발신한 시각
(밑에 그림)
이렇게 하고 실행 시킨 다음에 (결과 - 밑에 그림)
액티비티는 뭐 한게 없으니깐 앱을 끄고,
자기자신한테 문자를 날리고 (문자 온 것을 확인해볼려고......)
안드로이드 스튜디오의 Logcat을 보면
코드에 작성한(sender, contents, 날짜) 것들이 출력 된 것을 확인 할 수 있다.
Logcat <- 받은거 찍히는거임
이젠 위에 처럼
sms를 받았을 때, 이런 sms가 왔습니다라는 화면을 띄워주고 싶겠죠?!
그런데 "브로드캐스트 수신자"는 화면이 없다고 했잖아요!!
그래서 새로 화면(Activity)을 만들어서
그 화면(Activity)을 띄워주는 것이 가능하다.
어떻게? 띄워 줄 수 있냐면,
"브로드캐스트 리시버(=수신자)"도 "애플리케이션 구성요소"니깐
시스템에서 관리를 하죠!!!!!!
그래서, 인텐트객체를 만들어서 startActivity()로 띄워 줄 화면의 액티비티한테 던져 주어서
그 액티비티는 받아서 화면에 뿌려주게 되는 것이다.!
- 여기까지 코드 구조 -
- 참고 -
그래서 이런 과정을 만들어서,
화면에다가 sms내용을 뿌려줄 수가 있다. (밑에 방법)
4. 화면에다가 뿌려주는 방법
xml,java 파일 만듬(SmsActivity.java, activity_sms.xml)
- activity_sms.xml 화면
- SmsActivity.java 처리
이 화면(SmsActivity.java)으로 브로드캐스트리시버(SmsReceiver.java)에서 데이터를 보내줘야 하잖아요!!
데이터를 보낼려면 인텐트에 넣어서 보내주어야 한다. ("보내는 방법"보면 됨)
그러면 이젠 context.startActivity(intent); 하면
SmsReceiver.java(브로드캐스트 수신자)에서 SmsActivity.java(액티비티)쪽으로 화면을 띄워 주는 거죠!
이제 SmsActivity.java(액티비티)쪽에서 인텐트 안에 들어가 있는 부가데이터를 받아서 처리 해주면됩니다. (밑에 코드)
싱글 탑(FLAG_ACTIVITY_SINGLE_TOP)이라고 해서,
SmsActivity.java가 화면에 이미 떠 있는 경우라든가, 이미 만들어져 있는 경우에는
onNewIntent()를 재정(오버라이드)이해서 사용하면,
intent가 이쪽으로 전달이 되었을 때, onNewIntent() 쪽으로 전달이 된다.
이렇게 sms 내용을 쉽게 처리 할 수 있다.
- 여기까지 코드 구조 -
- 결과 -
(자기핸드폰 or 다른 핸드폰)기본 문자로 "야야" 보내면
(받는 폰에서)바로 이렇게 화면 뜸
5.
- 참고 -
근데 이거
기본 문자로 나한테 누가 보내면 그냥 전부 이렇게 떠버리네........
음.........
설정해줘야함.
6. 전체 코드
1) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
2) MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
3) SmsReceiver.java
package com.example.mysmsreceiver;
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 SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 포맷
@Override
public void onReceive(Context context, Intent intent) {
Log.d("SmsReceiver","onReceive() 호출됨");
Bundle bundle = intent.getExtras();
SmsMessage[] messages =parseSmsMessage(bundle);
if(messages.length > 0){
String sender = messages[0].getOriginatingAddress(); // 상대방 번호 = 발신 번호
Log.d("SmsReceiver","sender : " +sender);
String contents = messages[0].getMessageBody().toString(); // 메시지내용
Log.d("SmsReceiver","contents : " +contents);
Date receivedDate = new Date(messages[0].getTimestampMillis()); // 발신한 시각
Log.d("SmsReceiver","receivedDate : " +receivedDate);
// 보내는 방법
sendToActivity(context,sender,contents,receivedDate);
}
}
private void sendToActivity(Context context, String sender, String contents, Date receivedDate){
Intent intent = new Intent(context, SmsActivity.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",fm.format(receivedDate));
context.startActivity(intent);
}
private SmsMessage[] parseSmsMessage(Bundle bundle){
Object[] objs = (Object[])bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[objs.length];
for(int i = 0; i<objs.length; i++){ //sms로 복원을 해볼거다.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
String format = bundle.getString("format");
messages[i] = SmsMessage.createFromPdu((byte[]) objs[i],format);
}else { // 단말이 이전 버전 이면
messages[i] = SmsMessage.createFromPdu((byte[]) objs[i]);
}
}
return messages;
}
}
4) AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mysmsreceiver">
<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">
<receiver
android:name=".SmsReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SmsActivity"></activity>
</application>
</manifest>
5) activity_sms.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="발신번호"/>
<EditText
android:id="@+id/editText3"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:hint="내용"/>
<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="수신시각"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="확인"/>
</LinearLayout>
6) SmsActivity.java
package com.example.mysmsreceiver;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class SmsActivity extends AppCompatActivity {
EditText editText,editText2,editText3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms);
editText = (EditText)findViewById(R.id.editText);
editText2 = (EditText)findViewById(R.id.editText2);
editText3 = (EditText)findViewById(R.id.editText3);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
Intent passedIntent = getIntent(); // 전달 받은 인텐트 확인
processCommand(passedIntent);
}
private void processCommand(Intent intent){
// 브로드캐스트 수신자에서 sms를 받으로 화면으로 보여주는 기능
if(intent != null){ //intent라고 하는게 null 아니면
String sender = intent.getStringExtra("sender");
String contents = intent.getStringExtra("contents");
String receivedDate = intent.getStringExtra("receivedDate");
editText.setText(sender);
editText3.setText(contents);
editText2.setText(receivedDate);
}
}
@Override
protected void onNewIntent(Intent intent) {
processCommand(intent);
super.onNewIntent(intent);
}
}
'■ Android > Tip' 카테고리의 다른 글
[Android] 위험 권한 부여 - 사용법 (0) | 2020.04.25 |
---|---|
[Android] 브로드캐스트 수신자(=브로드캐스트 리시버) - (3)사용법(위험 권한 부여(넣어줌)) (0) | 2020.04.25 |
[Android] 브로드캐스트 수신자(=브로드캐스트 리시버) - (1)사용법(만드는 방법),(동작과정) (0) | 2020.04.25 |
[Android] 서비스 컴포넌트 바인드 서비스 - 사용법 (0) | 2020.04.24 |
[Android] 서비스 포그라운드(ForegroundService) - 사용법★ (0) | 2020.04.24 |