ऑडियो फ़ोकस को मैनेज करें

दो या उससे ज़्यादा Android ऐप्लिकेशन, एक ही आउटपुट स्ट्रीम पर ऑडियो चला सकते हैं साथ ही, सिस्टम सभी चीज़ों को एक साथ मिला देता है. हालांकि, यह तो यह उपयोगकर्ता के लिए बहुत खराब हो सकता है. इतने समय में संगीत ऐप्लिकेशन एक साथ चल रहे हैं, तो Android ने पेश किया ऑडियो फ़ोकस. एक बार में सिर्फ़ एक ऐप्लिकेशन, ऑडियो फ़ोकस को होल्ड कर सकता है.

जब आपके ऐप्लिकेशन को ऑडियो आउटपुट की ज़रूरत हो, तो उसे ऑडियो फ़ोकस का अनुरोध करना चाहिए. जब इसमें फ़ोकस करते हैं, तो आवाज़ सुनाई देती है. हालांकि, ऑडियो फ़ोकस हासिल करने के बाद, हो सकता है कि आप उसे तब तक सेव करके रखा जा सकता है, जब तक आप उसे पूरा न देख लें. कोई दूसरा ऐप्लिकेशन, फ़ोकस करने का अनुरोध कर सकता है, जो ऑडियो फ़ोकस पर आपकी होल्ड को रोकता है. अगर ऐसा होता है, तो आपका ऐप्लिकेशन रुक जाना चाहिए आवाज़ को कम या ज़्यादा कर सकते हैं. इससे उपयोगकर्ता नए ऑडियो सोर्स को आसानी से सुन सकते हैं.

Android 12 के एपीआई लेवल 31 से पहले के वर्शन में, ऑडियो फ़ोकस को सिस्टम मैनेज नहीं करता. इसलिए, ऐप्लिकेशन डेवलपर को ऑडियो फ़ोकस से जुड़े दिशा-निर्देशों का पालन करने के लिए बढ़ावा दिया जाता है. अगर कोई ऐप्लिकेशन, डिवाइस पर ऑडियो फ़ोकस बंद होने के बाद भी तेज़ आवाज़ में चलता रहता है अगर Android 11 (एपीआई लेवल 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) से शुरू किया गया था.
Android 7.1 (एपीआई लेवल 25) और इससे पहले के वर्शन
सिस्टम, ऑडियो फ़ोकस को मैनेज नहीं करता. साथ ही, ऐप्लिकेशन इनका इस्तेमाल करके ऑडियो फ़ोकस को मैनेज करते हैं requestAudioFocus() और abandonAudioFocus().

Android 12 और उसके बाद वाले वर्शन में ऑडियो फ़ोकस की सुविधा

ऑडियो फ़ोकस का इस्तेमाल करने वाले मीडिया या गेम ऐप्लिकेशन के खोने के बाद, ऑडियो नहीं चलाया जाना चाहिए फ़ोकस. सिस्टम, Android 12 (एपीआई लेवल 31) और उसके बाद के वर्शन में इसे लागू करता है व्यवहार. जब कोई ऐप्लिकेशन ऑडियो फ़ोकस का अनुरोध करता है, जबकि दूसरे ऐप्लिकेशन में फ़ोकस और जब ऑडियो ठीक से चल रहा हो, तो सिस्टम उसे फ़ेड आउट कर देता है. इसके अलावा, एक ऐप्लिकेशन से दूसरे ऐप्लिकेशन पर जाते समय, फ़ेड-आउट की सुविधा आसान तरीके से ट्रांज़िशन करती है.

यह फ़ेड आउट व्यवहार तब होता है, जब ये शर्तें पूरी होती हैं:

  1. इस समय चल रहा पहला ऐप्लिकेशन, इन सभी शर्तों को पूरा करता है:

  2. एक दूसरे ऐप्लिकेशन ने AudioManager.AUDIOFOCUS_GAIN में ऑडियो फ़ोकस का अनुरोध किया है.

ये शर्तें पूरी होने पर, ऑडियो सिस्टम पहले ऐप्लिकेशन को फ़ेड आउट कर देता है. इस जब यह सुविधा चालू हो जाती है, तब सिस्टम पहले ऐप्लिकेशन को फ़ोकस घटने की सूचना देता है. ऐप्लिकेशन का प्लेयर तब तक म्यूट रहते हैं, जब तक ऐप्लिकेशन फिर से ऑडियो फ़ोकस का अनुरोध नहीं करता.

ऑडियो फ़ोकस की मौजूदा सुविधाएं

आपको ऐसे अन्य मामलों की जानकारी भी होनी चाहिए जिनमें ऑडियो स्विच करना शामिल है फ़ोकस.

अपने-आप डकिंग

अपने-आप डकिंग (किसी ऐप्लिकेशन का ऑडियो लेवल कम करने की सुविधा) अन्य को साफ़ तौर पर सुना जा सकता है) की सुविधा Android 8.0 (एपीआई लेवल 26) में दी गई थी.

सिस्टम की मदद से डकिंग को लागू करने पर, आपको डकिंग को लागू करने की आपका ऐप्लिकेशन.

अपने-आप डकिंग की सुविधा तब भी होती है, जब कोई ऑडियो सूचना फ़ोकस हासिल कर लेती है साइन इन करने के लिए प्रोत्साहित करें. सूचना प्लेबैक की शुरुआत को सिंक किया गया है डकिंग रैंप की समाप्ति के साथ.

ये शर्तें पूरी होने पर, अपने-आप डकिंग होती है:

  1. सबसे पहले, अभी चल रहा ऐप्लिकेशन, इन सभी शर्तों को पूरा करता है:

  2. दूसरे ऐप्लिकेशन में, ऑडियो फ़ोकस के साथ ऑडियो फ़ोकस करने का अनुरोध किया गया है 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 फ़ील्ड में वैल्यू डालना ज़रूरी है; बाकी सभी फ़ील्ड ज़रूरी नहीं हैं.

Methodनोट
setFocusGain() हर अनुरोध में यह फ़ील्ड ज़रूरी होता है. यह वैसी ही वैल्यू लेता है, जो requestAudioFocus() को किए गए Android 8.0 से पहले के कॉल में इस्तेमाल किया गया durationHint: AUDIOFOCUS_GAIN, AUDIOFOCUS_GAIN_TRANSIENT, AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK या AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE.
setAudioAttributes() AudioAttributes में, आपके ऐप्लिकेशन के इस्तेमाल के उदाहरण की जानकारी दी गई है. कॉन्टेंट बनाने जब कोई ऐप्लिकेशन, ऑडियो फ़ोकस की सुविधा को चालू या बंद कर देता है, तब वह इन सुझावों को देखता है. विशेषताएं स्ट्रीम टाइप की धारणा की जगह लागू होगी. Android 8.0 (एपीआई लेवल 26) और उसके बाद के वर्शन में, वॉल्यूम कंट्रोल के अलावा, किसी भी दूसरे कार्रवाई के लिए स्ट्रीम टाइप इस्तेमाल नहीं किए जा सकते. इस्तेमाल की जाने वाली चीज़ें फ़ोकस करने के अनुरोध में वे विशेषताएं डालें जिनका इस्तेमाल आप अपने ऑडियो प्लेयर में करते हैं (जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है).

वैल्यू को तय करने के लिए AudioAttributes.Builder का इस्तेमाल करें पहले एट्रिब्यूट है, फिर इस तरीके का इस्तेमाल करके एट्रिब्यूट को अनुरोध.

अगर इसके लिए वैल्यू तय नहीं की गई है, तो AudioAttributes की वैल्यू AudioAttributes.USAGE_MEDIA पर डिफ़ॉल्ट रूप से सेट हो जाती है.

setWillPauseWhenDucked() जब कोई दूसरा ऐप्लिकेशन, फ़ोकस करने का अनुरोध करता है AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, जिस ऐप्लिकेशन में फ़ोकस किया गया है वह आम तौर पर onAudioFocusChange() कॉलबैक करता है, क्योंकि सिस्टम यह कर सकता है: खुद ही डकिंग करना. जब आपको वीडियो चलाने की ज़रूरत हो वॉल्यूम कम करने के बाद, setWillPauseWhenDucked(true) पर कॉल करें और OnAudioFocusChangeListener, जैसा कि अपने-आप' में बताया गया है डकिंग.
setAcceptsDelayedFocusGain() किसी दूसरे ऐप्लिकेशन से फ़ोकस लॉक होने पर, हो सकता है कि ऑडियो फ़ोकस का अनुरोध पूरा न हो. इस तरीके से, देर से फ़ोकस गेन की सुविधा मिलती है: उपलब्ध होने पर, फ़ोकस को एसिंक्रोनस रूप से हासिल करने में मदद करता है.

ध्यान दें कि देरी से फ़ोकस गेन की सुविधा सिर्फ़ तब काम करती है, जब आपने AudioManager.OnAudioFocusChangeListener अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है ऑडियो अनुरोध में बदल सकते हैं, क्योंकि आपके ऐप्लिकेशन को कॉलबैक पा सकें, ताकि यह पता चल सके कि फ़ोकस का ऐक्सेस दिया गया है.

setOnAudioFocusChangeListener() OnAudioFocusChangeListener की ज़रूरत सिर्फ़ तब होती है, जब आपने यह भी बताया हो अनुरोध में willPauseWhenDucked(true) या setAcceptsDelayedFocusGain(true).

लिसनर को सेट करने के दो तरीके हैं: पहला हैंडलर आर्ग्युमेंट. हैंडलर वह थ्रेड होता है जिस पर लिसनर चलता है. अगर आपको किसी हैंडलर की वैल्यू तय न करें, Looper का इस्तेमाल किया गया है.

नीचे दिए गए उदाहरण में, 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() को कॉल करता है है.

देर से मिलने वाली फ़ोकस की समस्या को मैनेज करने के लिए, आपको onAudioFocusChange() कॉलबैक मैथड से OnAudioFocusChangeListener मनमुताबिक व्यवहार लागू करता है और लिसनर को कॉल करके रजिस्टर करता है setOnAudioFocusChangeListener().

Android 7.1 और इससे पहले के वर्शन में ऑडियो फ़ोकस

आपके कॉल करने पर requestAudioFocus() आपको एक अवधि संकेत ज़रूर बताना होगा, जो एक ऐसे ऐप्लिकेशन से सम्मानित किया जा सकेगा जो अभी फ़ोकस बनाए हुए है और खेल रहा है:

  • जब आपको ऑडियो चलाना हो, तब स्थायी ऑडियो फ़ोकस (AUDIOFOCUS_GAIN) का अनुरोध करें आने वाले समय में काफ़ी कुछ हासिल किया जा सकता है (उदाहरण के लिए, संगीत चलाते समय) और आपको उम्मीद है कि चलाना बंद करने के लिए ऑडियो फ़ोकस के पिछला होल्डर.
  • जब आपको गेम खेलना हो, तब कुछ देर के लिए फ़ोकस (AUDIOFOCUS_GAIN_TRANSIENT) करने का अनुरोध करें ऑडियो कम समय के लिए अपलोड किया जाता है और आपको लगता है कि पिछले वीडियो को चलाने वाले व्यक्ति को चल रहा है.
  • डकिंग की मदद से, कुछ समय के लिए फ़ोकस करना (AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) से पता चलता है कि आपको ऑडियो चलाना है का इस्तेमाल नहीं किया जा सकता. साथ ही, फ़ोकस के पुराने मालिक के लिए अगर यह "बतख़" है, तो खेला जा रहा है अपने ऑडियो आउटपुट को (कम करता है). दोनों ऑडियो आउटपुट मिले-जुले रूप में ऑडियो स्ट्रीम में शामिल कर सकते हैं. डकिंग टूल उन ऐप्लिकेशन के लिए खास तौर पर सही है जो बीच-बीच में आने वाली ऑडियो स्ट्रीम, जैसे कि ड्राइविंग के दिशा-निर्देश सुनाई देने वाले हों.

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() पर कॉल करने पर बताया था.

onAudioFocusChange() को पास किया गया focusChange पैरामीटर, प्रकार होने वाले बदलावों के बारे में बताया है. यह फ़ोकस पाने वाले ऐप्लिकेशन की अवधि के संकेत तक. आपके ऐप्लिकेशन को चाहिए सही जवाब दें.

कुछ समय के लिए फ़ोकस ठीक न होना
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है अगर फ़ोकस में बदलाव कुछ समय के लिए है (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) बदलाव. उदाहरण के लिए, अपने कॉलबैक के onPlay() में removeCallbacks() को कॉल करें, onSkipToNext(), वगैरह. आपको इस तरीके को अपनी सेवा के आपकी सेवा में इस्तेमाल किए गए संसाधनों को साफ़ करते समय onDestroy() कॉलबैक.