Home » Android » How to detect an outgoing call ring in Android using Visualizer class?

How to detect an outgoing call ring in Android using Visualizer class?

Posted by: admin May 14, 2020 Leave a comment

Questions:

I currently need to capture the moment when an outgoing call begins ringing. According to Abeer Ahmad in “How to identify the ringing state of outgoing call in android”, a solution would be to detect the frequency change of the emitted sound (from 0 to the value corresponding to the ring) using the Visualizer class. However, no frequency value other than 0 (silence) is detected while I make a call. This does not correspond to what happens when the mobile emits another sound, such as the reproduction of an audio track, where the frequency values are detected. Could someone help me, or give me an alternative solution?

Here is my code:

mVisualizer = new Visualizer(0);
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
Visualizer.OnDataCaptureListener listener = new Visualizer.OnDataCaptureListener(){
                    @Override
                    public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { }
                    @Override
                    public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {
                        for (int i=0;i<bytes.length;i++) {
                            if (bytes[i] != 0) {
                              Log.i("INFO","FREQUENCY:"+bytes[i]);
                                break;
                            }
                        }
                    }
                };
mVisualizer.setDataCaptureListener(listener, Visualizer.getMaxCaptureRate() / 2, true, true);

I’m using Android Jellybean (API 17).

How to&Answers:

Calling new Visualizer(0); listens to Stream 0, the mixed output.

The issue is call audio isn’t always present in the mixed output as indicated on this Google Bug so you need to find the correct stream yourself. However, I haven’t found a simple way to do this.

MediaPlayer used to have a non-public snoop method which could be utilized but it was removed from recent versions. A long shot you could try is creating an audio track on the same stream and listening to that session id:

AudioTrack track = new AudioTrack(AudioManager.STREAM_VOICE_CALL, aSampleRate, 
        AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, 
        aBuffersize, AudioTrack.MODE_STREAM);

You could also try calling audioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true); before starting your visualizer. In theory as STREAM_VOICE_CALL will become the only session allowed to produce audio, it should affect the results of the visualizer.

Note: If you look at generateAudioSessionId in AudioManager sources you’ll see it uses the Native AudioSystem class. I would suggest it’s possible to use the NDK to access this class and find current audio session id’s