Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if the user actually dialed a number programmatically

In an app I show some phone numbers in a textview that the user can tap on them to dial them (autoLink set to phone on the textview).
When I tap on the numbers the option to dial that number shows up.
My question is: Is there a way to figure out if the user actual pressed the dial button in the dial pad to actually do the call?

like image 491
Jim Avatar asked Nov 19 '22 19:11

Jim


1 Answers

You can create a GSMBroadcastListener and receive events about the call state of the phone (Hangup, Ringing, Established, etc).

If you want to know, if it happened after a click on your phone button, just create this listener in the on-click event, so it will receive the events only if one of your buttons is clicked. Unhook (unregister) in the Hangup-Event after the call has ended, so will not receive events after the call.

Here is my implementation with an Listener Interface that works fine in a production app:

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

Code:

public interface GSMBroadcastListener {
    void onHangUp(
    void onEstablished();
    void onRinging();
}


public class GSMBroadcastReceiver extends BroadcastReceiver {

    private static GSMBroadcastListener handler = null;
    private static PrivateListener privateListener = null;

    public static void registerGSMBroadcastListener(@Nullable GSMBroadcastListener listener) {
        handler = listener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        if (privateListener == null) {
            privateListener = new PrivateListener();
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            telephonyManager.listen(privateListener, PhoneStateListener.LISTEN_CALL_STATE);
        }

    }

    private class PrivateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);

            Log.i("PHONE_STATE", String.format("GSM event \"onCallStateChanged\" received: state=%d; incomingNumber=\"%s\";", state, incomingNumber));
            if (handler != null) {
                if (state == TelephonyManager.CALL_STATE_IDLE) {
                    Log.i("PHONE_STATE", "Forwarding event as \"GSM onHangUp\".");
                    handler.onHangUp();
                } else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                    Log.i("PHONE_STATE", "Forwarding event as \"GSM onEstablished\".");
                    handler.onEstablished();
                } else if (state == TelephonyManager.CALL_STATE_RINGING) {
                    Log.i("PHONE_STATE", "Forwarding event as \"GSM onRinging\".");
                    handler.onRinging();
                }
            }
        }
    }

}

This class will forward GSM events to a listener that you add with GSMBroadcastReceiver.registerGSMBroadcastListener.

To use it, you need this:

  • Register the receiver in your manifest

    <receiver android:name=".handlers.GSMBroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE"/>
        </intent-filter>
    </receiver>
    
  • Then, in the click listener of your phone number button, register a listener: (Note, that you unregister it in the onHangUp() callback!)

    GSMBroadcastReceiver.registerGSMBroadcastListener(new GSMBroadcastListener() {
    @Override
    public void onRinging() {
        Log.i("GSM", "GSM event \"onRinging\" received.");
    }
    
    @Override
    public void onEstablished() {
        Log.i("GSM", "GSM event \"onEstablished\" received.");
    }
    
    @Override
    public void onHangUp() {
        Log.i("GSM", "GSM event \"onHangUp\" received.");
        GSMBroadcastReceiver.registerGSMBroadcastListener(null); // Unregister the handler!
    }
    });
    

That's it! You should now get informed about GSM activity after your button click.

Hope this helps, cheers, Gris

like image 200
Grisgram Avatar answered Dec 28 '22 11:12

Grisgram