Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Incoming call listener without permission

I know that we can listen phone state by broadcast receiver with filter

action android:name="android.intent.action.PHONE_STATE"

but this way requires permission

uses-permission android:name="android.permission.READ_PHONE_STATE"

How to determine the incoming GSM call whithout this permission?

P.S.

I'm sure that this is possibly because Whatsapp doing it.
When I'm talking on the Whatsapp audio calls and then got incoming gsm call - whatsapp checking it and set self call to pause. How do they understand that need set pause?

Whatsapp has READ_PHONE_STATE permission in Manifest file, but I check calls on Android 6 and not granted this permission. This permission was disabled.

When this permission is disabled my Receiver doesn't receive action android.intent.action.PHONE_STATE and PhoneStateListener is not working.

like image 291
Dmitriy Puchkov Avatar asked Mar 14 '17 11:03

Dmitriy Puchkov


2 Answers

I found solution without this permission.

First of all (when our sip call start) we need request audio focus with lisener

 mAudioManager.requestAudioFocus(afChangeListener, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);

The afChangeListener can tell us then someboby changed audio focus and then we can check current audio channel. If current mode is AudioManager.MODE_IN_CALL or AudioManager.MODE_RINGTONE then we know that gsm call started.

AudioManager.OnAudioFocusChangeListener afChangeListener =
        new AudioManager.OnAudioFocusChangeListener() {
            public void onAudioFocusChange(int focusChange) {

                if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
                    // Permanent loss of audio focus
                    // Pause playback immediately
                } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
                    ScheduledExecutorService scheduler = App.getInstance().obtainScheduler();
                    scheduler.schedule(() -> {
                         Logging.i(TAG, "onAudioFocusChange defer mode = " + mAudioManager.getMode());
                         switch (mAudioManager.getMode()) {
                             case AudioManager.MODE_RINGTONE:
                             case AudioManager.MODE_IN_CALL:
                                 //**there we can start standby mode**
                                 break;
                         }
                    }, 100, TimeUnit.MILLISECONDS);

                } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
                    Logging.i(TAG, "onAudioFocusChange AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
                    // Lower the volume, keep playing
                } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
                    // Your app has been granted audio focus again
                    //**there we can stop standby mode**
                }

            }
        };
like image 104
Dmitriy Puchkov Avatar answered Oct 22 '22 06:10

Dmitriy Puchkov


First of all whatsapp used permission which required to get phone state

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Here is WhatsApp menifest file link.

You can see their they have added their and used inside it.

Android itself provide best solution to handle it using broadcast receiver.You should use these otherwise your system would be hacky.

Follow these link to work with broadcast receiver to detect phone calls.

Hope these helps you.

like image 32
Jitesh Mohite Avatar answered Oct 22 '22 06:10

Jitesh Mohite