오늘은 Receiver 챕터 배터리 정보 앱을 구현해봤다.
메인 액티비티에서 배터리 상태를 바로 알 수 있게한다.
배터리의 충전량과 전원 연결 여부 표시
버튼을 누르면 브로드캐스트 리시버를 실행해 알림을 띄운다.
초기상태
배터리 소모 + 충전상태
알림
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val permissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) {
if (it.all { permission -> permission.value == true }) {
val intent = Intent(this, MyReceiver::class.java)
sendBroadcast(intent)
} else {
Toast.makeText(this, "permission denied...", Toast.LENGTH_SHORT).show()
}
}
registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))!!.apply {
when(getIntExtra(BatteryManager.EXTRA_STATUS, -1)){
BatteryManager.BATTERY_STATUS_CHARGING -> {
when(getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)){
BatteryManager.BATTERY_PLUGGED_USB -> {
binding.chargingResultView.text = "USB Plugged"
binding.chargingImageView.setImageBitmap(BitmapFactory.decodeResource(
resources, R.drawable.usb
))
}
BatteryManager.BATTERY_PLUGGED_AC -> {
binding.chargingResultView.text = "AC Plugged"
binding.chargingImageView.setImageBitmap(BitmapFactory.decodeResource(
resources, R.drawable.ac
))
}
}
}
else -> {
binding.chargingResultView.text = "Not Plugged"
}
}
val level = getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale = getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPct = level / scale.toFloat() * 100
binding.percentResultView.text = "$batteryPct %"
}
binding.button.setOnClickListener {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(
this,
"android.permission.POST_NOTIFICATIONS"
) == PackageManager.PERMISSION_GRANTED
) {
val intent = Intent(this, MyReceiver::class.java)
sendBroadcast(intent)
} else {
permissionLauncher.launch(
arrayOf(
"android.permission.POST_NOTIFICATIONS"
)
)
}
}else {
val intent = Intent(this, MyReceiver::class.java)
sendBroadcast(intent)
}
}
}
}
class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("event","MyReceiver...............")
val manager = context.getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager
val builder: NotificationCompat.Builder
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//26버전 이상
val channelId = "one-channel"
val channelName = "My Channel One"
val channel = NotificationChannel(
channelId,
channelName,
NotificationManager.IMPORTANCE_DEFAULT
).apply {
//채널에 정보 설정
description = "My Channel One Description"
setShowBadge(true)
val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val audioAttributes = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build()
setSound(uri, audioAttributes)
enableVibration(true)
}
//채널을 NotificationManager에 등록
manager.createNotificationChannel(channel)
//채널을 이용하여 builder 생성
builder = NotificationCompat.Builder(context, channelId)
} else {
//26버전 이하
builder = NotificationCompat.Builder(context)
}
builder.run {
//알림 기본 정보
setSmallIcon(android.R.drawable.ic_notification_overlay)
setWhen(System.currentTimeMillis())
setContentTitle("배터리 알림")
setContentText("배터리 알림입니다.")
}
manager.notify(11, builder.build())
}
}
모듈이 실행이 안되는 에러가 발생
FATAL EXCEPTION: main
Process: com.example.ch14_receiver, PID: 21746
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.ch14_receiver/com.example.ch14_receiver.MainActivity}:
java.lang.IllegalStateException:
You need to use a Theme.AppCompat theme (or descendant) with this activity.