Android開發(fā)全局音量調(diào)整的實(shí)現(xiàn)方式詳解
引言
之前參與過一個(gè)項(xiàng)目,開發(fā)的是一個(gè)系統(tǒng)級(jí)別的軟件,安裝在定制的設(shè)備上,設(shè)備沒有控制音量的按鍵,因此軟件需要實(shí)現(xiàn)一個(gè)在任意頁面都能控制音量的功能。
實(shí)現(xiàn)方案是在所有頁面的頂部加上一個(gè)觸發(fā)音量控制彈窗的按鈕,用戶點(diǎn)擊該按鈕后顯示音量控制彈窗。
全局添加按鈕
參與項(xiàng)目時(shí),已經(jīng)出了第一版了,包含的頁面很多,因此一個(gè)個(gè)頁面去加肯定不合適。項(xiàng)目中所有Activity
都繼承了一個(gè)自定義的BaseActivity
,所以只能在這個(gè)BaseActivity
中做文章。
Android中,每個(gè)Activity
都包含一個(gè)DecorView
,DecorView
內(nèi)部包含一個(gè)FrameLayout
,可以通過android.R.id.content
來獲取,我們的布局包含在這個(gè)FrameLayout
中。
因此如果需要在所有的頁面都添加View
,那么在BaseActivity
中實(shí)現(xiàn)向android.R.id.content
對(duì)應(yīng)的FrameLayout
添加View
的邏輯,然后所有的Activity
就都可以自動(dòng)添加View
了。
實(shí)現(xiàn)代碼如下:
object DensityUtil { @JvmStatic fun dp2Px(dpValue: Int): Int { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue.toFloat(), Resources.getSystem().displayMetrics).toInt() } @JvmStatic fun px2Dp(pxValue: Int): Int { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, pxValue.toFloat(), Resources.getSystem().displayMetrics).toInt() } } // Base類 open class BaseActivity : AppCompatActivity() { override fun onResume() { super.onResume() // 在onResume中添加,確保在主布局添加完成后添加,避免被遮擋。 initVolumeControllerView() } private fun initVolumeControllerView() { val controllerView = AppCompatImageView(this) controllerView.layoutParams = FrameLayout.LayoutParams(DensityUtil.dp2Px(80), DensityUtil.dp2Px(12)).apply { gravity = Gravity.START marginStart = DensityUtil.dp2Px(20) topMargin = DensityUtil.dp2Px(10) } controllerView.setImageResource(R.drawable.shape_vollume_controller) controllerView.setOnClickListener { runOnUiThread { Toast.makeText(this, "點(diǎn)擊了全局按鈕", Toast.LENGTH_SHORT).show() } } val rootView = findViewById<FrameLayout>(android.R.id.content) rootView.addView(controllerView) } }
效果如圖:
音量控制
AudioManager
類提供了控制音量的方法。
實(shí)現(xiàn)音量控制代碼如下:
class VolumeControllerDialog : DialogFragment() { private var binding: LayoutVolumeContollerDialogBinding? = null private var currentVolume = 0 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { dialog?.window?.run { setBackgroundDrawable(ContextCompat.getDrawable(requireContext(), android.R.color.transparent)) decorView.setBackgroundResource(android.R.color.transparent) val layoutParams = attributes layoutParams.width = DensityUtil.dp2Px(360) layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT layoutParams.gravity = Gravity.CENTER attributes = layoutParams } binding = DataBindingUtil.inflate(inflater, R.layout.layout_volume_contoller_dialog, container, false) return binding?.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val audioManager = requireContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) val step = 1 binding?.run { btnMute.text = getMuteButtonString(audioManager.isStreamMute(AudioManager.STREAM_MUSIC)) btnIncreaseVolume.setOnClickListener { // 增加音量 currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume + step, AudioManager.FLAG_SHOW_UI or AudioManager.FLAG_PLAY_SOUND) btnMute.text = getMuteButtonString(audioManager.isStreamMute(AudioManager.STREAM_MUSIC)) } btnReduceVolume.setOnClickListener { //減少音量 currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, if (currentVolume - step < 0) 0 else currentVolume - step, AudioManager.FLAG_SHOW_UI or AudioManager.FLAG_PLAY_SOUND) btnMute.text = getMuteButtonString(audioManager.isStreamMute(AudioManager.STREAM_MUSIC)) } btnMute.setOnClickListener { // 靜音或取消靜音 val currentMute = audioManager.isStreamMute(AudioManager.STREAM_MUSIC) if (currentVolume == 0) { btnMute.text = getMuteButtonString(true) } else { btnMute.text = getMuteButtonString(!currentMute) } val setVolume = if (currentMute) { currentVolume } else { currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) 0 } audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, setVolume, AudioManager.FLAG_SHOW_UI or AudioManager.FLAG_PLAY_SOUND) } } } private fun getMuteButtonString(mute: Boolean): String { return if (mute) "UnMute" else "Mute" } } open class BaseActivity : AppCompatActivity() { override fun onResume() { super.onResume() // 在onResume中添加,確保在主布局添加完成后添加,避免被遮擋。 initVolumeControllerView() } private fun initVolumeControllerView() { val controllerView = AppCompatImageView(this) controllerView.layoutParams = FrameLayout.LayoutParams(DensityUtil.dp2Px(80), DensityUtil.dp2Px(12)).apply { gravity = Gravity.START marginStart = DensityUtil.dp2Px(20) topMargin = DensityUtil.dp2Px(10) } controllerView.setImageResource(R.drawable.shape_vollume_controller) controllerView.setOnClickListener { VolumeControllerDialog().show(supportFragmentManager, null) } val rootView = findViewById<FrameLayout>(android.R.id.content) rootView.addView(controllerView) } }
效果如圖:
以上就是Android開發(fā)全局音量調(diào)整的實(shí)現(xiàn)方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Android 全局音量調(diào)整的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android制作登錄頁面并且記住賬號(hào)密碼功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android制作登錄頁面并且記住賬號(hào)密碼功能的實(shí)現(xiàn)代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04Android webview加載https鏈接錯(cuò)誤或無響應(yīng)的解決
這篇文章主要介紹了Android webview加載https鏈接錯(cuò)誤或無響應(yīng)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03Android使用DatePickerDialog顯示時(shí)間
本文將結(jié)合實(shí)例代碼,介紹Android使用DatePickerDialog顯示時(shí)間,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07Android利用Intent實(shí)現(xiàn)記事本功能(NotePad)
這篇文章主要為大家詳細(xì)介紹了Android利用Intent實(shí)現(xiàn)簡單記事本功能(NotePad)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06Android?TextView的maxEms和maxLength屬性區(qū)別
這篇文章主要為大家介紹了Android?TextView的maxEms和maxLength屬性區(qū)別,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03解決Kotlin 類在實(shí)現(xiàn)多個(gè)接口,覆寫多個(gè)接口中相同方法沖突的問題
這篇文章主要介紹了解決Kotlin 類在實(shí)現(xiàn)多個(gè)接口,覆寫多個(gè)接口中相同方法沖突的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03Android開發(fā)手冊TextView屬性實(shí)現(xiàn)效果盤點(diǎn)
這篇文章主要為大家介紹了Android開發(fā)手冊TextView屬性實(shí)現(xiàn)的效果盤點(diǎn)及使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06