일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 인텐트
- Class
- null-safety
- 안드로이드
- classList
- 프래그먼트
- 생명주기
- Flutter
- DOMContentLoaded
- ViewPager
- ActionBar
- intent
- 230503
- serializable
- 함수 인자
- 230510
- Adapter
- DFS
- textContent
- html
- parcelable
- putextra
- 부가데이터
- javascript
- 데이터 타입
- 230508
- fragment
- C++
- string
- querySelector
- Today
- Total
나만의 개발노트
[안드로이드] 브로드캐스트 수신자, onReceiver, SMS메시지 수신 어플 본문
메모 : ***22버전 이후 위험권한으로 SMS 수신 안되는 부분 수정 필요***
(아래 코드는 22 이전 버전에서만 작동합니다)
브로드캐스트 수신자 (Broadcast Receiver)
: 앱에서 브로드캐스팅 메시지를 받고 싶을 때, 브로드캐스트 수신자를 등록하여 받는다
*브로드캐스팅(Braodcasting)이란,
메시지를 여러 대상에게 전달하는
-> 안드로이드는 여러 어플리케이션 구성요소에게 메시지를 전달하고 싶은 경우 브로드캐스팅을 사용
ex) SMS 메시지를 받을 때
[브로드캐스트 수신자 등록 방법]
1. new 브로드캐스트 수신자
- Mainfest.xml에 receiver 태그로 등록
2. Manifest.xml에 receiver 태그 안에 intent-filter태그를 통해 원하는 브로드캐스팅 메시지를 제한
ex) SMS 메시지 받기
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
3. SMS를 수신할 권한 부여
- Manifest.xml에 RECEIVE_SMS 권한 추가
(마시멜로 이후 버전은, SMS권한을 위험권한으로 승인 필요
이전 버전으로 낮추려면, build.gradle에서 targetSdkVersion을 22이하로 낮추기)
<uses-permission android:name="android.permission.RECEIVE_SMS" />
*uses-feature 입력하니 가능
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
-> 브로딩캐스팅 메시지가 인텐트 객체로 전달됨 (SMS를 보낸 사람, SMS내용, 보낸 시간)
[사용법 - 브로드캐스팅 SMS메시지 받아서 띄우는 액티비티 만들기]
1. 브로드캐스트 수신자 등록 (본문 윗쪽 참고)
1) app 우클릭 -> New -> Other -> Broadcast Receiver
2) Manifest.xml에 receiver태그 수정
3) SMS 권한 받기
2. 전달받은 SMS메시지를 확인할 수 있는 코드 작성
1) 전달받은 SMS 객체 내용을 Bundle 형태로 받기
Bundle bundle = intent.getExtras();
2) Bundle을 SmsMessage[] 로 바꾸는 parseSmsMessage() 만들기
*SmsMessage는 android.telephony클래스
SmsMessage[] messages = parseSmsMessage(bundle);
private SmsMessage[] parseSmsMessage(Bundle bundle){
//SMS 데이터를 처리하는 국제표준 프로토콜 smpp에 pdus라는 이름
//pdus에 SMS 데이터 관련 내용이 들어가 있다 --> 좀 더 공부 필요
Object[] objects = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[objects.length];
for(int i=0;i<objects.length;i++){
//마시멜로 (23) 버전 이상의 경우, string 인자가 하나 더 필요
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
String format = bundle.getString("format");
messages[i] = SmsMessage.createFromPdu((byte[]) objects[i],format);
} else{
//마시멜로(23) 이전 버전
messages[i] = SmsMessage.createFromPdu((byte[]) objects[i]);
}
}
return messages;
}
3) onReceive()에 전달받은 SmsMessage[] 출력하기 (index 0 만 예시)
if(messages.length > 0){
//SMS 수신자 정보
String sender = messages[0].getOriginatingAddress();
Log.d(TAG,"sender : "+ sender);
//SMS 내용
String contents = messages[0].getMessageBody();
Log.d(TAG,"contents : "+ contents);
//수신 시간 Date -> String으로 변경
String receivedDate = dateFormat.format(messages[0].getTimestampMillis());
Log.d(TAG,"receivedDate : "+ receivedDate);
}
*Date -> String 방법
//원하는 String 형태 format 만들기
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd HH:mm");
String date = dateFromat.format(Date);
3. SMS 메시지를 띄울 액티비티 생성
1) app 우클릭 -> New -> Activity (SmsActivity생성)
2) activity_sms.xml 작성
3) SmsActivity.java 작성
- activity_sms.xml 에서 editText 불러오기
- 브로드캐스팅 받은 intent 받기
Intent passsedIntent = getIntent();
//intent에서 내용 표시해주는 함수
processCommand(passsedIntent);
- onNewIntent() 생성
//이미 생성된 액티비티는 onCreate()가 아닌, onNewIntent()로 시작됨 *생명주기 참고
@Override
protected void onNewIntent(Intent intent) {
processCommand(intent);
super.onNewIntent(intent);
}
- processCommand() 생성
//intent의 내용을 editText에 지정하는 함수
private void processCommand(Intent intent){
if(intent != null){
String sender = intent.getStringExtra("sender");
String contents = intent.getStringExtra("contents");
String receivedDate = intent.getStringExtra("receivedDate");
editText1.setText(sender);
editText2.setText(contents);
editText3.setText(receivedDate);
}
}
4. 액티비티에 SMS메시지 전달
- SmsActivity.java에 액티비티로 보내는 함수 sendToActivity() 생성
//액티비티로 메시지 내용을 보내는 함수
//context도 전달받아야함
private void sendToActivity(Context context, String sender, String contents, String receivedDate){
Intent intent = new Intent(context, SmsActivity.class);
//보이지 않는 브로드캐스트를 보이는 액티비티로 띄워주기 위해, Flag를 추가해야함
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",receivedDate);
//Context.startActivity로 액티비티에 intent 보내기
context.startActivity(intent);
}
#최종 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MySMSReceiver"
tools:targetApi="31">
<activity
android:name=".SmsActivity"
android:exported="false" />
<receiver
android:name=".SmsReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.provier.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
#최종 SmsReceiver.java
package com.example.mysmsreceiver;
import static androidx.core.content.ContextCompat.startActivity;
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;
public class SmsReceiver extends BroadcastReceiver {
private static final String TAG = "SMSReciever";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd HH:mm");
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"onReceiver() 호출됨.");
//전달받은 SMS 인텐트 객체 내용을 Bundle 형태로 받기
Bundle bundle = intent.getExtras();
SmsMessage[] messages = parseSmsMessage(bundle);
if(messages.length > 0){
//SMS 수신자 정보
String sender = messages[0].getOriginatingAddress();
Log.d(TAG,"sender : "+ sender);
//SMS 내용
String contents = messages[0].getMessageBody();
Log.d(TAG,"contents : "+ contents);
//수신 시간 Date -> String으로 변경
String receivedDate = dateFormat.format(messages[0].getTimestampMillis());
Log.d(TAG,"receivedDate : "+ receivedDate);
//액티비티로 보내는 함수 호출
sendToActivity(context, sender,contents,receivedDate);
}
}
//액티비티로 메시지 내용을 보내는 함수
private void sendToActivity(Context context, String sender, String contents, String receivedDate){
Intent intent = new Intent(context, SmsActivity.class);
//보이지 않는 브로드캐스트를 보이는 액티비티로 띄워주기 위해, Flag를 추가해야함
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",receivedDate);
//Context.startActivity로 액티비티에 intent 보내기
context.startActivity(intent);
}
private SmsMessage[] parseSmsMessage(Bundle bundle){
//SMS 데이터를 처리하는 국제표준 프로토콜 smpp에 pdus라는 이름
//pdus에 SMS 데이터 관련 내용이 들어가 있다 --> 좀 더 공부 필요
Object[] objects = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[objects.length];
for(int i=0;i<objects.length;i++){
//마시멜로 (23) 버전 이상의 경우, string 인자가 하나 더 필요
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
String format = bundle.getString("format");
messages[i] = SmsMessage.createFromPdu((byte[]) objects[i],format);
} else{
//마시멜로(23) 이전 버전
messages[i] = SmsMessage.createFromPdu((byte[]) objects[i]);
}
}
return messages;
}
}
#최종 activity_sms.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SmsActivity">
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="수신자"/>
<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="메시지 내용"/>
<EditText
android:id="@+id/editText3"
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:layout_gravity="center"
android:text="확인"/>
</LinearLayout>
#최종 SmsActivity.java
package com.example.mysmsreceiver;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class SmsActivity extends AppCompatActivity {
EditText editText1;
EditText editText2;
EditText editText3;
@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 button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
//Intent 받기
Intent passsedIntent = getIntent();
processCommand(passsedIntent);
}
//이미 생성된 액티비티는 onCreate()가 아닌, onNewIntent()로 시작됨 *생명주기 참고
@Override
protected void onNewIntent(Intent intent) {
processCommand(intent);
super.onNewIntent(intent);
}
//intent의 내용을 editText에 지정하는 함수
private void processCommand(Intent intent){
if(intent != null){
String sender = intent.getStringExtra("sender");
String contents = intent.getStringExtra("contents");
String receivedDate = intent.getStringExtra("receivedDate");
editText1.setText(sender);
editText2.setText(contents);
editText3.setText(receivedDate);
}
}
}
[참조]
https://www.boostcourse.org/mo316/lecture/259038?isDesc=false
'[안드로이드] > [안드로이드] 공부 기록' 카테고리의 다른 글
[안드로이드] 프래그먼트 (Fragment), FragmentManager (0) | 2023.11.22 |
---|---|
[안드로이드] 권한, 위험권한, permission, RECEIVE_SMS (0) | 2023.11.16 |
[안드로이드] 서비스, startService, onStartCommand (0) | 2023.10.13 |
[안드로이드] 수명주기/생명주기 (LifeCycle), getSharedPreferences() (0) | 2023.10.13 |
[안드로이드] Serializable, Parcelable (0) | 2023.10.12 |