Xử lý các thay đổi trong đầu ra âm thanh

Người dùng mong muốn có thể kiểm soát âm lượng của ứng dụng âm thanh. Hành vi tiêu chuẩn bao gồm khả năng sử dụng các nút điều khiển âm lượng (nút hoặc núm trên thiết bị hoặc thanh trượt trong giao diện người dùng) và tránh đột ngột phát to khi một thiết bị ngoại vi như tai nghe bị ngắt kết nối khi đang sử dụng.

Sử dụng các nút điều chỉnh âm lượng

Khi người dùng nhấn phím âm lượng trong một trò chơi hoặc ứng dụng âm nhạc, âm lượng sẽ thay đổi, ngay cả khi trình phát bị tạm dừng giữa các bài hát hoặc không có nhạc cho vị trí trò chơi hiện tại.

Android sử dụng các luồng âm thanh riêng biệt để phát nhạc, chuông báo, thông báo, trình tạo nhạc chuông cuộc gọi đến, âm thanh hệ thống, âm lượng trong cuộc gọi và âm DTMF. Điều này cho phép người dùng kiểm soát âm lượng của mỗi luồng một cách độc lập.

Theo mặc định, việc nhấn vào nút điều khiển âm lượng sẽ sửa đổi âm lượng của luồng âm thanh đang hoạt động. Nếu ứng dụng của bạn hiện không phát nội dung nào, hãy nhấn phím âm lượng để điều chỉnh âm lượng nhạc (hoặc âm lượng của trình tạo nhạc chuông trước Android 9).

Trừ phi ứng dụng của bạn là đồng hồ báo thức, bạn nên phát âm thanh bằng cách sử dụng AudioAttributes.USAGE_MEDIA.

Để đảm bảo các nút điều khiển âm lượng điều chỉnh đúng luồng, bạn nên gọi setVolumeControlStream() truyền vào loại luồng phù hợp với các thuộc tính mà bạn có thể truy xuất từ AudioAttributes.getVolumeControlStream.

Kotlin

setVolumeControlStream(AudioManager.STREAM_MUSIC)

Java

setVolumeControlStream(AudioManager.STREAM_MUSIC);

Thực hiện lệnh gọi này trong vòng đời của ứng dụng, thường là từ phương thức onResume() của hoạt động hoặc mảnh kiểm soát nội dung nghe nhìn. Đoạn mã này sẽ kết nối các nút điều khiển âm lượng với STREAM_MUSIC bất cứ khi nào hoạt động hoặc mảnh mục tiêu hiển thị.

Điều chỉnh âm lượng luồng theo phương thức lập trình

Trong một số ít trường hợp, bạn có thể đặt âm lượng của luồng âm thanh theo phương thức lập trình. Ví dụ: khi ứng dụng thay thế một giao diện người dùng hiện có. Bạn không nên thực hiện cách này vì AudioManager của Android sẽ kết hợp tất cả luồng âm thanh cùng loại với nhau. Các phương thức này sẽ thay đổi âm lượng của mọi ứng dụng sử dụng luồng. Tránh sử dụng chúng:

Làm việc với thiết bị có âm lượng cố định

Một số thiết bị (chẳng hạn như Chromebook) có nút điều khiển âm lượng nhưng không cho phép ứng dụng dùng phương thức AudioManager mô tả ở trên để thay đổi cấp độ của luồng âm thanh. Các thiết bị này được gọi là thiết bị có âm lượng cố định. Bạn có thể khám phá xem ứng dụng của mình có đang chạy trên thiết bị có dung lượng cố định hay không bằng cách gọi isVolumeFixed().

Ứng dụng âm thanh phải cung cấp khả năng cân bằng âm lượng đầu ra với các ứng dụng khác có thể đang phát trên cùng một luồng. Trên các thiết bị có âm lượng cố định, ứng dụng phải kết nối các nút điều khiển âm lượng riêng với phương thức setVolume() thích hợp trong bảng dưới đây:

Người chơi Phương thức
Bản âm thanh AudioTrack.setVolume()
MediaPlayer MediaPlayer.setVolume()
ExoPlayer Dùng SimpleExoPlayer.setVolume() để đặt âm lượng của AudioTrack cơ bản.

Đừng ồn ào

Người dùng có nhiều lựa chọn để thưởng thức âm thanh trên thiết bị Android. Hầu hết thiết bị đều có loa tích hợp, giắc cắm tai nghe cho tai nghe có dây, nhiều thiết bị khác cũng có kết nối Bluetooth và hỗ trợ âm thanh A2DP.

Khi tai nghe rút phích cắm hoặc thiết bị Bluetooth bị ngắt kết nối, luồng âm thanh sẽ tự động chuyển hướng đến loa tích hợp. Nếu bạn nghe nhạc ở mức âm lượng cao, điều này có thể khiến bạn ngạc nhiên.

Người dùng thường muốn các ứng dụng có trình phát nhạc có bộ điều khiển chế độ phát trên màn hình sẽ tạm dừng phát trong trường hợp này. Các ứng dụng khác (như trò chơi không có các chế độ điều khiển) sẽ tiếp tục chơi. Người dùng có thể điều chỉnh âm lượng bằng các tính năng điều khiển phần cứng của thiết bị.

Khi đầu ra âm thanh chuyển về loa tích hợp, hệ thống sẽ truyền đi ý định ACTION_AUDIO_BECOMING_NOISY. Bạn nên tạo một BroadcastReceiver để theo dõi ý định này bất cứ khi nào bạn phát âm thanh. Bộ nhận của bạn sẽ có dạng như sau:

Kotlin

private class BecomingNoisyReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY) {
            // Pause the playback
        }
    }
}

Java

private class BecomingNoisyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
      if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
          // Pause the playback
      }
    }
}

Đăng ký bộ thu khi bạn bắt đầu phát và huỷ đăng ký khi bạn dừng phát. Nếu bạn thiết kế ứng dụng như chúng tôi mô tả trong hướng dẫn này, thì các lệnh gọi này sẽ xuất hiện trong lệnh gọi lại phiên phát nội dung nghe nhìn onPlay()onStop().

Kotlin

private val intentFilter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
private val myNoisyAudioStreamReceiver = BecomingNoisyReceiver()

private val callback = object : MediaSessionCompat.Callback() {

    override fun onPlay() {
        registerReceiver(myNoisyAudioStreamReceiver, intentFilter)
    }

    override fun onStop() {
        unregisterReceiver(myNoisyAudioStreamReceiver)
    }
}

Java

private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private BecomingNoisyReceiver myNoisyAudioStreamReceiver = new BecomingNoisyReceiver();

MediaSessionCompat.Callback callback = new
MediaSessionCompat.Callback() {
  @Override
  public void onPlay() {
    registerReceiver(myNoisyAudioStreamReceiver, intentFilter);
  }

  @Override
  public void onStop() {
    unregisterReceiver(myNoisyAudioStreamReceiver);
  }
}