Audio Focus: khái niệm, chế độ và quản lý trong Android

Tác giả: IT Sectr Đã đăng: 2026-05-23 Thời gian đọc: 8 phút

Audio Focus là cơ chế Android điều chỉnh việc sử dụng đồng thời đầu ra âm thanh bởi nhiều ứng dụng. Nó ngăn chặn sự chồng chéo âm thanh: khi một ứng dụng bắt đầu phát, hệ thống tự động giảm hoặc tạm dừng ứng dụng khác. Theo Android Developer Guide, 2026, Audio Focus là bắt buộc đối với tất cả ứng dụng phát âm thanh — nếu không có nó, Google Play có thể từ chối bản cập nhật.

Những điểm chính

  • Audio Focus là cơ chế hệ thống Android để phối hợp phát âm thanh giữa các ứng dụng mà không chồng chéo âm thanh.
  • Yêu cầu focus được thực hiện qua AudioManager.requestAudioFocus() với loại và thời lượng phát được chỉ định.
  • Hệ thống thông báo về thay đổi focus qua AudioManager.OnAudioFocusChangeListener với các mã AUDIOFOCUS_GAIN, LOSS và DUCK.
  • Auto Resume — khi nhận AUDIOFOCUS_LOSS, ứng dụng phải tạm dừng phát và tiếp tục khi nhận AUDIOFOCUS_GAIN.
  • Android 12+ yêu cầu sử dụng AudioFocusRequestCompat từ AndroidX để tạo yêu cầu focus.

Audio Focus là gì?

Audio Focus là hệ thống phân xử âm thanh tập trung trong Android. Khi một ứng dụng yêu cầu focus, hệ thống kiểm tra xem có “chủ sở hữu” focus đang hoạt động không và gửi cho họ thông báo mất focus. Chủ sở hữu có thể giảm âm lượng (duck), tạm dừng phát hoặc bỏ qua — tùy thuộc vào loại focus.

Trước Android 8.0, focus được quản lý qua AudioManager.requestAudioFocus(callback, stream, durationHint). Bắt đầu từ Android 8.0, AudioFocusRequest được giới thiệu, thêm khả năng chỉ định loại yêu cầu và tự động khôi phục focus. Trong Android 12, cơ chế được tăng cường — tất cả trình phát đa phương tiện phải xử lý focus chính xác để xuất bản trên Google Play.

Theo Google I/O 2024, khoảng 15% khiếu nại của người dùng trong đánh giá ứng dụng âm thanh liên quan đến chồng chéo âm thanh. Triển khai Audio Focus đúng cách giải quyết vấn đề này và cải thiện trải nghiệm người dùng lên 30% về thời gian nghe.

Audio Focus và phát đa phương tiện

Điều quan trọng là hiểu rằng Audio Focus không tự động kiểm soát việc phát. Nó chỉ thông báo cho ứng dụng về các sự kiện focus. Ứng dụng tự quyết định: tạm dừng trình phát, giảm âm lượng hoặc tiếp tục phát. Hệ thống không ép buộc — quyết định kiến trúc này được để cho nhà phát triển.

Ngoại lệ là các ứng dụng điều hướng (Google Maps, Yandex Maps). Chúng có thể yêu cầu loại focus AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, nơi trình phát hiện tại bị giảm âm lượng trong khi hướng dẫn bằng giọng nói phát trên nó. Sau khi hướng dẫn kết thúc, trình phát tự động khôi phục âm lượng.

Audio Focus hoạt động như thế nào trong Android

Hệ thống duy trì một chủ sở hữu focus âm thanh hoạt động duy nhất. Khi một ứng dụng mới yêu cầu focus, hệ thống xác định ưu tiên và gửi sự kiện cho chủ sở hữu hiện tại. Nếu chủ sở hữu hiện tại bỏ qua sự kiện và tiếp tục phát to, hệ thống không áp dụng hình phạt — trách nhiệm hoàn toàn thuộc về trình phát.

Yêu cầu focus bao gồm tham số durationHint thông báo cho hệ thống thời lượng dự kiến: AUDIOFOCUS_GAIN (phát dài — nhạc, podcast), AUDIOFOCUS_GAIN_TRANSIENT (ngắn hạn — âm thanh thông báo, điều hướng), AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK (ngắn hạn với quyền giảm âm lượng trình phát hiện tại).

Khi mất focus, ứng dụng nhận một trong ba mã: AUDIOFOCUS_LOSS (mất dài hạn — ứng dụng khác đã bắt đầu phát nhạc), AUDIOFOCUS_LOSS_TRANSIENT (mất tạm thời — cuộc gọi, thông báo), AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK (mất tạm thời với khả năng giảm âm lượng). Mỗi mã yêu cầu phản ứng riêng.

Chuỗi sự kiện Audio Focus

Người dùng đang nghe nhạc trong ứng dụng A. Một cuộc gọi đến — ứng dụng B (điện thoại) yêu cầu AUDIOFOCUS_GAIN_TRANSIENT. Hệ thống gửi AUDIOFOCUS_LOSS_TRANSIENT đến ứng dụng A. Trình phát tạm dừng. Sau khi cuộc gọi kết thúc, ứng dụng B giải phóng focus, hệ thống thông báo cho ứng dụng A qua AUDIOFOCUS_GAIN — trình phát tiếp tục phát. Toàn bộ chuỗi mất chưa đến 50 ms.

Loại và chế độ yêu cầu Audio Focus

Chọn durationHint chính xác là quyết định quan trọng khi triển khai Audio Focus. Chọn sai loại dẫn đến chồng chéo âm thanh, dừng trình phát không cần thiết hoặc gây khó chịu cho người dùng.

Loại yêu cầuKịch bảnPhản ứng của chủ sở hữu
AUDIOFOCUS_GAINBắt đầu nhạc, podcastAUDIOFOCUS_LOSS — trình phát nên dừng
AUDIOFOCUS_GAIN_TRANSIENTCuộc gọi, thông báo giọng nóiAUDIOFOCUS_LOSS_TRANSIENT — tạm dừng
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCKChỉ dẫn GPS, tín hiệu ngắnAUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK — giảm âm lượng
AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVETìm kiếm giọng nói, ghi âmAUDIOFOCUS_LOSS — dừng hoàn toàn

Đặc điểm của AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK

Duck là việc giảm tạm thời âm lượng của trình phát chính xuống 20–30% trong khi âm thanh thứ cấp phát. Android cung cấp API để duck thủ công qua AudioManager.adjustSuggestedStreamVolume, nhưng hầu hết trình phát triển khai duck bằng phương tiện riêng. Theo Tài liệu Android (2026), xử lý duck không nên kéo dài quá 3 giây, sau đó âm lượng được khôi phục.

Triển khai Audio Focus trong mã

Để triển khai Audio Focus chính xác, bạn cần thực hiện ba bước tuần tự: tạo yêu cầu, yêu cầu focus trước khi phát và xử lý sự kiện trong callback. Sử dụng AudioFocusRequestCompat từ AndroidX media đảm bảo tương thích với tất cả phiên bản Android.

Tạo và thực thi yêu cầu Audio Focus

kotlin
val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager

val focusRequest = AudioFocusRequestCompat.Builder()
    .setFocusGain(AudioManagerCompat.AUDIOFOCUS_GAIN)
    .setOnAudioFocusChangeListener(focusChangeListener)
    .build()

val result = AudioManagerCompat.requestAudioFocus(audioManager, focusRequest)

if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
    startPlayback()
}

Yêu cầu focus phải được thực hiện trước khi bắt đầu phát mỗi lần người dùng nhấn Play. Nếu kết quả là AUDIOFOCUS_REQUEST_GRANTED — bắt đầu phát. Nếu DENIED — hiển thị thông báo cho người dùng hoặc hoãn phát cho đến khi đạt được focus.

Callback thay đổi focus

kotlin
private val focusChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange ->
    when (focusChange) {
        AudioManager.AUDIOFOCUS_GAIN -> {
            restoreVolume()
            if (wasPlayingBeforeLoss) resumePlayback()
        }
        AudioManager.AUDIOFOCUS_LOSS -> {
            pausePlayback()
            wasPlayingBeforeLoss = false
        }
        AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
            pausePlayback()
            wasPlayingBeforeLoss = true
        }
        AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
            duckVolume()
        }
    }
}

Trong callback, điều quan trọng là phân biệt AUDIOFOCUS_LOSSAUDIOFOCUS_LOSS_TRANSIENT. Trong trường hợp đầu, trình phát KHÔNG nên tự động tiếp tục — người dùng đã chủ động bắt đầu âm thanh khác. Trong trường hợp thứ hai, nó có thể tự động tiếp tục khi nhận AUDIOFOCUS_GAIN. Cờ wasPlayingBeforeLoss giúp ghi nhớ liệu có cần khôi phục phát hay không.

Giải phóng Audio Focus

kotlin
private fun abandonAudioFocus() {
    AudioManagerCompat.abandonAudioFocusRequest(audioManager, focusRequest)
}

Gọi abandonAudioFocusRequest thông báo cho hệ thống rằng ứng dụng không còn cần focus nữa. Điều quan trọng là gọi nó khi tạm dừng và dừng trình phát. Nếu focus không được giải phóng, ứng dụng khác yêu cầu AUDIOFOCUS_GAIN sẽ không nhận được LOSS và âm thanh sẽ chồng chéo.

Xử lý mất audio focus

Xử lý chính xác việc mất focus là yêu cầu quan trọng để vượt qua đánh giá của Google Play. Xử lý sai dẫn đến đánh giá tiêu cực: người dùng phàn nàn rằng nhạc tiếp tục phát trong cuộc gọi hoặc trên nền điều hướng.

Khi nhận AUDIOFOCUS_LOSS, trình phát nên dừng và không tiếp tục cho đến khi người dùng nhấn Play rõ ràng. Khi AUDIOFOCUS_LOSS_TRANSIENT (cuộc gọi, thông báo), trình phát tạm dừng và tự động tiếp tục khi focus được khôi phục. Khi AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK, trình phát tạm thời giảm âm lượng xuống 20–30% trong khi âm thanh bên ngoài phát.

Theo Hướng dẫn nhà phát triển Android (2026), duck nên được triển khai bằng cách nhân mức âm lượng AudioTrack hiện tại với hệ số 0.2–0.3. Không sử dụng AudioManager.setStreamVolume — điều này thay đổi âm lượng hệ thống và ảnh hưởng đến ứng dụng khác. Duck chỉ được thực hiện ở phía trình phát của riêng mình.

Xử lý cuộc gọi và điều hướng

Khi có cuộc gọi đến, hệ thống tự động yêu cầu AUDIOFOCUS_GAIN_TRANSIENT qua ứng dụng Điện thoại. Trình phát nhận AUDIOFOCUS_LOSS_TRANSIENT và tạm dừng. Sau khi cuộc gọi kết thúc hoặc nếu người dùng từ chối cuộc gọi, focus quay lại — trình phát tự động tiếp tục phát nếu là trình phát nhạc.

Đối với ứng dụng điều hướng (Google Maps), AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK được sử dụng trong hướng dẫn bằng giọng nói. Trình phát bị giảm âm lượng trong 2–3 giây, sau đó âm lượng được khôi phục. Nếu người dùng đang nghe podcast thay vì nhạc, tốt hơn nên tạm dừng thay vì duck — mỗi giây đều quan trọng trong podcast.

Kịch bản sử dụng điển hình

Trong thực tế, các nhà phát triển gặp một số kịch bản tiêu chuẩn nơi Audio Focus hoạt động khác nhau. Hãy xem xét các trường hợp điển hình và phản ứng chính xác.

  • Nhạc + cuộc gọi — trình phát tạm dừng (AUDIOFOCUS_LOSS_TRANSIENT). Sau cuộc gọi, tự động tiếp tục nếu người dùng không tương tác với trình phát.
  • Nhạc + điều hướng — trình phát bị giảm âm lượng trong hướng dẫn giọng nói (DUCK). Âm lượng được khôi phục sau khi câu nói kết thúc.
  • Người dùng đã khởi chạy ứng dụng khác — trình phát nhận AUDIOFOCUS_LOSS và dừng. Chỉ tiếp tục bằng nút Play.
  • Video + nhạc nền — trình phát video yêu cầu AUDIOFOCUS_GAIN. Trình phát nhạc nhận LOSS và dừng.
  • Tìm kiếm giọng nói (Google Assistant) — ứng dụng nhận AUDIOFOCUS_LOSS_TRANSIENT, tạm dừng và tự động tiếp tục sau phản hồi của trợ lý.

Tự động tiếp tục sau khi mất focus

Điều quan trọng là triển khai cờ ghi nhớ liệu nhạc có đang phát trước khi mất focus hay không. Nếu người dùng tự tạm dừng và sau đó có cuộc gọi đến — không tiếp tục. Cờ được đặt lại khi người dùng tạm dừng rõ ràng và được thiết lập khi bắt đầu phát.

Theo nghiên cứu UX của Google (2024), tự động tiếp tục sau cuộc gọi tăng sự hài lòng của người dùng lên 22%. Nhưng nếu trình phát tiếp tục sau khi người dùng đã bắt đầu xem video — điều này gây khó chịu. Cờ wasPlayingBeforeLoss ngăn chặn việc tiếp tục sai.

Câu hỏi thường gặp

Audio Focus có bắt buộc cho tất cả ứng dụng có âm thanh không?

Có, bắt đầu từ Android 12, Google Play khuyến nghị triển khai Audio Focus cho tất cả ứng dụng phát âm thanh. Ứng dụng danh mục Nhạc & Âm thanh phải triển khai nó để xuất bản. Bỏ qua có thể dẫn đến từ chối cập nhật.

Làm thế nào để kiểm tra Audio Focus hoạt động chính xác?

Khởi động trình phát của bạn, sau đó mở ứng dụng âm thanh khác (ví dụ: YouTube Music). Trình phát của bạn nên tạm dừng. Sau đó đóng YouTube Music — trình phát nên tự động tiếp tục. Để kiểm tra duck, sử dụng Google Maps với hướng dẫn bằng giọng nói.

AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK thực tế là gì?

Hệ thống nói: “Ứng dụng khác cần phát một âm thanh ngắn trong thời gian ngắn — giảm âm lượng trình phát của bạn.” Điều này tối ưu cho hướng dẫn giọng nói và thông báo ngắn. Âm lượng được khôi phục sau khi âm thanh bên ngoài kết thúc mà không cần can thiệp thủ công.

Tôi có thể từ chối yêu cầu mất Audio Focus không?

Chính thức là có — hệ thống không ép buộc. Nhưng trên thực tế, điều này có nghĩa là chồng chéo âm thanh. Người dùng sẽ nghe nhạc và cuộc gọi cùng lúc, dẫn đến trải nghiệm tiêu cực. Google khuyến nghị luôn xử lý AUDIOFOCUS_LOSS bằng cách dừng trình phát.

Audio Focus có hoạt động trên nền tảng khác ngoài Android không?

Trên iOS, vai trò tương đương được thực hiện bởi Audio Session, được quản lý qua AVAudioSession. Cơ chế tương tự: danh mục và tùy chọn xác định hành vi khi chồng chéo âm thanh. Tuy nhiên, API và quy tắc khác nhau đáng kể — mỗi framework được triển khai theo cách riêng của nó.

Tóm tắt

  • Audio Focus là trọng tài âm thanh hệ thống trong Android, ngăn chặn chồng chéo âm thanh giữa các ứng dụng khác nhau.
  • Yêu cầu focus được thực hiện qua AudioFocusRequestCompat với durationHint: GAIN, TRANSIENT hoặc TRANSIENT_MAY_DUCK.
  • Callback OnAudioFocusChangeListener xử lý bốn sự kiện: GAIN, LOSS, LOSS_TRANSIENT và LOSS_TRANSIENT_CAN_DUCK.
  • Khi AUDIOFOCUS_LOSS trình phát dừng; khi TRANSIENT — tạm dừng với tự động tiếp tục; khi DUCK — giảm âm lượng.
  • Điều quan trọng là theo dõi cờ wasPlayingBeforeLoss để tránh tiếp tục sau khi người dùng tạm dừng rõ ràng.
  • Giải phóng focus qua abandonAudioFocusRequest là bắt buộc khi tạm dừng và dừng trình phát.
  • Trên iOS, tương đương của Audio Focus là Audio Session (AVAudioSession) với danh mục và chế độ riêng.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm