2011-07-29 20 views
29

मैं बिना किसी सफलता के एंड्रॉइड के AudioManager.setMicrophoneMute() का उपयोग करने की कोशिश कर रहा हूं। यही है, यह माइक्रोफोन को म्यूट करने से इंकार कर देता है, इससे कोई फर्क नहीं पड़ता कि मैं क्या करता हूं।setMicrophoneMute() कैसे काम करता है?

मैं कुछ सुराग के लिए वेब खोज की है और मैं कई समान अनुभव रिपोर्टिंग संदर्भ मिले:

कौन सा सवाल भीख माँगता: पर AudioManager.setMicrophoneMute() काम करता है सब? क्या यह केवल एक स्टब विधि है, एंड्रॉइड के कुछ भविष्य के संस्करण में लागू होने का इंतजार कर रहा है? यदि नहीं, तो यह कैसे काम करता है? इसे काम करने के लिए मुझे क्या चाहिए? इसके नाम के रूप में कार्य करने वाली स्थितियां क्या हैं?

संपादित करें: मैंने देखा है कि इस विधि के लिए प्रलेखन कहते हैं:

यह विधि केवल अनुप्रयोगों को बदलने के द्वारा इस्तेमाल किया जाना चाहिए ऑडियो सेटिंग या मुख्य टेलीफोनी की मंच चौड़ा प्रबंधन आवेदन।

इसका क्या अर्थ है? मैं प्लेटफार्म-व्यापी प्रबंधन को क्यों बदलना चाहूंगा? क्या मुझे वास्तव में ऐसा करने की ज़रूरत है? अगर ऐसा है, तो मैं वह कैसे करू?

संपादित करें: नीचे इस सवाल का जवाब बहुत अच्छा है लेकिन मैं अभी भी समझ में नहीं आता:

  1. कि झंडा (डेटाबेस में SET_MIC_MUTE) कैसे किया जा रहा है?
  2. यह ध्वज वास्तव में फोन के अंदर प्री-एम्पलीफायर सर्किट से माइक्रोफ़ोन सिग्नल डिस्कनेक्ट करता है?
  3. यदि ऐसा नहीं करता है, तो वह कौन करता है?
  4. यदि कुछ भी नहीं करता है, तो यह "म्यूट" कैसे काम करने की उम्मीद है?

कृपया समझाएं। धन्यवाद।

+1

मुझे यकीन है कि आप होना चाहिए हूँ - लेकिन आप 'checkAudioSettingsPermission' द्वारा परीक्षण अनुमतियाँ सक्षम था? – YetAnotherUser

+1

@YetAnotherUser मैंने [checkAudioSettingsPermission] के लिए "प्रलेखन" की जांच की है (http://www.androidjavadoc.com/1.0_r1_src/android/media/AudioService.html#checkAudioSettingsPermission%28java.lang.String%29) और लौटने के अलावा बूलियन, स्ट्रिंग पैरामीटर में यह क्या करता है और यह क्या अपेक्षा करता है इसके बारे में कोई संकेत नहीं है। मैं वास्तव में 'setMicrophoneMute() 'से' checkAudioSettingsPermission' 'से प्रश्न नहीं बदलना चाहता हूं, लेकिन क्या आपको कोई विचार है कि' checkAudioSettingsPermission' क्या करता है और उस 'स्ट्रिंग' पैरामीटर का अर्थ क्या है? +1 – ateiob

+1

आप शुरुआत में जो हासिल करना चाहते हैं उसे रेखांकित करना चाहते हैं। ऐसा लगता है जैसे आप थोड़ा सा कोर्स प्राप्त कर चुके हैं। आप शायद टेलीफ़ोनी-एप्लिकेशंस को प्रतिस्थापित नहीं करना चाहते हैं और न ही आपको (और आप प्लेटफार्म प्रमाण के बिना रास्ते से नहीं कर सकते)। – marsbear

उत्तर

21

an00b पर विस्तार से बता दें: उपरोक्त रों जवाब और सवाल हम स्रोत कोड में बेहतर जानकारी के लिए है का संपादित संस्करण। IAudioflinger AudioFlinger सेवा करने के लिए इंटरफ़ेस और

करने के लिए कॉल
virtual status_t setMicMute(bool state) 
{ 
    Parcel data, reply; 
    data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 
    data.writeInt32(state); 
    remote()->transact(SET_MIC_MUTE, data, &reply); 
    return reply.readInt32(); 
} 

वास्तव में माइक्रोफ़ोन म्यूट करने के बाइंडर लेन-देन है। बाइंडर कॉल की प्राप्ति की ओर दिखाई देता है:

 status_t BnAudioFlinger::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 
    { 
switch(code) { 
... 
case SET_MIC_MUTE: { 
      CHECK_INTERFACE(IAudioFlinger, data, reply); 
      int state = data.readInt32(); 
      reply->writeInt32(setMicMute(state)); 
      return NO_ERROR; 
     } break; 
... 
}} 

और AudioFlinger में setMicMute के वास्तविक क्रियान्वयन के लिए कहता है। अगला चरण इस फ़ंक्शन को देखना है:

status_t AudioFlinger::setMicMute(bool state) 
{ 
    // check calling permissions 
    if (!settingsAllowed()) { 
     return PERMISSION_DENIED; 
    } 

    AutoMutex lock(mHardwareLock); 
    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE; 
    status_t ret = mAudioHardware->setMicMute(state); 
    mHardwareStatus = AUDIO_HW_IDLE; 
    return ret; 
} 

यहां हम दो चीजें नोट कर सकते हैं। पहला यह है कि माइक्रोफ़ोन को म्यूट करने में सक्षम होने की अनुमति है। सेटिंग्स में अनुमति की अनुमति दी गई है एंड्रॉइड.permission.MODIFY_AUDIO_SETTINGS जैसा कि माइक्रोफ़ोन को म्यूट करने के लिए पहली आवश्यकता के ऊपर टिप्पणियों में से एक में उल्लिखित है, यह है कि आपके एप्लिकेशन ने घोषणा की है कि उसे इस अनुमति की आवश्यकता है। अगली बात यह है कि अब हम mAudioHardware-> setMicMute (राज्य) का उपयोग कर setMicMute के हार्डवेयर विशिष्ट संस्करण में कॉल करते हैं।

हार्डवेयर प्लग करने के तरीके के बारे में अधिक जानकारी के लिए फ़ाइल AudioHardwareInterface.cpp का अध्ययन करें। असल में यह एक बाहरी सी कॉल के साथ एक libhardware में समाप्त होता है ताकि ऑडियोियोर्डवेयर बनाया जा सके जो मंच के लिए सही ऑडियोहार्डवेयर में प्लग करता है। ए 2 डीडी आधारित हार्डवेयर का उपयोग करने के लिए स्विच भी हैं, जो एमुलेटर के लिए एक सामान्य है और ऑडियो को दबा रहा है। माना जाता है कि आप एक वास्तविक डिवाइस पर काम कर रहे हैं, कार्यान्वयन तब बहुत अधिक हार्डवेयर निर्भर करता है। इसके लिए एक महसूस करने के लिए हम उदाहरण के रूप में क्रेस्पो (नेक्सस एस) से उपलब्ध ऑडियोहार्डवेयर का उपयोग कर सकते हैं।

status_t AudioHardware::setMicMute(bool state) 
{ 
    LOGV("setMicMute(%d) mMicMute %d", state, mMicMute); 
    sp<AudioStreamInALSA> spIn; 
    { 
     AutoMutex lock(mLock); 
     if (mMicMute != state) { 
      mMicMute = state; 
      // in call mute is handled by RIL 
      if (mMode != AudioSystem::MODE_IN_CALL) { 
       spIn = getActiveInput_l(); 
      } 
     } 
    } 

    if (spIn != 0) { 
     spIn->standby(); 
    } 

    return NO_ERROR; 
} 

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

अपने 4 अतिरिक्त प्रश्न करने के लिए लघु संस्करण देने के लिए:

  1. झंडा कोड की कई परतों के माध्यम से पारित हो जाता है जब तक यह हार्डवेयर विशिष्ट मूक माइक्रोफोन में समाप्त होता है।

  2. जब हार्डवेयर विशिष्ट कोड कम से कम कुछ उपकरणों पर कॉल में छोड़कर हार्डवेयर विशिष्ट कोड चलाया जाता है तो माइक्रो डिस्कनेक्ट हो जाता है।

  3. जब सेटमिक्रोपोन म्यूट माइक को म्यूट नहीं करता है, यानी जब कॉल में टेलीफ़ोनी एपीआई का उपयोग करके ऐसा करना संभव हो सकता है, तो मैं फोन ऐप का अध्ययन करने का सुझाव दूंगा।

  4. वर्तमान कार्यान्वयन म्यूट के आधार पर कॉल में नहीं होने पर काम करना प्रतीत होता है लेकिन प्लेटफॉर्म पर हार्डवेयर विशिष्ट समस्याएं हो सकती हैं जिन पर हमने अध्ययन नहीं किया है।

संपादित करें:

कुछ और खुदाई और जिस तरह मॉडेम सीपीयू के लिए एक मूक आदेश भेजने के लिए आंतरिक फोन इंटरफेस है कि com.android.internal.telephony पैकेज का हिस्सा है के माध्यम से है क्या यह एसडीके डेवलपर्स के लिए उपलब्ध नहीं है। टिप्पणी के आधार पर आपने देखा कि यह फ़ंक्शन केवल उन अनुप्रयोगों द्वारा उपयोग किया जाना चाहिए जो ऑडियो प्रबंधन या मूल टेलीफ़ोनी एप्लिकेशन को प्रतिस्थापित करते हैं, मुझे लगता है कि AudioManager.setMicrophoneMute() को हमेशा माइक्रोफ़ोन को म्यूट करना था। लेकिन चूंकि अन्य अनुप्रयोगों ने शायद इसका उपयोग किया है, इसलिए उन्होंने हार्डवेयर कार्यान्वयन में एक चेक जोड़ा है ताकि फोन एप्लिकेशन की स्थिति को गड़बड़ न किया जा सके जो म्यूट कनेक्शन के साथ-साथ माइक्रोफोन का ट्रैक रखता है। यह कार्य शायद हार्डवेयर कार्यान्वयन के विवरणों के कारण अभी तक काम नहीं कर रहा है और तथ्य यह है कि म्यूट एक अधिक जटिल ऑपरेशन है, जो शुरुआत में कॉल राज्यों पर विचार करते समय सोचता है।

+0

वाह! मैं इससे बेहतर जवाब की उम्मीद नहीं कर सका। एएनएसबी का जवाब एक अच्छा प्रारंभिक बिंदु था, लेकिन आप निश्चित रूप से गहरे स्तर पर पहुंचे, जो मुझे समझने की जरूरत है कि यह क्यों मेरे लिए काम नहीं करता है जब 'पहचानकर्ता' सुन रहा है। यही है, अगर मैं 'mAudioManager.setMicrophoneMute (true)' को 'पहचान पहचान' के अंदर कॉल करने का प्रयास करता हूं, तो RenitionListener.onReadyForSpeech() ', कुछ भी नहीं होता है: माइक्रोफ़ोन भाषण स्वीकार करना जारी रखता है जैसे कि म्यूट कभी नहीं कहा जाता था। और ** प्रगति पर कोई कॉल नहीं है! ** क्या इसका मतलब यह है कि Google की 'पहचान पत्र' ऑडियो सिस्टम :: MODE_IN_CALL सेट करता है? – ateiob

+0

मुझे अभी एक और संस्करण [AudioHardware.cpp] (http://vogue-android.googlecode.com/hg/AudioHardware.cpp) मिला है जो इसे एक और अधिक जटिल तरीके से लागू करता है ... और मैं बस इतना चाहता था 'onReadyForSpeech() 'में माइक्रोफ़ोन को संक्षेप में डिस्कनेक्ट करने के लिए ... क्या इसे पूरा करने का कोई तरीका है? ऑडियो प्रबंधन की जगह क्या बदलती है? – ateiob

+1

मुझे रीडफ़ोरस्पेच() पर अपने प्रश्न का उत्तर देने के लिए फिर से ऑडियो कोड में थोड़ा और खोदना होगा, लेकिन अब तक मुझे लगता है कि ऐसा लगता है कि एपीआई फ़ंक्शन AudioManager.setMicroPhoneMute() वास्तव में आधुनिक में ऑडियो रूटिंग की जटिलता को प्रतिबिंबित नहीं करता है स्मार्टफोन्स। इसका शायद मतलब है कि आप जो चाहते हैं उसे लागू करने के लिए कोई सामान्य तरीका नहीं है क्योंकि प्रत्येक हार्डवेयर प्लेटफ़ॉर्म माइक्रोफ़ोन को विभिन्न तरीकों से म्यूट करने में संभालता प्रतीत होता है। अगर मुझे कोई रास्ता मिल जाए तो मैं इस टिप्पणी को संपादित करूंगा। – BMB

12

प्रयास करें AudioManager source code को देख:

public void setMicrophoneMute(boolean on) { 
    if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 
     return; 
    } 
    synchronized (mSettingsLock) { 
     if (on != mMicMute) { 
      AudioSystem.muteMicrophone(on); 
      mMicMute = on; 
     } 
    } 
} 

कौन सा, बारी में, प्रतिनिधियों यह AudioSystem को जो लगता है:

public void setMicrophoneMute(boolean on){ 
    IAudioService service = getService(); 
    try { 
     service.setMicrophoneMute(on); 
    } catch (RemoteException e) { 
     Log.e(TAG, "Dead object in setMicrophoneMute", e); 
    } 
} 

माइक्रोफोन म्यूट करने का कार्य IAudioService नाम के एक सेवा को सौंपा जाता है native code में लागू किया जाना चाहिए:

status_t AudioSystem::muteMicrophone(bool state) { 
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 
    if (af == 0) return PERMISSION_DENIED; 
    return af->setMicMute(state); 
} 

कौन सा, बारी में, यह IAudioFlinger के प्रतिनिधियों के रूप में IAudioFlinger.cpp में पाया जा सकता:

virtual status_t setMicMute(bool state) 
{ 
    Parcel data, reply; 
    data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); 
    data.writeInt32(state); 
    remote()->transact(SET_MIC_MUTE, data, &reply); 
    return reply.readInt32(); 
} 
+1

धन्यवाद लेकिन मुझे अभी भी समझ में नहीं आता कि यह कैसे काम करता है। मैं देखता हूं कि यह कुछ डेटाबेस में ध्वज को मूल रूप से सेट या साफ़ करने के लिए कई परतों और रैपरों के माध्यम से जाता है। लेकिन उस ध्वज का उपयोग कैसे किया जा रहा है? यह ध्वज वास्तव में फोन के अंदर प्री-एम्पलीफायर सर्किट से माइक्रोफोन सिग्नल को डिस्कनेक्ट करता है? अगर ऐसा नहीं होता है, तो वह कौन करता है? अगर ऐसा कुछ नहीं करता है, तो यह "म्यूट" कैसे काम करने की उम्मीद है? कृपया समझाएँ। +1। – ateiob

1

किसी कारण से मुझे टिप्पणी के रूप में पोस्ट करते समय त्रुटियां मिलती हैं। यहां कुछ जानकारी दी गई है जो मैंने सीखा है कि कौन से डिवाइस सेट हैं माइक्रोफोन मॉ्यूट() करता है और काम नहीं करता है, और इसके आसपास काम करने के लिए (कुछ) तरीके क्या हैं - निश्चित रूप से एक आदर्श समाधान नहीं है! setMicrophoneMute(boolean) doesn't work on some devices

+1

आपके द्वारा प्रदान किया गया लिंक मेरे मूल पोस्टिंग में दूसरी बुलेट के समान है। – ateiob

5

दोस्तों। मुझे सैमसंग गैलेक्सी पर एक ही समस्या मिली और मैंने हल किया MODE_IN_COMMUNICATION मोड का उपयोग किया। मैंने AudioManager.java स्रोत कोड में देखा, यह कहता है: 1.MODE_IN_CALL- 'ऑडियो मोड कॉल करें। एक टेलीफोनी कॉल स्थापित किया गया है। ' 2.MODE_IN_COMMUNICATION- 'संचार ऑडियो मोड में। एक ऑडियो/वीडियो चैट या वीओआईपी कॉल स्थापित किया गया है। ' बीकॉज़ मैं तीसरे वीओआईपी पुस्तकालय का उपयोग करता हूं, फिर मैं MODE_IN_COMMUNICATION का उपयोग करता हूं और समस्या हल करता हूं। इस तरह:

AudioManager audioManager = (AudioManager) 
    context.getSystemService(Context.AUDIO_SERVICE); 
    // get original mode 
    int originalMode = audioManager.getMode(); 
    audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); 
    // change mute 
    boolean state = !audioManager.isMicrophoneMute(); 
    audioManager.setMicrophoneMute(state); 
    // set mode back 
    audioManager.setMode(originalMode); 
+1

'MODE_IN_COMMUNICATION' ने चाल की, मैं' MODE_IN_CALL' का उपयोग करके माइक को म्यूट/अनम्यूट करने का प्रयास कर रहा था। मदद के लिए धन्यवाद –

संबंधित मुद्दे