التعامل مع التغييرات في إخراج الصوت

يتوقّع المستخدمون أن يتمكّنوا من التحكّم في مستوى صوت تطبيق الصوت. ويشمل السلوك العادي إمكانية استخدام عناصر التحكّم في مستوى الصوت (إما الأزرار أو المقابض على الجهاز أو أشرطة التمرير في واجهة المستخدم)، وتجنُّب التشغيل بصوت عالٍ فجأة في حال انقطاع اتصال أحد الأجهزة الطرفية، مثل سماعات الرأس، أثناء الاستخدام.

استخدام عناصر التحكّم في مستوى الصوت

عندما يضغط المستخدم على مفتاح الصوت في لعبة أو تطبيق موسيقى، يجب أن يتغيّر مستوى الصوت، حتى إذا تم إيقاف المشغّل مؤقتًا بين الأغاني أو لم تكن هناك موسيقى في الموقع الجغرافي الحالي للّعبة.

يستخدم نظام التشغيل Android مصادر صوت منفصلة لتشغيل الموسيقى ونغمات المنبّهات والرسائل الإشعارية ونغمة المكالمات الواردة وأصوات النظام ومستوى الصوت أثناء المكالمات ونغمات DTMF. يتيح ذلك للمستخدمين التحكّم في مستوى صوت كل بث بشكل مستقل.

يؤدي الضغط على زر التحكّم في مستوى الصوت تلقائيًا إلى تعديل مستوى الصوت في البث الصوتي attivo. إذا لم يكن تطبيقك يشغّل أي محتوى حاليًا، يؤدي الضغط على مفاتيح التحكّم بمستوى الصوت إلى ضبط مستوى صوت الموسيقى (أو مستوى صوت الرنين قبل الإصدار 9 من نظام التشغيل Android).

يجب تشغيل الصوت باستخدام الإذن AudioAttributes.USAGE_MEDIA ما لم يكن تطبيقك عبارة عن منبّه.

لضمان ضبط عناصر التحكّم في مستوى الصوت للبث الصحيح، يجب استدعاء setVolumeControlStream() مع إدخال نوع البث الذي يتطابق مع السمات التي يمكنك استرجاعها من AudioAttributes.getVolumeControlStream.

Kotlin

setVolumeControlStream(AudioManager.STREAM_MUSIC)

Java

setVolumeControlStream(AudioManager.STREAM_MUSIC);

يمكنك إجراء هذا الطلب في دورة حياة تطبيقك، عادةً من onResume() طريقة النشاط أو المقتطف الذي يتحكّم في الوسائط. يؤدي ذلك إلى ربط عناصر التحكّم في مستوى الصوت برمز STREAM_MUSIC عندما يكون النشاط أو المقتطف المستهدفان مرئيَين.

التحكّم في مستوى صوت البث آليًا

في حالات نادرة، يمكنك ضبط مستوى صوت بث صوتي آليًا. على سبيل المثال، عندما يستبدل تطبيقك واجهة مستخدم حالية. لا يُنصح بذلك لأنّه يمزج نظام التشغيل Android AudioManager جميع مصادر الصوت من النوع نفسه معًا. وتؤدي هذه الطرق إلى تغيير مستوى الصوت في كل تطبيق يستخدم البث. تجنَّب استخدام العناصر التالية:

العمل مع الأجهزة التي تتضمّن مستوى صوت ثابتًا

تتضمّن بعض الأجهزة (مثل أجهزة Chromebook وسيارات Android Automotive OS) عناصر تحكّم في مستوى الصوت، ولكنها لا تسمح للتطبيقات باستخدام AudioManager الطرق الموضّحة سابقًا لتغيير مستوى بث الصوت. وتُعرف هذه الأجهزة باسم أجهزة الصوت الثابت. يمكنك معرفة ما إذا كان تطبيقك يعمل على جهاز بمستوى صوت ثابت من خلال الاتصال بالرقم isVolumeFixed().

يجب أن يتيح تطبيق الصوت توازن مستوى الصوت الصادر عنه مع التطبيقات الأخرى التي قد يتم تشغيلها في البث نفسه. على الأجهزة التي تتضمّن مستوى صوت ثابتًا، يجب أن يربط التطبيق عناصر التحكّم في الصوت الخاصة به بالطريقة المناسبة setVolume():

اللاعب الطريقة
AudioTrack AudioTrack.setVolume()
MediaPlayer MediaPlayer.setVolume()
ExoPlayer استخدِم SimpleExoPlayer.setVolume() لضبط مستوى صوت AudioTrack الأساسي.
الويب اضبط السمة volume للعنصر HTMLMediaElement.

عدم إحداث ضوضاء

يتوفّر للمستخدمين عدد من البدائل للاستماع إلى الصوت من أجهزة Android. تحتوي معظم الأجهزة على مكبّر صوت مدمج وفتحات سماعات رأس لسمّاعات الرأس السلكية، كما تتضمّن العديد منها إمكانية الاتصال عبر البلوتوث ودعم تنسيق A2DP للصوت.

عند فصل سماعة الرأس أو قطع اتصال جهاز بلوتوث، تتم إعادة توجيه بث الصوت تلقائيًا إلى مكبّر الصوت المدمج. إذا كنت تستمع إلى الموسيقى بصوتٍ عالٍ، قد يفاجئك هذا الضجيج.

يتوقع المستخدمون عادةً أن تتضمّن التطبيقات التي تتضمّن مشغّل موسيقى مع عناصر تحكّم في التشغيل على الشاشة ميزة الإيقاف المؤقت للتشغيل في هذه الحالة. من المفترض أن تستمر تشغيل التطبيقات الأخرى، مثل الألعاب التي لا تشمل عناصر تحكّم. يمكن للمستخدم ضبط مستوى الصوت باستخدام عناصر التحكّم في الجهاز.

عندما يعود إخراج الصوت إلى مكبّر الصوت المدمج، يُرسِل النظام ACTION_AUDIO_BECOMING_NOISY intent. يجب إنشاء BroadcastReceiver يستمع إلى هذا الإجراء عند تشغيل الصوت. من المفترض أن يظهر جهاز الاستقبال على النحو التالي:

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
      }
    }
}

سجِّل جهاز الاستقبال عند بدء التشغيل وألغِ تسجيله عند إيقافه. إذا صمّمت تطبيقك على النحو الموضّح في هذا الدليل، من المفترض أن تظهر هذه الطلبات في طلبات الاستدعاء لجلسة الوسائط 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);
  }
}