오늘이라도
[Android] 13. SMS 메시지 수신 후 내용 출력 본문
반응형
- SMS 메시지 수신 후 내용 출력 -
- 첫 실행시 권한이 필요하다는 확인창이 뜬다.
▼activiy_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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" />
</androidx.constraintlayout.widget.ConstraintLayout>
▼MainActivity.java
package com.example.my14_smsservice;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkDangerousPermissions();
}
//위험 권한 체크
//manifest와 java에 둘 다 권한 허가받는 코드를 작성한다.
private void checkDangerousPermissions() {
String[] permissions = {
Manifest.permission.RECEIVE_SMS
};
int permissionCheck = PackageManager.PERMISSION_GRANTED;
for (int i = 0; i < permissions.length; i++) {
permissionCheck = ContextCompat.checkSelfPermission(this, permissions[i]);
if (permissionCheck == PackageManager.PERMISSION_DENIED) {
break;
}
}
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "권한 있음", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "권한 없음", Toast.LENGTH_LONG).show();
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[0])) {
Toast.makeText(this, "권한 설명 필요함.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(this, permissions, 1);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 1) {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, permissions[i] + " 권한이 승인됨.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, permissions[i] + " 권한이 승인되지 않음.", Toast.LENGTH_LONG).show();
}
}
}
}
}
▼MyReceiver.java
package com.example.my14_smsservice;
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;
//패키지 우클릭 - New - Other - Broadcast Receiver
public class MyReceiver extends BroadcastReceiver {
private static final String TAG = "MyReceiver";
//연-월-일 시:분:초 형태로 출력하게끔 정하는 메서드
public SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//문자가 오면 반드시 작동하는 메서드
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: 호출됨");
//intent의 내용을 bundle에 넣는다.
Bundle bundle = intent.getExtras();
//sms 메세지가 한 개가 아니므로 배열로 만든다.
SmsMessage[] messages = parseSmsMessage(bundle);
//메세지 내용이 있을 경우 작동
if(messages != null && messages.length > 0) {
Log.d(TAG, "onReceive: SMS를 수신하였습니다");
//보낸 사람
String sender = messages[0].getOriginatingAddress();
Log.d(TAG, "onReceive: sender:" + sender);
//받은 날짜
Date receivedDate = new Date(messages[0].getTimestampMillis());
Log.d(TAG, "onReceive: receivedDate: " + receivedDate);
//내용
String contents = messages[0].getMessageBody();
Log.d(TAG, "onReceive: contents: " + contents);
//SmsDisplayActivity 화면에 띄우기
//Flag : 속성을 부여하는 키워드
//예시 : M화면 → A화면 → SMS메시지화면 → B화면
//NEW_TASK : 새 화면을 띄우겠다 (SMS메시지화면)
//CLEAR_TOP : SMS메시지 위의 화면들을 없앰 (B화면 이하 화면들)
//SINGLE_TOP : 기존의 SMS메시지 화면이 있으면 그걸 사용하라는 뜻
Intent displayIntent = new Intent(context, SmsDisplayActivity.class);
displayIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
//값을 추가로 보냄
displayIntent.putExtra("sender", sender);
displayIntent.putExtra("receivedDate", dateFormat.format(receivedDate));
displayIntent.putExtra("contents", contents);
context.startActivity(displayIntent);
}
}
private SmsMessage[] parseSmsMessage(Bundle bundle) {
//pdus에 메세지가 담겨있다.
Object[] objs = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[objs.length];
for (int i = 0; i < objs.length; i++) {
//M버젼 (API 23 마시멜로우)이상일 때와 아닐때의 메세지 저장 형식 지정
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;
}
}
▼activity_sms_display.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="SMS 발신 번호"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/btnTitle"
android:layout_above="@+id/btnClose"
android:layout_margin="10dp"
android:background="#ff222288">
<TextView
android:id="@+id/tvMsg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="SMS 내용"
android:textStyle="bold"
android:padding="20dp"
android:gravity="center"
android:textColor="#FFFFFFFF"/>
</ScrollView>
<Button
android:id="@+id/btnClose"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
▼SmsDisplayActivity.java
package com.example.my14_smsservice;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class SmsDisplayActivity extends AppCompatActivity {
//객체 선언
Button btnTitle, btnClose;
TextView tvMsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms_display);
//객체 초기화
tvMsg = findViewById(R.id.tvMsg);
btnTitle = findViewById(R.id.btnTitle);
btnClose = findViewById(R.id.btnClose);
//btnClose 기능 추가 : 창 닫기
btnClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
//onCreate에 있으면 새로 받은 문자가 갱신이 안된다.
//인텐트 받기
Intent displayIntent = getIntent();
processIntent(displayIntent);
}
//새 문자를 받을때(이미 창이 만들어져 있어서 onCreate가 작동을 안할 때, 새 Intent를 받을 때) 작동
//매개 변수에는 자동으로 갱신되는 인텐트가 들어간다.
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
processIntent(intent);
}
//인텐트를 받아서 내용을 TextView에 출력하는 메서드
private void processIntent(Intent displayIntent) {
String sender = displayIntent.getStringExtra("sender");
String receivedDate = displayIntent.getStringExtra("receivedDate");
String contents = displayIntent.getStringExtra("contents");
//보낸 사람이 있으면
if(sender != null) {
btnTitle.setText(sender + "에서 문자 수신");
tvMsg.setText("[" + receivedDate + "]\n" + contents);
}
}
}
▼AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.my14_smsservice">
<!-- API 21 이상 부터는 Manifest에 권한 부분을 적어야한다. -->
<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=".SmsDisplayActivity"></activity>
<receiver
android:name=".MyReceiver"
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>
</application>
</manifest>
반응형