안드로이드/개발관련(Kotlin)

안드로이드 AudioManager로 볼륨 조절(Kotlin)

닉네임못짓는사람 2022. 1. 3. 02:13
반응형

이번 글에선 안드로이드에서 AudioManager를 사용해 볼륨을 조절하는 법에 대해 알아보도록 하자.

권한 요청


해당 기능을 사용하기 위해선 방해금지 권한이 필요하다.

android.permission.ACCESS_NOTIFICATION_POLICY

먼저, Manifest파일에 위와 같은 코드를 추가해주고

 

사용자에게 권한을 요청해야 하는데, 여기서 다른 권한들과 요청하는 방법이 조금 다르다.

val notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if(Build.VERSION.SDK_INT >= 23){
    if(!notificationManager.isNotificationPolicyAccessGranted){
        this.startActivity(Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS))
    }
}

위와 같이 코드를 작성하고 실행하게 되면, 앱에 방해금지 권한을 주는 화면으로 이동하게 된다.

이렇게 권한을 모두 요청하였으면 실제로 AudioManager를 사용해 볼륨을 조절해보도록 하자.

Layout작성


이제 Layout파일을 아래와 같이 작성해준다.

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

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/apply"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="적용" />

    <Button
        android:id="@+id/vib"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="진동" />

    <Button
        android:id="@+id/silent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="무음" />
</LinearLayout>

화면에 seekbar와 버튼 세 개를 배치하는데, seekbar의 값을 받아오거나

진동이나 무음 버튼을 누름으로써 볼륨을 조절하도록 만들어보자.

볼륨 조절


이제 실제로 볼륨을 조절하는 코드를 MainActivity에 작성한다.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        getPermisson()

        binding.apply.setOnClickListener{
            val volume = binding.seekBar.progress
            Log.e("seekbar", "${binding.seekBar.progress}")
            volChange(volume)
        }

        binding.vib.setOnClickListener {
            volChange(0)
        }

        binding.silent.setOnClickListener {
            volChange(-1)
        }
    }

    private fun getPermisson(){
        val notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if(Build.VERSION.SDK_INT >= 23){
            if(!notificationManager.isNotificationPolicyAccessGranted){
                this.startActivity(Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS))
            }
        }
    }

    private fun volChange(volume: Int){
        val audioManager = this.applicationContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager

        when(volume){
            -1 -> audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT
            else -> {
                audioManager.ringerMode = AudioManager.RINGER_MODE_NORMAL
                audioManager.setStreamVolume(
                        AudioManager.STREAM_RING,
                        (audioManager.getStreamMaxVolume(AudioManager.STREAM_RING) * volume/100.0).toInt(),
                        AudioManager.FLAG_PLAY_SOUND
                )
            }
        }
    }
}

먼저 권한을 요청하고, 버튼을 누르면 볼륨 값을 인자로 주어 volChange함수를 실행시킨다.

해당 함수에선 스마트폰 벨소리의 볼륨을 조절한다.

 

무음 버튼은 -1을 값으로 전달하고, 진동 버튼은 0을 전달한다.

또한 seekbar의 최솟값은 0, 최댓값은 100이다.

 

그리고 volChange함수에서 setStreamVolume이후 괄호 내의 두 번째 줄을 보면,

이 부분이 실제로 볼륨 값을 정하는 부분인데 먼저 getStreamMaxvolume값을 구해야 한다.

 

왜냐하면 전화나 응용프로그램에서의 최댓값이 다르기 때문인데,

그래서 최댓값을 먼저 구한 뒤 volume값을 가지고 비율을 구해서 적용해주어야 한다.

FLAG_PLAY_SOUND는 소리를 한 번 재생해주는 부분이다. (진동이나 비프음)

 

코드를 실행했을 때 AVD에서는 잘 되지 않아서 실제 기기해서 사용해보니

정상적으로 동작하는 걸 확인했다.

반응형