본문 바로가기
깡샘 코틀린

10-4 소리와 진동 알림

by 농농씨 2023. 6. 25.

소리알림

사용자에게 짧은 소리로 특정한 상황을 알리는 것을 알림음이라고 한다.

알림음은 카카오톡처럼 자체 녹음한 음원을 쓸 수도 있지만 안드로이드 시스템에 등록된 소리를 이용할 수도 있다. 먼저 시스템에 등록된 소리를 이용하는 방법을 살펴보자.

안드로이드 시스템은 알림(NOTIFICATION), 알람(ALARM), 벨소리(RINGTONE) 등의 소리를 제공하며 이 소리는 RingtoneManager로 얻을 수 있다.

// 소리 얻기
val notification: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
// 함수로 소리의 식별값 얻음
val ringtone = RingtoneManager.getRingtone(applicationContext, notification)
// 소리의 식별값을 매개변수로 전달해서 Ringtone 객체 얻음
ringtone.play() // 얻은 Ringtone객체의 play() 함수를 호출함

1️⃣먼저 RingtoneManager.getDefaultUri() 함수를 이용해 소리의 식별값을 얻는다. 이 식별값은 Uri 객체이며 2️⃣이 값을 RingtoneManager.getRingtone() 함수의 두번째 매개변수로 전달하면 소리를 재생하는 Ringtone 객체를 얻는다. 3️⃣이 Ringtone 객체의 play() 함수를 호출하면 비로소 소리가 재생된다.

 

이번에는 앱에서 자체 음원을 준비해서 재생하는 방법을 보자. 음원 파일은 리소스로 등록해서 이용해야 하는데 음원 리소스 디렉터리는 res/raw이다.

음원을 재생하는 클래스는 MediaPlayer이다. 이 클래스에 리소스 정보를 지정하고 start() 함수를 호출하면 음원이 재생된다.

// 음원 재생하기
val player: MediaPlayer = MediaPlayer.create(this, R.raw.fallbackring)
player.start()

 

 

진동 알림

진동도 사용자 알림 효과로 많이 이용한다. 앱에서 진동이 울리게 하려면 먼저 매니페스트 파일에 <uses-permission>으로 퍼미션을 얻어야 한다.

// 진동 퍼미션 얻기(매니페스트 파일)
<uses-permission android:name="android.permission.VIBRATE" />

진동은 Vibrator 클래스를 이용한다. 그런데 Vibrator 객체를 얻는 방법이 API 레벨 31(Android 12)부터 변경됐다. 31 이전 버전에서는 VIBRATOR_SERVICE로 식별되는 시스템 서비스를 이용했지만, 31 버전부터는 VIBRATOR_MANAGER_SERVICE로 식별되는 VibratorManager라는 시스템 서비스를 얻고 이 서비스에서 Vibrator를 이용해야 한다.

// 진동 객체 얻기
val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
	val vibratorManaget = this.getSystemService(Context.VIBRATOR_MANAGER_SERVICE)
    				      as VibratorManager
    vibratorManager.defaultVibrator;                      
} else {
	getSystemService(VIBRATOR_SERVICE) as Vibrator
}

 

시간과 패턴을 지정해 진동 울리기(API 레벨 1부터 제공하는 함수)

그런데 API 레벨 1부터 제공한 진동 알림 함수가 26 버전(Android 8)에서 deprecated*되었다. 26 버전에서 새로운 함수를 제공하지만 이전 버전의 기기 사용자를 위해 여전히 사용해야 한다. 결국 [10-1]절에서 살펴봤던 API 레벨 호환성을 고려해서 사용해야 한다.

* deprecated는 사용을 보장할 수 없으니 더는 사용하지 말라는 뜻이다.

API 레벨 1부터 제공했다가 deprecated 된 진동 알림 함수는 다음과 같다.

  • open fun vibrate(milliseconds: Long): Unit
  • open fun vibrate(pattern: LongArray!, repeat: Int): Unit

첫번째 함수의 매개변수는 Long타입 하나이다. 이 매개변수는 진동이 울리는 시간을 의미한다. 만약 500으로 설정하면 0.5초간 진동이 울린다.

두번째 함수는 매개변수가 2개인데 진동을 반복해서 울리는 함수이다. 첫번째 매개변수에는 진동패턴을 배열로 지정한다. 만약 500, 1000, 500, 2000 의 배열값을 전달하면 0.5초 쉬고 1초간 울리고 0.5초 쉬고 2초간 울린다. 두번째 매개변수는 이 패턴을 얼마나 반복할지를 지정한다. 만약 -1로 지정하면 반복하지 않고 패턴대로 한 번만 진동이 울리고, 0으로 지정하면 코드에서 cancel()함수로 진동 알림을 끄지 않는 한 패턴대로 계속 울린다. 

 

진동의 세기까지 지정해 진동 울리기(API 레벨 26부터 제공하는 함수)

그런데 API 레벨 26부터는 진동 정보를 VibrationEffect 객체로 지정할 수 있는 함수를 제공한다. VibrationEffect 객체로는 진동이 울리는 시간 이외에 진동의 세기까지 제어할 수 있다. 다음은 API 레벨 26에서 제공하는 진동 알림 함수이다.

  • open fun vibrate(vibe: VibrationEffect!): Unit

vibrate() 함수의 매개변수에 VibrationEffect객체를 지정한다. VibrationEffect는 진동 정보를 지정하는 다음 함수를 제공한다.

  • open static fun createOneShot(milliseconds: Long, amplitude: Int): VibrationEffect!

이 함수로 만든 VibrationEffect 객체를 vibrate() 함수에 대입하면 첫 번째 매개변수의 시간 동안 진동이 울린다. 그리고 두 번째 매개변수를 이용해 진동의 세기를 지정할 수 있다. 진동의 세기는 0~255 사이의 숫자로 표현하며, 0으로 지정하면 진동이 울리지 않고 255는 기기에서 지원하는 가장 센 강도로 울린다.

이렇게 숫자를 직접 대입해도 되고 VibrationEffect.DEFAULT_AMPLITUDE처럼 상수를 지정해 기기가 정의한 기본 세기로 진동이 울리게 할 수도 있다.

// 기본 세기로 진동 울리기
if (Build.VERSIN.SDK_INT >= Build.VERSION_CODES.0) {
	vibrator.vibrate(
    	VibrationEffect.createOneShot(500,
        VibrationEffect.DEFAULT_AMPLITUDE))
} else {
	vibrator.vibrate(500)
}

 

이번에는 반복해서 진동을 울리는 createWaveform() 함수를 살펴보자.

  • open static fun createWaveform(timings: LongArray!, amplitudes: IntArray!, repeat: Int): VibrationEffect!

첫 번째 매개변수는 마찬가지로 진동이 울리는 시간 패턴의 배열이며, 두 번째 매개변수는 진동 세기 패턴의 배열이다. 그리고 세 번째 매개변수가 이 패턴의 반복 횟수이다. 

// 패턴대로 반복해서 울리기
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.0) {
	vibrator.vibrate(VibrationEffect.createWaveform(longArrayOf(500, 1000, 500, 2000),
    intArrayOf(0, 50, 0, 200), -1)) // create~부터 주목!
} else {
	vibrator.vibrate(longArrayOf(500, 1000, 500, 2000), -1)
}

createWaveform() 함수의 첫 번째와 두 번째 매개변수를 보면 각각 4개의 숫자 배열을 대입했다. 이렇게 하면 처음 0.5초간은 진동이 울리지 않다가 1초간 50만큼의 세기로 울리고, 다시 0.5초간 울리지 않다가 마지막 2초간 200만큼의 세기로 울린다.(반복은 -1이라는 숫자로 반복하지 않음을 나타냄)

'깡샘 코틀린' 카테고리의 다른 글

11-1 제트팩과 androidx 소개  (0) 2023.06.27
10-5 알림 띄우기  (0) 2023.06.27
10-3 다양한 다이얼로그  (0) 2023.06.24
10-2 퍼미션 설정하기  (0) 2023.06.24
10-1 API 레벨 호환성 고려하기  (2) 2023.06.24