안드로이드 앱 개발 시, minSdk와 targetSdk를 설정하여 앱의 최소 지원 버전과 목표 버전을 지정한다.
minSdk 24
targetSdk 34
위 설정은 앱이 API 레벨 34 버전에서 개발되지만, API 레벨 24 이상을 지원하는 기기에서도 오류 없이 동작해야 함을 의미한다. 하지만, 개발 중에 minSdk 설정값보다 상위 버전에서 제공하는 API를 사용한다면, 하위 버전에서의 호환성 문제를 고려해야 한다.
위 이미지에서 Notification
클래스는 API 레벨 1에서 추가되었음을 나타낸다. 즉, 이 클래스는 모든 안드로이드 버전에서 사용할 수 있으므로, minSdk
를 24로 설정한 앱에서도 API 레벨 호환성 문제가 발생하지 않는다.
그러나, 상위 버전에 새로 추가된 기능을 사용할 때는 상황이 달라진다.
예를 들어, Notification.CallStyle
클래스는 API 레벨 31에 추가되었다. 따라서 이 클래스를 사용할 경우, API 레벨 24를 사용하는 기기에서는 호환성 문제가 발생한다. 이때, 안드로이드 스튜디오에서 컴파일 에러 또는 경고가 발생할 수 있다.
안드로이드에서는 이러한 호환성 문제를 해결하기 위해 @RequiresApi
또는 if (Build.VERSION.SDK_INT >= ...)
조건문을 사용한다.
@RequiresApi(Build.VERSION_CODES.S) // API 레벨 31 이상에서만 호출 가능
fun useCallStyleNotification() {
val callStyle = Notification.CallStyle.forIncomingCall("caller", null, null)
// API 레벨 31 이상에서만 사용 가능한 기능
}
위와 같이 @RequiresApi
애너테이션을 사용하면, 해당 함수가 특정 API 레벨 이상에서만 호출되도록 제한할 수 있다.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// API 레벨 31 이상에서만 사용 가능한 기능
val callStyle = Notification.CallStyle.forIncomingCall("caller", null, null)
} else {
// 하위 버전에서 사용할 대체 기능
}
위 코드에서는 조건문을 통해 기기의 API 레벨을 체크한 후, 해당 기능을 사용할지 여부를 결정한다.
API 레벨 호환성은 안드로이드 앱 개발에서 중요한 부분이다.
minSdk
보다 상위 버전의 API를 사용할 때는 반드시 호환성을 고려해야 하며, 이를 위해 애너테이션 또는 조건문을 통해 안전한 코드를 작성해야 한다.
안드로이드 시스템에서는 민감한 정보에 접근하거나 기기 기능을 사용할 때 사용자로부터 권한을 요청해야 한다.
INTERNET
).CAMERA
), 위치 접근 권한 (ACCESS_FINE_LOCATION
).READ_LOGS
.READ_CONTACTS
권한을 승인하면, 같은 그룹의 WRITE_CONTACTS
권한도 자동으로 승인된다.ActivityCompat.requestPermissions()
메서드를 사용한다.onRequestPermissionsResult()
콜백 메서드를 통해 결과를 처리한다.shouldShowRequestPermissionRationale()
메서드를 통해 권한이 필요한 이유를 설명하는 UI를 제공하는 것이 좋다.ACCESS_FINE_LOCATION
과 ACCESS_COARSE_LOCATION
외에 백그라운드 위치 권한 (ACCESS_BACKGROUND_LOCATION
)으로 세분화되었다.Toast.makeText(context, "This is a Toast message", Toast.LENGTH_SHORT).show()
Toast.LENGTH_SHORT
는 짧은 시간(약 2초), Toast.LENGTH_LONG
은 긴 시간(약 3.5초) 동안 표시됩니다.안드로이드에서 날짜나 시간을 입력받을 때는 DatePickerDialog
와 TimePickerDialog
를 사용한다. 이 다이얼로그들은 사용자가 날짜 또는 시간을 선택할 수 있는 UI를 제공한다.
날짜 선택 다이얼로그:
DatePickerDialog(context, { _, year, month, dayOfMonth ->
// 선택된 날짜 처리
}, year, month, day).show()
시간 선택 다이얼로그:
TimePickerDialog(context, { _, hourOfDay, minute ->
// 선택된 시간 처리
}, hour, minute, true).show() // true는 24시간 형식 사용 여부
AlertDialog.Builder(context)
.setTitle("Alert")
.setMessage("This is an alert dialog")
.setPositiveButton("OK") { dialog, _ -> dialog.dismiss() }
.setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() }
.show()
안드로이드에서 소리를 재생하기 위해 다양한 방법을 사용할 수 있다.
val soundPool = SoundPool.Builder().setMaxStreams(5).build()
val soundId = soundPool.load(this, R.raw.sound_file, 1)
soundPool.play(soundId, 1f, 1f, 0, 0, 1f)
val mediaPlayer = MediaPlayer.create(this, R.raw.music_file)
mediaPlayer.start()
val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volumeLevel, 0)
진동은 사용자가 기기에서 특정 이벤트를 인식하도록 도와준다.
알림, 경고, 사용자 인터페이스 상호작용 시 피드백을 제공하는 데 유용하다.
Vibrator
클래스를 사용한다. 간단한 진동부터 패턴 진동까지 다양한 설정을 할 수 있다.val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)) // 500ms 진동
} else {
vibrator.vibrate(500) // 500ms 진동 (레거시 방식)
}
val pattern = longArrayOf(0, 200, 100, 300) // 대기 0ms, 진동 200ms, 멈춤 100ms, 진동 300ms
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createWaveform(pattern, -1)) // -1은 반복 없음
} else {
vibrator.vibrate(pattern, -1) // 레거시 방식
}
AudioManager
를 통해 현재 기기의 소리 모드를 확인하고(예: 무음, 진동 모드) 이에 맞게 동작을 조정해야 한다.VIBRATE
권한이 필요하며, 알림이나 소리 관련 기능을 추가할 때 권한 요청 및 설정이 적절히 이루어져야 한다.알림은 안드로이드 시스템 상단의 상태 바에 표시되며, 사용자가 이를 클릭하면 특정 액션을 수행하도록 할 수 있다. 기본적으로 알림은 다음과 같은 구조로 이루어진다:
예시)
NotificationCompat.Builder: 알림을 생성하기 위한 빌더 클래스다. 이 빌더를 사용해 알림의 제목, 내용, 아이콘, 우선순위 등을 설정한다.
NotificationManager: 생성된 알림을 시스템에 전달하여 실제로 표시되도록 하는 클래스다. notify()
메서드를 통해 알림을 화면에 띄운다.
API 레벨 33(Android 13, Tiramisu) 이상에서는 알림을 띄우기 전에 사용자에게 권한을 요청해야 한다. 이는 사용자가 원치 않는 알림을 받을 가능성을 줄이기 위한 보안 조치이다.
알림은 다음 단계로 구성된다.
API 레벨 33 이상에서는 알림을 띄우기 전에 권한을 요청해야 한다.
권한이 부여되지 않으면 알림을 띄울 수 없으므로, 권한이 필요한 경우 이를 처리하는 로직을 추가해야 한다.
IMPORTANCE_HIGH
로 설정하면 알림이 팝업으로 표시되고 소리와 진동이 함께 발생한다.PendingIntent
를 사용한다.{책의 내용은 너무 방대해서 스킵하고 간단하게 정리하였다.}