티스토리 뷰
안드로이드에서는 휴대폰에서 사건이 발생하면 사건마다 정해 놓은 이름으로 시스템 메시지를 발생합니다.
브로드 캐스트 리시버에 동일한 이름으로 설정해두어 동작시킬 수도 있습니다.
아래 링크에 있는 것들은 앱이 실행이 아니라도 사용을 할 수 있습니다.
https://developer.android.com/guide/components/broadcast-exceptions
휴대폰 부팅 시 동작하기
휴대폰 부팅 시에 동작하는 브로드 캐스터 리시버를 만들도록 하겠습니다.
먼저 AndroidManifest.xml에 아래 권한을 추가합니다.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
부팅 권한은 권한 체크가 필요 없습니다.
New > Other > Broadcast Receiver를 통해 하나 만들어 줍니다.
AndroidManifest.xml에서 리시버에 intent filter를 추가해줍니다.
<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
만든 브로드 캐스터 리시버에 아래와 같이 코드를 작성합니다.
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when(intent.action) {
"android.intent.action.BOOT_COMPLETED" -> Toast.makeText(context, "부팅 완료", Toast.LENGTH_SHORT).show()
}
}
}
intent에서 action을 가져와 부팅을 하면 toast 메시지를 띄어주는 코드를 작성하였습니다.
앱을 실행하고 부팅을 하면 아래와 같이 동작하는 것을 확인할 수 있습니다.
지금은 간단히 toast 메시지를 띄우는 코드만 작성을 하였지만 부팅 시 동작하게 하고 싶은 코드를 작성하면 됩니다.
메시지 수신 시 동작하기
https://developer.android.com/reference/android/provider/Telephony.Sms.Intents
먼저 AndroidManifest.xml에 아래 권한을 추가합니다.
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
그리고 리시버의 intent filter에 아래의 코드를 추가해줍니다.
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
MainActivity에서는 권한 체크 코드를 작성해줍니다.
class MainActivity : AppCompatActivity() {
private val permissionList = arrayOf(
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.RECEIVE_SMS
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
checkPermission()
}
private fun checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for(permission in permissionList) {
if(checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_DENIED) {
requestPermissions(permissionList, 0)
}
}
}
}
}
그리고 리시버에 아래의 코드를 작성해 줍니다.
"android.provider.Telephony.SMS_RECEIVED" -> {
var str = ""
val bundle = intent.extras
if (bundle != null) {
val obj = bundle.get("pdus") as Array<*>
val msg = arrayOfNulls<SmsMessage>(obj.size)
for (i in obj.indices) {
msg[i] = SmsMessage.createFromPdu(obj[i] as ByteArray)
}
for (i in msg.indices) {
str = "${msg[i]?.originatingAddress } : ${msg[i]?.messageBody}"
Toast.makeText(context, str, Toast.LENGTH_SHORT).show()
}
}
}
val bundle = intent.extras
intent.extras를 통해 bundle 값을 가져왔습니다.
val obj = bundle.get("pdus") as Array<*>
val msg = arrayOfNulls<SmsMessage>(obj.size)
그리고 pdus를 통해 문자 메시지를 가져오고 msg에 문자 메시지의 데이터가 담길 배열을 만들어 줍니다.
for (i in obj.indices) {
msg[i] = SmsMessage.createFromPdu(obj[i] as ByteArray)
}
문자 메시지 객체를 담아 줍니다.
for (i in msg.indices) {
str = "${msg[i]?.originatingAddress } : ${msg[i]?.messageBody}"
Toast.makeText(context, str, Toast.LENGTH_SHORT).show()
}
그리고 toast를 통해 출력을 해줍니다.
originatingAddress는 전화번호이고 messageBody는 문자 내용입니다.
문자 메시지가 여러 개 올 수 있으므로 for문으로 처리를 하였습니다.
실행하면 아래와 같이 동작합니다.
위의 예제에서 리시버 action 값을 아래와 같은 문자열로 처리를 하였습니다.
when(intent.action) {
"android.intent.action.BOOT_COMPLETED" -> {}
"android.provider.Telephony.SMS_RECEIVED" -> {}
}
하지만 아래와 같이 안드로이드에서 제공되는 것으로 처리할 수 있습니다.
when(intent.action) {
Intent.ACTION_BOOT_COMPLETED -> {}
Telephony.Sms.Intents.SMS_RECEIVED_ACTION -> {}
}
'알려주는 이야기 > 안드로이드' 카테고리의 다른 글
안드로이드 http 통신 (0) | 2020.08.23 |
---|---|
안드로이드 서비스 (0) | 2020.08.23 |
안드로이드 Broad Cast Receiver (0) | 2020.08.22 |
안드로이드 소켓 통신 예제 (0) | 2020.08.22 |
안드로이드 IPC (2) | 2020.08.21 |