setStreamMute never unmutes

2019-01-12 04:09发布

问题:

In the documentation, it is said:

The mute command is protected against client process death: if a process with an active mute request on a stream dies, this stream will be unmuted automatically.

The mute requests for a given stream are cumulative: the AudioManager can receive several mute requests from one or more clients and the stream will be unmuted only when the same number of unmute requests are received.

Well, the first paragraph is true; Whenever my process dies, all of the streams I muted are automatically unmuted. However, no matter how many time I call setStreamMute(someStream, false) it NEVER EVER unmutes. Last time I tried calling it over 1 million times after muting only ONCE and NOTHING happens!

Just to mention - If i unmute it in the same method I mute it - it stays unmuted. But on the next calls to the same method - it never unmutes.

I am muting in a Broadcast Receiver onReceive method, which I start using an alarm manager. So maybe it because my app was killed during the time between the muting call and the unmuting call? (But my app still stays in the RAM)

Can this problem be because I am not keeping a reference to the AlarmManager (Getting different instances each time?)

Did anyone encounter this problem?

回答1:

Apperantly, there is a bug in these Android versions; Tested for versions 2.2 and 2.3.3 and the bug exists. Looks like, if you call setStreamMute on an AudioManager object:

AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
am.setStreamMute(...., true);

and you lose your reference, then get a new reference:

am = null;
am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);

No matter how many times you call am.setStreamMute(..., false) now, it will never unmutes.

I think ill report this bug now..

Lesson: Keep a static reference to your AudioManager.

@Michell Bak, thanks for giving me the idea to check whether its the Android software bug :) I've been stuck on this thing for way too much time, and I never had the idea to see if its not my fault.



回答2:

I've never used that API before, but a quick Google search, returned a few results with it not working. It seems to be a bug that's still present in Android 2.3:

http://code.google.com/p/android/issues/detail?id=4235



回答3:

I solve the problem by putting the audio manager variable in the application

   public class myApplication extends Application {


  static AudioManager am;
      public void onCreate() {
    super.onCreate();
    am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    this.setMute(false);
      }
    }

Then in my activity class add this function:

private AudioManager getAM() {
return ((elpApplication)getApplication()).am;

}

and here is how I use the getAM();

private void toogleMediaPlayerMute() {

    //defaultVolumn = am.getStreamVolume(AudioManager.STREAM_MUSIC);
    elpApplication app = getElpApp();
    Log.d("appmute", String.valueOf(app.isMute()));
    if (!app.isMute()) {
        getAM().setStreamVolume(AudioManager.STREAM_MUSIC, 0,
                AudioManager.FLAG_PLAY_SOUND);
        getAM().setStreamMute(AudioManager.STREAM_MUSIC, true);
        ismute = true;

    } else {
        int maxVolume = getAM().getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        Log.d("maxvol", String.valueOf(maxVolume));
        getAM().setStreamMute(AudioManager.STREAM_MUSIC, false);
        getAM().setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume,
                AudioManager.FLAG_SHOW_UI);

        ismute = false;
        // app.setMute(ismute);
    }
    app.setMute(ismute);
}


回答4:

I have been having the same problem w/ newer versions of the API. So, to work [around] this issue, I've implemented a bit of 'old-school' solution. If your design is such that you handle getting the byte stream / sending the byte stream directly - send a byte array filled with zeros if mute is selected: *

...
byte[] whatToSend = realByteData;
byte [] mutedOutput = new byte[recBuffSize];
Array.setByte( mutedOutput, 0, (byte) 0);
...
if ( muteSet )
  whatToSend = mutedOutput;

amountWritten = audioTrack.write(whatToSend, 0, amountRead);

*