[Android] 알림 효과 정리

Minjun Kim·2023년 9월 3일
0

Android

목록 보기
32/47
post-thumbnail

📝 SeSAC의 'JetPack과 Kotlin을 활용한 Android App 개발' 강좌를 정리한 글 입니다.


📚 Vibration

📌 Manifest 에 퍼미션 설정

<uses-permission android:name="android.permission.VIBRATE" />
  • 퍼미션 필요

📌 Vibrator 시스템 서비스

val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION.CODES.S) {
	val vibratorManager = this.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
    vibratorManager.defaultVibrator,
} else {
	getSystemService(VIBRATOR_SERVICE) as Vibrator
}
  • Vibrator 라는 시스템 서비스 이용

  • API Level 31 이전 버전에서는 Vibrator 라는 시스템 서비스 이용

  • API Level 31 버전부터는 VibratorManager 라는 시스템 서비스 이용

📌 진동

API Level 26 이전 버전에서 사용되던 함수

open fun vibrate(milliseconds: Long): Unit
- 매개변수로 진동이 울리는 시간 지정

open fun vibrate(pattern: LongArray!, repeat: Int): Unit
- 진동을 여러번 울리는 경우 매개변수를 배열로 전달

API Level 26 버전부터 사용되는 함수

open fun vibrate(vibe: VibrationEffect!): Unit
- 매개변수로 VibrationEffect 라는 객체 전달
VibrationEffect 객체 획득 방법

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

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

분기 프로그램

if (Build.VERSION.SDK_INT >= Build.VERSION.CODES.O) {
	vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE))
} else {
	vibrator.vibrate(500)
}

📚 Beep

대부분의 앱이 그냥 시스템에 등록되어 있는 알림음을 갖다 쓴다.

val notification: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val ringtone = RingtoneManager.getRingtone(applicationContext, notification)
ringtone.play()
  • 시스템에 등록된 알림음 플레이

  • 시스템에는 알림(NOTIFICATION), 알람(ALARM), 링톤(RINGTONE) 등의 음이 준비되어 있다.

  • Uri 로 기본 효과음의 식별자 값을 얻는다.

  • RingtoneManager의 getRingtone() 함수에 식별자를 지정하면 Ringtone 객체가 리턴 된다.

  • Ringtone 객체의 play() 함수를 콜하면 효과음을 울릴 수 있다.

📌 독자적인 효과음 사용

  • 임의의 음원을 비프음으로 사용 한다면 raw 폴더 이용

  • raw 폴더는 음원 뿐만 아니라 바이트 데이터로 직접 사용되는 리소스를 담는다.

val player: MediaPlayer = MediaPlayer.create(this, R.raw.fallbackring)
player.start()
  • MediaPlayer 클래스 이용

  • MediaPlayer 클래스는 알림음 뿐만 아니라 일반적으로 음원 혹은 영상을 플레이하기 위한 API 이다.

  • start() 함수로 플레이 한다.

🧩 실습 예제

  • activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:gravity="center">

    <Button
        android:id="@+id/vibration"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Vibration"/>

    <Button
        android:id="@+id/beep"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="beep"/>

</LinearLayout>


  • MainActivity.kt
package com.kotdev99.android.c52

class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)

		val vibButton = findViewById<Button>(R.id.vibration)
		val beepButton = findViewById<Button>(R.id.beep)

		vibButton.setOnClickListener {
			val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
				val vibManager =
					this.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
				vibManager.defaultVibrator
			} else {
				getSystemService(VIBRATOR_SERVICE) as Vibrator
			}

			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
				vibrator.vibrate(
					VibrationEffect.createOneShot(
						500,
						VibrationEffect.DEFAULT_AMPLITUDE
					)
				)
			} else {
				vibrator.vibrate(500)
			}
		}

		beepButton.setOnClickListener {
			val uri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
			val ringtone = RingtoneManager.getRingtone(applicationContext, uri)
			ringtone.play()
		}
	}
}

  • AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.VIBRATE" />
    <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/Theme.AndroidLab">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

📲 결과

진동은 실제 핸드폰으로 확인


📚 Toast

화면 하단에 잠깐 출력되는 문자열

Toast.makeText(this, "text", Toast.LENGTH_SHORT).show()
  • open static fun makeText(context: Context!, text: CharSequence!, duration: Int): Toast!

  • open static fun makeText(context: Context!, resId: Int, duration: Int): Toast!

  • val LENGTH_LONG: Int -> 5초

  • val LENGTH_SHORT: Int -> 3초


📇 Dialog

📚 AlertDialog

AlertDialog 라는 API 제공

  • 안드로이드 다이얼로그의 기본

  • 단순히 문자열만 출력할 수도 있고 다양한 화면을 출력할 수도 있다.

  • AlertDialog 의 화면은 title, content, button 영역으로 구분

📌 기본 함수

AlertDialog.Builder 를 생성하고 Builder 의 setter 함수를 이용해 다이얼로그의 정보를 지정

  • open fun setIcon(iconId: Int) : AlertDialog.Builder!

  • open fun setTitle(title: CharSequence!) : AlertDialog.Builder!

  • open fun setMessage(message: CharSequence!) : AlertDialog.Builder!

버튼은 최대 3개 까지만 추가

  • open fun setPositiveButton(text: CharSequence!, listener: DialogInterface.OnClickListener!)

  • open fun setNegativeButton(text: CharSequence!, listener: DialogInterface.OnClickListener!)

  • open fun setNeutralButton(text: CharSequence!, listener: DialogInterface.OnClickListener!)

목록을 제공하는 다이얼로그

  • open fun setItems(items: Array<CharSequence!>!, listener: DialogInterface.OnClickListener!)

  • open fun setMultiChoiceItems(items: Array<CharSequence!>!, checkedItems: BooleanArray!, listener: DialogInterface.OnMultiChoiceClickListener!)

  • open fun setSingleChoiceItems(items: Array<CharSequence!>!, checkedItem: Int, listener: DialogInterface.OnClickListener!)

📚 DatePickerDialog

날짜를 입력받기 위해 제공되는 다이얼로그

  • DatePickerDialog(context: Context, listener: DatePickerDialog.onDateSetListener?, year: Int, month: Int, dayOfMonth: Int)

📚 TimePickerDialog

시간을 입력받기 위해 제공되는 다이얼로그

  • TimePickerDialog(context: Context!, listener: TimePickerDialog.onTimeSetListener!, hourOfDay: Int, minute: Int, is24HourView: Boolean)

🧩 실습 예제

  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/alertDialogButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="alert dialog" />

    <Button
        android:id="@+id/listDialogButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="list dialog" />

    <Button
        android:id="@+id/dateDialogButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="date dialog" />

    <Button
        android:id="@+id/timeDialogButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="time dialog" />

</LinearLayout>

  • MainActivity.kt
package com.kotdev99.android.c53

class MainActivity : AppCompatActivity() {
	@SuppressLint("ResourceType")
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)

		val alertDialog = findViewById<Button>(R.id.alertDialogButton)
		val listDialog = findViewById<Button>(R.id.listDialogButton)
		val dateDialog = findViewById<Button>(R.id.dateDialogButton)
		val timeDialog = findViewById<Button>(R.id.timeDialogButton)

		alertDialog.setOnClickListener {
			AlertDialog.Builder(this).run {
				setTitle("test dialog")
				setIcon(android.R.drawable.ic_dialog_alert)
				setMessage("정말 종료하시겠습니까?")
				setPositiveButton("OK", null)
				setNegativeButton("Cancel", null)
				show()
			}
		}

		listDialog.setOnClickListener {
			val items = arrayOf<String>("사과", "복숭아", "수박")
			AlertDialog.Builder(this).run {
				setTitle("items test")
				setItems(items, object : DialogInterface.OnClickListener {
					override fun onClick(p0: DialogInterface?, p1: Int) {
						Toast.makeText(
							this@MainActivity, "선택한 항목: ${items[p1]}", Toast.LENGTH_SHORT
						).show()
					}
				})
				setPositiveButton("ok", null)
				show()
			}
		}

		dateDialog.setOnClickListener {
			DatePickerDialog(this, object : DatePickerDialog.OnDateSetListener {
				override fun onDateSet(p0: DatePicker?, p1: Int, p2: Int, p3: Int) {
					Toast.makeText(
						this@MainActivity, "$p1, ${p2 + 1}, $p3", Toast.LENGTH_SHORT
					).show()
				}
			}, 2022, 8, 21).show()
		}

		timeDialog.setOnClickListener {
			TimePickerDialog(this, object : TimePickerDialog.OnTimeSetListener {
				override fun onTimeSet(p0: TimePicker?, p1: Int, p2: Int) {
					Toast.makeText(
						this@MainActivity, "$p1, $p2", Toast.LENGTH_SHORT
					).show()
				}
			}, 15, 0, true).show()
		}
	}
}
profile
응애 나 아기 뉴비

0개의 댓글