简体   繁体   中英

Audio settings access via AudioManager causes decrease in volume for other apps?

In the application, I am developing we have to notify the user via beep sound when an update to foreground Service happens.

We use this foreground service for audio recording. To play beep we use the speaker. We enable phones speakers before playing beep and disable on beep completely played, as follows :

    stopSoundPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {
                    SpeakerManager.get().disable();
                    .....
                }
            });
            SpeakerManager.get().enable();
            stopSoundPlayer.start();

I have following permissions in Manifest :

// Audio related permissions
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

// Other permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

The runtime audio recording permission is managed properly.

But when my application is installed on any phone it automatically decreases the volume of all other applications which are audio playing. When I uninstall my application audio volume is restored. What may have caused this?

For reference below is my SpeakerManager class :

public class SpeakerManager {

    private static SpeakerManager instance;

    private final AudioManager audioManager;

    private SpeakerManager(Context context) {
        audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        audioManager.setMode(AudioManager.STREAM_MUSIC);
    }

    public static void init(Context context) {
        instance = new SpeakerManager(context);
    }

    public static SpeakerManager get() {
        if (instance == null) {
            throw new IllegalStateException("SpeakerManager should be initialized by calling init()");
        }
        return instance;
    }

    public void enable() {
        if (null != audioManager) {
            audioManager.setSpeakerphoneOn(true);
        }
    }

    public void disable() {
        if (null != audioManager) {
            audioManager.setSpeakerphoneOn(false);
        }
    }
}

Try below for playing beep sound

public final class BeepManager {

    private static final String TAG = BeepManager.class.getSimpleName();

    private static final float BEEP_VOLUME = 0.10f;

    private final Context context;

    public BeepManager(Activity activity) {
        activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);

        // We do not keep a reference to the Activity itself, to prevent leaks
        this.context = activity.getApplicationContext();
    }


    public void playBeepSound() {
        AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

        if (am != null) {
            switch (am.getRingerMode()) {
                case AudioManager.RINGER_MODE_SILENT:
                case AudioManager.RINGER_MODE_VIBRATE:
                    return;
            }
        }

        MediaPlayer mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mp.stop();
                mp.release();
            }
        });
        mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                Log.w(TAG, "Failed to beep " + what + ", " + extra);
                // possibly media player error, so release and recreate
                mp.stop();
                mp.release();
                return true;
            }
        });
        try {
            AssetFileDescriptor file = context.getResources().openRawResourceFd(R.raw.beep_sound);
            try {
                mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
            } finally {
                file.close();
            }
            mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
            mediaPlayer.prepare();
            mediaPlayer.start();
        } catch (IOException ioe) {
            Log.w(TAG, ioe);
            mediaPlayer.release();
        }
    }
}

I have followed Akhils answer , but with minor changes :

Change 1: Removed below line from constructor as I want use this in service.

activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);

Change 2: As I wanted to play this beep as notification sound I changed following line mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); to mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);

Hence bounty goes to Akhil :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM