Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inhibit "Loud music may harm your hearing..." warning in Android

Tags:

android

I have an Android application for a Samsung tablet that uses an external device which draws its power from the tablet headphone jack. When the external device is powered on (by programmatically maxing out the volume), Android briefly displays a warning popup saying: "Loud music may harm your hearing if you listen to it for too long..." I would like that message to not be displayed.

Here's the offending line of code:

mAudioMgr.setStreamVolume(AudioManager.STREAM_MUSIC, mAudioMgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);

It's not an option to only turn it up halfway. In fact, I've seen the tablet display the warning (when changing the volume by hand) even on volume settings lower than the max setting.

And yes, I record the original volume, and restore it when we're done with the external device.

Thanks for any suggestions.

like image 427
Mike Hedman Avatar asked Feb 15 '13 18:02

Mike Hedman


2 Answers

Since you cannot disable the systems message, and you will also have a problem when the user manually lowers the volume, I suggest you do a series of controls which will help with that. To max the volume:

public void maxVolume() {
    AudioManager audioManager = (AudioManager)context.getSystemService(this.AUDIO_SERVICE);
    while ( audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) < audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)) {
        audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0);
    }
}

To prevent users from manually changing volume:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) 
         || (keyCode == KeyEvent.KEYCODE_VOLUME_UP) 
         || (keyCode == KeyEvent.KEYCODE_VOLUME_MUTE)) {
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

You can call maxVolume() in your onCreate method, and later call it just before you start using the jack output procedure to make sure the system has not changed your volume. Alternatively you can register a listener to listen for volume changes, make maxVolume() static and call it from the listener. Hope it helps you out!

like image 155
alexm Avatar answered Oct 21 '22 16:10

alexm


I know that this question is quite old, but I just ran across this issue myself. I figured that I would add to the answers given with what I found in case it helps someone else that happens upon this.

One of the posts here mentions that the warning is not in the AOSP, but this is not true. Please reference the VolumePanel::SafteyWarning class here: VolumePanel::SafetyWarning

Once you peruse through the SafetyWarning class you'll notice that there is a hidden method inside of the AudioManager class called disableSafeMediaVolume. You can, through reflection, invoke this hidden method easily enough, but if you do then you'll get a security exception as it requires the system permission "android.permission.STATUS_BAR_SERVICE".

So... with that said, the dialog as far as I can tell, cannot be programmatically suppressed unless you have this system permission.

What we ended up doing with the blessing of product management is we cache the volume setting in SharedPreferences and then reset it from the cache when our application starts. If it happens to be above the threshold for the warning dialog then the warning will be shown and the user will just have to press OK to get the volume setting that they want, but at least they won't have to manually reset the volume themselves.

A couple of other notes on why some don't see this dialog. You will only see it if you have headphones (or earbuds, or a wired headset) plugged into the device and you attempt to set the media volume stream over a certain threshold (on the Samsung Galaxy Tab A this threshold is 60%). If you press OK at the dialog then it will not be shown again unless you either restart the device or unplug the headphones and plug them back in (with the volume set at or above the threshold).

Hope this helps someone.

like image 37
Thomas Sunderland Avatar answered Oct 21 '22 18:10

Thomas Sunderland