يمكن لتطبيقين أو أكثر من تطبيقات Android تشغيل الصوت على نفس مصدر الإخراج في الوقت نفسه، ويمزج النظام كل شيء معًا. في حين أن هذا من الناحية الفنية، فقد يؤدي ذلك إلى تفاقم حالة المستخدم بشكل كبير. لتجنب كل تطبيق موسيقى واحد يتم تشغيله في الوقت نفسه، يقدّم Android فكرة الصوت التركيز. يمكن لتطبيق واحد فقط الاحتفاظ بالتركيز على الصوت في كل مرة.
يجب أن يطلب التطبيق التركيز على الصوت عندما يحتاج إلى إصدار صوت. عندما يكون التركيز، فيمكنه تشغيل الصوت. ولكن بعد الحصول على تركيز صوتي، قد لا الاحتفاظ بها حتى تنتهي من اللعب. يمكن لتطبيق آخر أن يطلب التركيز، مما بشكل استباقي تعليق التركيز على الصوت. إذا حدث ذلك، من المفترض أن يتوقف تطبيقك مؤقتًا. تشغيل الصوت أو خفضه للسماح للمستخدمين بسماع مصدر الصوت الجديد بسهولة أكبر
قبل الإصدار Android 12 (المستوى 31 لواجهة برمجة التطبيقات)، لا يدير النظام تركيز الصوت. وبالتالي، بينما ننصح مطوّري التطبيقات بالالتزام بإرشادات التركيز الصوتي إذا استمرّ تشغيل أحد التطبيقات بصوت عالٍ حتى بعد فقدان ميزة التركيز الصوتي على أحد الأجهزة إذا كان الجهاز يعمل بالإصدار 11 من نظام التشغيل Android (المستوى 30 لواجهة برمجة التطبيقات) أو بإصدار أقدم، لا يمكن للنظام منعه. ومع ذلك، ينتج عن هذا السلوك في التطبيق تجربة سيئة للمستخدم وقد يؤدي غالبًا إلى من المستخدمين إلغاء تثبيت التطبيق الذي يعمل على نحو غير صحيح.
يجب أن يدير تطبيق الصوت التصميم جيدًا تركيز الصوت وفقًا لهذه القواعد إرشاداتنا:
يجب الاتصال بـ
requestAudioFocus()
مباشرةً قبل بدء التشغيل والتأكّد من أنّ يعود الاتصالAUDIOFOCUS_REQUEST_GRANTED
إجراء مكالمة معrequestAudioFocus()
في معاودة الاتصال "onPlay()
" لجلسة الوسائط.عندما يلتقط تطبيق آخر تركيزًا صوتيًا، أو يتوقف التشغيل أو توقفه مؤقتًا، أو يتوقف عن التشغيل (أي خفض مستوى الصوت.
عند إيقاف التشغيل (على سبيل المثال، عندما لا يكون لدى التطبيق أي شيء لتشغيله) التخلي عن التركيز الصوتي. ليس على تطبيقك التخلّي عن ميزة "التركيز على الصوت" إذا كان المستخدم يوقف التشغيل مؤقتًا ولكنه قد يستأنف التشغيل لاحقًا.
استخدام
AudioAttributes
لوصف ونوع الصوت الذي يتم تشغيله في تطبيقك. على سبيل المثال، في التطبيقات التي تشغِّل الكلام، التحديدCONTENT_TYPE_SPEECH
يتم التعامل مع ميزة "التركيز الصوتي" بشكل مختلف حسب إصدار Android الذي قيد التشغيل:
- Android 12 (المستوى 31 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث
- يدير النظام ميزة التركيز الصوتي. يفرض النظام تشغيل الصوت من تلاشي التطبيق عندما يطلب تطبيق آخر التركيز على الصوت. النظام وكتم أيضًا تشغيل الصوت عند تلقّي مكالمة واردة.
- Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات) إلى Android 11 (المستوى 30 لواجهة برمجة التطبيقات)
- لا يدير النظام التركيز على الصوت، ولكنه يتضمّن بعض التغييرات التي تمت تم طرحه بدءًا من الإصدار Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات).
- الإصدار 7.1 من نظام التشغيل Android (المستوى 25 من واجهة برمجة التطبيقات) والإصدارات الأقدم
- لا يدير النظام ميزة "التركيز الصوتي"، وتدير التطبيقات ميزة "التركيز الصوتي" باستخدام
requestAudioFocus()
أوabandonAudioFocus()
ميزة "تركيز الصوت" في الإصدار 12 من نظام التشغيل Android والإصدارات الأحدث
يجب عدم تشغيل الصوت بعد أن يفقد أي تطبيقات وسائط أو ألعاب تستخدم ميزة "التركيز على الصوت". التركيز. في Android 12 (المستوى 31 لواجهة برمجة التطبيقات) والإصدارات الأحدث، يفرض النظام ذلك السلوك. عندما يطلب أحد التطبيقات التركيز على الصوت بينما يتم التركيز على تطبيق آخر قيد التشغيل، يفرض النظام التلاشي على التطبيق قيد التشغيل. إن إضافة كما أن التلاشي للخارج يوفر انتقالاً أكثر سلاسة عند الانتقال من تطبيق إلى آخر.
ويحدث سلوك التلاشي هذا عند استيفاء الشروط التالية:
يستوفي التطبيق الأول الذي يتم تشغيله حاليًا جميع المعايير التالية:
- يحتوي التطبيق إما على
AudioAttributes.USAGE_MEDIA
أو سمة الاستخدامAudioAttributes.USAGE_GAME
- طلب التطبيق بنجاح التركيز على الصوت مع
AudioManager.AUDIOFOCUS_GAIN
. - لا يشغِّل التطبيق صوتًا مع نوع المحتوى
AudioAttributes.CONTENT_TYPE_SPEECH
.
- يحتوي التطبيق إما على
يطلب تطبيق آخر التركيز على الصوت باستخدام "
AudioManager.AUDIOFOCUS_GAIN
".
عند استيفاء هذه الشروط، يتلاشى النظام الصوتي للتطبيق الأول. في جلسة المعمل، نهاية التلاشي، يرسل النظام إشعارًا إلى التطبيق الأول لفقدان التركيز. ويظل المشغّلون مكتومين الصوت إلى أن يطلب التطبيق التركيز على الصوت مرة أخرى.
السلوكيات الحالية للتركيز الصوتي
يجب أن تطّلع أيضًا على هذه الحالات الأخرى التي تتضمّن تبديلاً في الصوت. التركيز.
تجنب التداخل التلقائي
تجنب التداخل التلقائي (خفض مستوى الصوت مؤقتًا لتطبيق واحد بحيث يمكن سماع شيء آخر بوضوح) في Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات).
ولن تضطر إلى تنفيذ نمط التداخل مع النظام من خلال تطبيقك.
يحدث تجنُّب التداخل مع أصوات أخرى أيضًا عندما يلفت إشعار صوتي التركيز. من تطبيق تشغيل. تتم مزامنة بدء تشغيل الإشعارات. مع نهاية منحدر التحايل.
يحدث تجنب التداخل التلقائي عند استيفاء الشروط التالية:
يستوفي التطبيق الأول المشغَّل حاليًا جميع المعايير التالية:
- طلب التطبيق بنجاح التركيز على الصوت مع أي نوع من التركيز. اكتساب.
- لا يشغِّل التطبيق الصوت مع نوع المحتوى
AudioAttributes.CONTENT_TYPE_SPEECH
- لم يتم ضبط التطبيق
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)
يطلب تطبيق ثانٍ التركيز الصوتي مع
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
عند استيفاء هذه الشروط، يقلل نظام الصوت جميع المشغلات النشطة التطبيق الأول بينما يركز التطبيق الثاني. عند إغلاق التطبيق الثاني التركيز، فإنه يتخلص منها. لا يتم إشعار التطبيق الأول عندما يفقد التركيز، لذلك لا يلزم القيام بأي شيء.
يُرجى العلم أنّه لا يتم تطبيق تجنّب التداخل مع أصوات أخرى عندما يستمع المستخدم إلى الحركات. محتوى الكلام، لأن المستخدم قد يفوته بعض البرنامج. على سبيل المثال: لا يتم استبعاد الإرشاد الصوتي لاتجاهات القيادة.
كتم تشغيل الصوت الحالي للمكالمات الهاتفية الواردة
لا تعمل بعض التطبيقات بشكل صحيح وتستمر في تشغيل الصوت أثناء المكالمات الهاتفية. يجبر هذا الموقف المستخدم على العثور على التطبيق المسيء وكتم صوته أو إنهائه في من أجل سماع نداءه. لمنع ذلك، يمكن للنظام كتم الصوت من أجهزة التطبيقات أثناء تلقي مكالمة واردة. يستدعي النظام هذه الميزة عند عند تلقّي مكالمة هاتفية واردة واستيفاء أحد التطبيقات الشروط التالية:
- يحتوي التطبيق على
AudioAttributes.USAGE_MEDIA
أو سمة الاستخدامAudioAttributes.USAGE_GAME
- طلب التطبيق بنجاح أي تركيز صوتي (أي زيادة التركيز) ويجري التشغيل. الصوت.
في حال استمرار تشغيل أحد التطبيقات أثناء المكالمة، سيتم كتم صوته حتى تنتهي المكالمة. ومع ذلك، إذا بدأ تشغيل أحد التطبيقات أثناء المكالمة، فلن يتم إيقاف مكتوم الصوت على افتراض أن المستخدم بدأ التشغيل عن قصد.
ميزة "تركيز الصوت" على إصدارات Android 8.0 إلى Android 11
بدءًا من Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات)، عند استدعاء
requestAudioFocus()
يجب توفير مَعلمة AudioFocusRequest
. AudioFocusRequest
يحتوي على معلومات عن سياق الصوت وإمكانات تطبيقك. تشير رسالة الأشكال البيانية
يستخدم هذا النظام هذه المعلومات لإدارة التقاط وفقدان التركيز الصوتي
تلقائيًا. لتحرير التركيز الصوتي، يمكنك استدعاء الطريقة.
abandonAudioFocusRequest()
والذي يأخذ أيضًا AudioFocusRequest
كوسيطة. استخدام القيم نفسها
يحدث AudioFocusRequest
عند طلب التركيز وإلغاء التركيز.
لإنشاء AudioFocusRequest
، استخدِم
AudioFocusRequest.Builder
نظرًا لأن طلب التركيز يجب
نوع الطلب دائمًا، يتم تضمين النوع في الدالة الإنشائية
للمنشئ. استخدم طرق الإنشاء لتعيين الحقول الأخرى
طلبك.
يجب ملء الحقل FocusGain
. فإن جميع الحقول الأخرى اختيارية.
الطريقة | ملاحظات |
---|---|
setFocusGain()
|
هذا الحقل مطلوب في كل طلب. إنها تأخذ نفس القيم مثل
durationHint المستخدم في الاتصال الذي جرى قبل نظام Android 8.0 للاتصال بـ requestAudioFocus() :
AUDIOFOCUS_GAIN ، AUDIOFOCUS_GAIN_TRANSIENT ،
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK أو AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
|
setAudioAttributes()
|
يصف AudioAttributes حالة الاستخدام لتطبيقك. تشير رسالة الأشكال البيانية
يفحصها النظام عندما يلتقط التطبيق تركيزه ويفقد تركيزه. السمات
أن تحل محل مفهوم نوع البث في Android 8.0 (المستوى 26 لواجهة برمجة التطبيقات) والإصدارات الأحدث،
سيتم إيقاف أنواع البث لأي عملية غير عناصر التحكم في مستوى الصوت. استخدام
السمات نفسها في طلب التركيز الذي تستخدمه في مشغِّل الصوت (كما
كما هو موضح في المثال الذي يلي هذا الجدول).
استخدِم
إذا لم يتم تحديده، سيتم ضبط |
setWillPauseWhenDucked()
|
عندما يطلب تطبيق آخر التركيز باستخدام
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ، لا يحتفظ التطبيق محل التركيز
تتلقى عادةً
onAudioFocusChange()
لأن النظام يمكنه إجراء
المحتوى بمفرده. عندما تريد إيقاف التشغيل مؤقتًا بدلاً من
من تقليل الصوت، يُرجى الاتصال بـ setWillPauseWhenDucked(true) وإنشاء
OnAudioFocusChangeListener ، كما هو موضح في قسم تلقائي
|
setAcceptsDelayedFocusGain()
|
قد يتعذّر طلب التركيز الصوتي عندما يكون التركيز مقفلاً بواسطة تطبيق آخر.
تتيح هذه الطريقة تفعيل زيادة التركيز المتأخرة: وهي القدرة
للتركيز بشكل غير متزامن عند توفُّره.
لاحظ أن زيادة التركيز المتأخر لا تعمل إلا إذا حددت أيضًا
|
setOnAudioFocusChangeListener()
|
لا يكون OnAudioFocusChangeListener مطلوبًا إلا إذا حددت أيضًا.
willPauseWhenDucked(true) أو setAcceptsDelayedFocusGain(true) في الطلب.
هناك طريقتان لإعداد المستمع: الطريقة الأولى مع
وسيطة المعالج. المعالِج هو سلسلة المحادثات التي يعمل فيها المستمع. إذا كنت
عدم تحديد معالج، فإن المعالج المرتبط
يتم استخدام |
يوضح المثال التالي كيفية استخدام AudioFocusRequest.Builder
لإنشاء
AudioFocusRequest
وطلب التركيز الصوتي والتخلي عنه:
Kotlin
// initializing variables for audio focus and playback management audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run { setAudioAttributes(AudioAttributes.Builder().run { setUsage(AudioAttributes.USAGE_GAME) setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) build() }) setAcceptsDelayedFocusGain(true) setOnAudioFocusChangeListener(afChangeListener, handler) build() } val focusLock = Any() var playbackDelayed = false var playbackNowAuthorized = false // requesting audio focus and processing the response val res = audioManager.requestAudioFocus(focusRequest) synchronized(focusLock) { playbackNowAuthorized = when (res) { AudioManager.AUDIOFOCUS_REQUEST_FAILED -> false AudioManager.AUDIOFOCUS_REQUEST_GRANTED -> { playbackNow() true } AudioManager.AUDIOFOCUS_REQUEST_DELAYED -> { playbackDelayed = true false } else -> false } } // implementing OnAudioFocusChangeListener to react to focus changes override fun onAudioFocusChange(focusChange: Int) { when (focusChange) { AudioManager.AUDIOFOCUS_GAIN -> if (playbackDelayed || resumeOnFocusGain) { synchronized(focusLock) { playbackDelayed = false resumeOnFocusGain = false } playbackNow() } AudioManager.AUDIOFOCUS_LOSS -> { synchronized(focusLock) { resumeOnFocusGain = false playbackDelayed = false } pausePlayback() } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> { synchronized(focusLock) { // only resume if playback is being interrupted resumeOnFocusGain = isPlaying() playbackDelayed = false } pausePlayback() } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> { // ... pausing or ducking depends on your app } } }
Java
// initializing variables for audio focus and playback management audioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE); playbackAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_GAME) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build(); focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) .setAudioAttributes(playbackAttributes) .setAcceptsDelayedFocusGain(true) .setOnAudioFocusChangeListener(afChangeListener, handler) .build(); final Object focusLock = new Object(); boolean playbackDelayed = false; boolean playbackNowAuthorized = false; // requesting audio focus and processing the response int res = audioManager.requestAudioFocus(focusRequest); synchronized(focusLock) { if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { playbackNowAuthorized = false; } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { playbackNowAuthorized = true; playbackNow(); } else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) { playbackDelayed = true; playbackNowAuthorized = false; } } // implementing OnAudioFocusChangeListener to react to focus changes @Override public void onAudioFocusChange(int focusChange) { switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: if (playbackDelayed || resumeOnFocusGain) { synchronized(focusLock) { playbackDelayed = false; resumeOnFocusGain = false; } playbackNow(); } break; case AudioManager.AUDIOFOCUS_LOSS: synchronized(focusLock) { resumeOnFocusGain = false; playbackDelayed = false; } pausePlayback(); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: synchronized(focusLock) { // only resume if playback is being interrupted resumeOnFocusGain = isPlaying(); playbackDelayed = false; } pausePlayback(); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // ... pausing or ducking depends on your app break; } } }
تجنب التداخل التلقائي
في Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات)، عندما يطلب تطبيق آخر التركيز مع
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
يمكن للنظام خفض مستوى الصوت واستعادة مستوى الصوت.
بدون استدعاء ميزة معاودة الاتصال onAudioFocusChange()
الخاصة بالتطبيق.
إنّ التشويش التلقائي يُعدّ سلوكًا مقبولاً في تشغيل الموسيقى والفيديو إلا أنه لا يكون مفيدًا عند تشغيل المحتوى المنطوق، كما هو الحال في تطبيق كتاب مسموع. في هذه الحالة، يجب أن يتوقف التطبيق مؤقتًا بدلاً من ذلك.
إذا أردت أن يتوقف تطبيقك مؤقتًا عندما يُطلب منك خفض مستوى صوته بدلاً من خفض مستوى الصوت، أنشئ OnAudioFocusChangeListener
باستخدام
طريقة استدعاء onAudioFocusChange()
تؤدي إلى تنفيذ سلوك الإيقاف المؤقت/الاستئناف المطلوب.
يمكنك الاتصال بالرقم setOnAudioFocusChangeListener()
لتسجيل المستمع ثم الاتصال.
setWillPauseWhenDucked(true)
لإخبار النظام باستخدام معاودة الاتصال بدلاً من تنفيذ تجنب التداخل تلقائيًا.
تأخّر زيادة التركيز
في بعض الأحيان، يتعذر على النظام منح طلب للتركيز الصوتي لأن التركيز
"مقفل" باستخدام تطبيق آخر، مثلاً أثناء مكالمة هاتفية. وفي هذه الحالة،
تُرجع requestAudioFocus()
مبلغ AUDIOFOCUS_REQUEST_FAILED
. عندما يحدث هذا،
يجب ألا يواصل التطبيق تشغيل الصوت لأنه لم يتم
التركيز.
الطريقة، setAcceptsDelayedFocusGain(true)
، التي تتيح لتطبيقك معالجة طلب التركيز
بشكل غير متزامن. عند ضبط هذه العلامة، يتم تقديم طلب عندما يكون التركيز مُقفَلاً
تعرض AUDIOFOCUS_REQUEST_DELAYED
. عندما يكون الشرط الذي أدى إلى قفل الصوت
لم يعد التركيز موجودًا، كما هو الحال عند انتهاء مكالمة هاتفية، أو عندما
يمنح طلب التركيز الذي لا يزال في انتظار المراجعة ويتصل بـ onAudioFocusChange()
لإعلام
التطبيق.
لمعالجة الزيادة المتأخرة في التركيز، يجب عليك إنشاء
OnAudioFocusChangeListener
باستخدام طريقة معاودة الاتصال onAudioFocusChange()
التي
وتنفيذ السلوك المطلوب وتسجيل المستمع من خلال استدعاء
setOnAudioFocusChangeListener()
ميزة "تركيز الصوت" في الإصدار 7.1 من نظام Android والإصدارات الأقدم
عند الاتصال
requestAudioFocus()
فيجب تحديد تلميح للمدة، والذي قد
أحد التطبيقات الأخرى التي يتم حاليًا التركيز عليها وتشغيلها:
- يمكنك طلب التركيز على الصوت الدائم (
AUDIOFOCUS_GAIN
) عند التخطيط لتشغيل الصوت. في المستقبل القريب (على سبيل المثال، عند تشغيل الموسيقى) وتتوقع المالك السابق لتركيز الصوت لإيقاف التشغيل. - طلب التركيز المؤقت (
AUDIOFOCUS_GAIN_TRANSIENT
) عندما تتوقّع اللعب الصوت لفترة قصيرة فقط وتتوقع أن يتوقّف المستخدم السابق عن العمل مؤقتًا اللعب. - طلب التركيز المؤقت من خلال التحايل
(
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
) للإشارة إلى أنّك تتوقّع تشغيل صوت لفترة قصيرة فقط وأنه من المقبول أن يواصل مالك التركيز السابق اللعب إذا كان "بط" (يخفض) إخراج الصوت. كلا مخرجات الصوت مختلطة مع البث الصوتي ويُعدّ تطبيق Ducking مناسبًا للتطبيقات التي تستخدم البث الصوتي بشكل متقطّع، مثلاً لتوجيهات القيادة الصوتية
تتطلّب الطريقة requestAudioFocus()
أيضًا السمة AudioManager.OnAudioFocusChangeListener
. يجب أن يكون هذا المستمع
تم إنشاؤها في النشاط أو الخدمة نفسها التي تملك جلسة الوسائط. أُنشأها جون هنتر، الذي كان متخصصًا
لتنفيذ استدعاء onAudioFocusChange()
الذي يتلقّاه تطبيقك عند
يكتسب تطبيق آخر التركيز الصوتي أو يتوقف عن التركيز.
يطلب المقتطف التالي التركيز الصوتي الدائم في البث
STREAM_MUSIC
ويسجِّل OnAudioFocusChangeListener
للتعامل معه.
التغييرات اللاحقة في التركيز الصوتي. (تتم مناقشة مستمع التغيير في
الاستجابة لتغيير التركيز الصوتي).
Kotlin
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager lateinit var afChangeListener AudioManager.OnAudioFocusChangeListener ... // Request audio focus for playback val result: Int = audioManager.requestAudioFocus( afChangeListener, // Use the music stream. AudioManager.STREAM_MUSIC, // Request permanent focus. AudioManager.AUDIOFOCUS_GAIN ) if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // Start playback }
Java
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); AudioManager.OnAudioFocusChangeListener afChangeListener; ... // Request audio focus for playback int result = audioManager.requestAudioFocus(afChangeListener, // Use the music stream. AudioManager.STREAM_MUSIC, // Request permanent focus. AudioManager.AUDIOFOCUS_GAIN); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // Start playback }
عند الانتهاء من التشغيل، اتصل
abandonAudioFocus()
Kotlin
audioManager.abandonAudioFocus(afChangeListener)
Java
// Abandon audio focus when playback complete audioManager.abandonAudioFocus(afChangeListener);
وسيؤدي ذلك إلى إعلام النظام بأنّك لم تعُد بحاجة إلى التركيز، كما يؤدّي إلى إلغاء تسجيل
المرتبطة OnAudioFocusChangeListener
. إذا طلبت التركيز العابر،
سيُرسل هذا إشعارًا إلى التطبيق الذي توقف مؤقتًا أو توقف عن العمل أو أنه قد يستمر في التشغيل أو
لاستعادة مستوى الصوت.
الاستجابة لتغيير التركيز الصوتي
عندما يكتسب أحد التطبيقات تركيزًا صوتيًا، يجب أن يكون قادرًا على تحريره عندما يكون هناك تطبيق آخر
يطلب التركيز على الصوت لنفسه. وعند حدوث ذلك، فإن تطبيقك
تلقي مكالمة مع
onAudioFocusChange()
في AudioFocusChangeListener
الذي حددته عند تشغيل التطبيق المسمى requestAudioFocus()
.
تشير مَعلمة focusChange
التي يتم تمريرها إلى onAudioFocusChange()
إلى النوع.
للتغيير الذي يحدث. يتجاوب
إلى تلميح المدة الذي يستخدمه التطبيق الذي يلفت الانتباه. يجب أن
الاستجابة بشكل مناسب.
- فقد التركيز بشكل عابر
-
إذا كان تغيير التركيز عابرًا (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
أوAUDIOFOCUS_LOSS_TRANSIENT
)، سيتراجع تطبيقك (إذا كنت لا تعتمد عند التحايل التلقائي) أو إيقاف التشغيل مؤقتًا تحافظ على نفس الحالة.يجب أن تستمر في مراقبة التغييرات أثناء فقدان التركيز مؤقتًا في الصوت. في وضع تركيز الصوت والاستعداد لاستئناف التشغيل العادي عند استعادة التركيز. عندما يتوقف تطبيق الحظر عن التركيز، ستتلقّى معاودة الاتصال. (
AUDIOFOCUS_GAIN
). عند هذه النقطة، يمكنك استعادة مستوى الصوت إلى المستوى العادي. أو إعادة بدء التشغيل - فقدان التركيز نهائيًا
-
إذا كان فقدان التركيز الصوتي نهائيًا (
AUDIOFOCUS_LOSS
)، يعني هذا أنّ تطبيقًا آخر يَتِمُّ الْآنْ تَشْغِيلُ الصَّوْتْ. من المفترض أن يتم إيقاف تشغيل تطبيقك مؤقتًا بشكل فوري، لأنه لن يتم تشغيله أبدًا. تلقّي معاودة الاتصال من "AUDIOFOCUS_GAIN
" ولإعادة تشغيل التشغيل، على المستخدم اتخاذ إجراء صريح، مثل الضغط على عنصر تحكم النقل في Play في إشعار أو واجهة مستخدم التطبيق.
يوضح مقتطف الرمز التالي كيفية تنفيذ
"OnAudioFocusChangeListener
" ومعاودة الاتصال "onAudioFocusChange()
" الخاصة به. لاحظ
استخدام Handler
لتأخير إيقاف معاودة الاتصال عند فقدان الصوت نهائيًا
التركيز.
Kotlin
private val handler = Handler() private val afChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange -> when (focusChange) { AudioManager.AUDIOFOCUS_LOSS -> { // Permanent loss of audio focus // Pause playback immediately mediaController.transportControls.pause() // Wait 30 seconds before stopping playback handler.postDelayed(delayedStopRunnable, TimeUnit.SECONDS.toMillis(30)) } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> { // Pause playback } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> { // Lower the volume, keep playing } AudioManager.AUDIOFOCUS_GAIN -> { // Your app has been granted audio focus again // Raise volume to normal, restart playback if necessary } } }
Java
private Handler handler = new Handler(); AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { // Permanent loss of audio focus // Pause playback immediately mediaController.getTransportControls().pause(); // Wait 30 seconds before stopping playback handler.postDelayed(delayedStopRunnable, TimeUnit.SECONDS.toMillis(30)); } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { // Pause playback } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { // Lower the volume, keep playing } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { // Your app has been granted audio focus again // Raise volume to normal, restart playback if necessary } } };
يستخدم المعالج علامة Runnable
على النحو التالي:
Kotlin
private var delayedStopRunnable = Runnable { mediaController.transportControls.stop() }
Java
private Runnable delayedStopRunnable = new Runnable() { @Override public void run() { getMediaController().getTransportControls().stop(); } };
وللتأكد من عدم بدء فترة التوقف المتأخر في حال أعاد المستخدم تشغيل التشغيل، اتصل
mHandler.removeCallbacks(mDelayedStopRunnable)
استجابةً لأي ولاية
التغييرات. على سبيل المثال، يمكنك طلب removeCallbacks()
من خلال الرقم onPlay()
الخاص بمعاودة الاتصال.
onSkipToNext()
، إلخ. كما يجب عليك أيضًا استدعاء هذه الطريقة في حساب
يمكنك معاودة الاتصال onDestroy()
عند إخلاء الموارد التي تستخدمها خدمتك.