Использование AudioManager мешает звуку вызова

Я использую следующий код в BroadcastReceiver (прослушиватель состояния телефона), чтобы включить громкую связь:

final Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        audioManager.setMode(AudioManager.MODE_IN_CALL);
        audioManager.setSpeakerphoneOn(true);
    }
}, 500);

Это происходит, когда новый исходящий вызов инициируется через мое приложение. Когда вызов отключен, я выключу громкоговоритель:

AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(false);

Это все, кажется, хорошо работает... в первый раз. Позже, мои звуковые потоки телефона, похоже, запутались в беспорядке. Последующие вызовы странно молчат, даже звонки, сделанные из-за пределов моего кода приложения (где приведенные выше настройки не запускаются). Я могу получить звук звонка, казалось бы, случайно, но я не уверен, что заставляет его возвращаться.

Любые идеи о том, что я могу делать неправильно? Есть ли ошибка Android, о которой я не знаю? Как я могу избежать отключения звука для последующих вызовов?

EDIT: Я тестирую Galaxy S4.

Ответ 1

Я решил эту проблему. Кажется, что код, который искажал мой звук, был такой:

audioManager.setMode(AudioManager.MODE_IN_CALL);

Я использовал этот метод, потому что я не мог заставить настройку громкой связи успешно участвовать без него (я нашел предложение установить режим в другом ответе на переполнение стека... он работал, но имел проблемные последствия).

Все, что мне действительно нужно было сделать, это удалить эту строку и увеличить задержку обработчика от 500 до 2000.

Я также поддерживал статическую ссылку на AudioManager, как это предложено в этом ответе. В этом конкретном случае это не кажется необходимым, но лучше безопасно, чем жаль.

Ответ 2

Сначала я скопирую этот текст из документации в setMode, просто чтобы убедиться, что вы его учитываете:

The audio mode encompasses audio routing AND the behavior of the telephony layer.
Therefore this method should only be used by applications that replace the platform-wide 
management of audio settings or the main telephony application

Другими словами, только une-приложение в системе должно быть связано с такими методами. Если это сделано иначе, согласованность не гарантируется.

Затем я бы проверил ваши разные аудиопотоки, если у вас есть некоторые из них слишком низко (STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING, STREAM_MUSIC или STREAM_ALARM). И, возможно, попробуйте использовать setStreamMute вместо setSpeakerphoneOn.

Было бы полезно узнать, действительно ли ваше приложение заменяет the platform-wide management of audio settings or the main telephony application