4

In my app i want to identify whether the outgoing call state like waiting,received or rejected by other side. I searched a lot in these below links
Outgoing call status How to detect answered or rejected state in outgoing call,outgoing call information through android BroadcastReceiver,identify outgoing call connect event
But couldn'd find a proper answer.Plz help me.Thanx.

Community
  • 1
  • 1
Ekanta Swain
  • 473
  • 2
  • 13
  • 28

4 Answers4

2

I know its been a while but i hope to be helpful for someone still looking for a solution!

I recently had to work on a similar project where i needed to capture the ringing state of an outgoing call and the only way i could find was using the hidden Api of native dial-up App. This would only be possible for android > 5.0 because of the api changes. This was tested on Android 5.0.1, and worked like a charm. (p.s. you would need a rooted device for it to work, because you need to install your app as a System application (google how!) which will then be able to detect the outgoing call states).

For the record, PhoneStateListener doesn't work for detecting the outgoing call states as mentioned in many posts.

First, add this permission in the manifest file,

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

Then define you broadcastreceiver, (here is a sample code!)

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;

public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, final Intent intent)
    {
        switch (intent.getIntExtra("foreground_state", -2)) {
            case 0: //  PreciseCallState.PRECISE_CALL_STATE_IDLE:
                System.out.println("IDLE");
                break;
            case 3: //  PreciseCallState.PRECISE_CALL_STATE_DIALING:
                System.out.println("DIALING");
                break;
            case 4: //  PreciseCallState.PRECISE_CALL_STATE_ALERTING:
                System.out.println("ALERTING");
                break;
            case 1: //  PreciseCallState.PRECISE_CALL_STATE_ACTIVE:
                System.out.println("ACTIVE");
                break;
        }

    }
} 

I replace some of the constants with their values because i saw alot of confusion among the folks unfamiliar with the concept of reflection (for ease). Alerting is basically the state when receiver is actually ringing! and that does not include the call setup time!.

Ali Tariq
  • 63
  • 1
  • 8
  • This does not track outgoing calls ringing state. Bad answer – yams Jun 17 '22 at 14:37
  • @yams ... why do you say its not tracking outgoing calls state? Like i mentioned before - this does exactly that. If the receiver is ringing ... it would trigger case 4 (ALERTING) in the above code – Ali Tariq Jul 26 '23 at 04:40
-1

I had a similar issue. I wanted to detect some states of outgoing calls. I solved the issue by using visualizer class in android. It can return you with a Fourier transform of the current audio playing on the speaker. Using the type of audio being played(small beeping on the front speaker) you can determine the state of out-going call. For example you can know whether the phone has started ringing on the receiver or not. When ever visualizer return non-zero samples it is a yes.

Background audio wont disturb you because during a phone call the caller app shuts down all other audio.

Wait for status off_hook and then start your visualizer class

-3

Try this, Look in else part and do changes there, it will work.

public class CallBr extends BroadcastReceiver {
        Bundle bundle;
        String state;
        String inCall, outCall;
        public boolean wasRinging = false;

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ACTION_IN)) {
                if ((bundle = intent.getExtras()) != null) {
                    state = bundle.getString(TelephonyManager.EXTRA_STATE);
                    if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                        inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                        wasRinging = true;
                        Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
                    } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                        if (wasRinging == true) {

                            Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();

                            String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
                            File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
                            if (!sampleDir.exists()) {
                                sampleDir.mkdirs();
                            }
                            String file_name = "Record";
                            try {
                                audiofile = File.createTempFile(file_name, ".amr", sampleDir);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            String path = Environment.getExternalStorageDirectory().getAbsolutePath();

                            recorder = new MediaRecorder();
//                          recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);

                            recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
                            recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
                            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                            recorder.setOutputFile(audiofile.getAbsolutePath());
                            try {
                                recorder.prepare();
                            } catch (IllegalStateException e) {
                                e.printStackTrace();
                            } catch (IOException e) { 
                                e.printStackTrace();
                            }
                            recorder.start();
                            recordstarted = true;
                        }
                    } else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                        wasRinging = false;
                        Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
                        if (recordstarted) {
                            recorder.stop();
                            recordstarted = false;
                        }
                    }
                }
            } else if (intent.getAction().equals(ACTION_OUT)) {
                if ((bundle = intent.getExtras()) != null) {
                    outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                    Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
                }
            }
        }
    }
Pratik Dasa
  • 7,439
  • 4
  • 30
  • 44
  • 1
    if (intent.getAction().equals(ACTION_IN)) this line gives compile time error..What is ACTION_IN.Can u plz tell me. thanx – Ekanta Swain Sep 20 '13 at 07:16
  • private static final String ACTION_IN = "android.intent.action.PHONE_STATE"; private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL"; – Pratik Dasa Sep 20 '13 at 07:19
  • 1
    In else part we can only get the outgoing number as there in toast message.But how i can get the outgoing ringing state.I couldn't find here.can u plz tell me elaborately .. – Ekanta Swain Sep 20 '13 at 07:26
  • Try to do like Action_IN, both the event are same. – Pratik Dasa Sep 20 '13 at 07:28
  • Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show(); I am getting only this toast only.How i will get the ringing state mere bhai.. – Ekanta Swain Sep 20 '13 at 07:33
  • mere bhai mene reference diya...thoda apne aap bhi try karo...exactly to me nahi de sakta na – Pratik Dasa Sep 20 '13 at 08:41
  • its ok kancha, but there must be something you have to do with your own, I cant do your whole project. I hope you understand. – Pratik Dasa Sep 20 '13 at 08:54
  • The OP has asked about outgoing call states. Your answer does not solve it. – Dheeraj Bhaskar Mar 20 '14 at 20:23
-3

Try this, You can use PhoneListener extends to PhoneStateListener.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class ListenToCallState extends BroadcastReceiver {

// private LoadProfImage mProfile;
@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    // mProfile = new LoadProfImage(context);

    PhoneListener phoneListener = new PhoneListener(context);
    TelephonyManager telephony = (TelephonyManager) context
            .getSystemService(Context.TELEPHONY_SERVICE);
    telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);

}

class PhoneListener extends PhoneStateListener {
    private Context context;

    public PhoneListener(Context context) {
        // TODO Auto-generated constructor stub
        this.context = context;
    }

    public void onCallStateChanged(int state, String incomingNumber) {

        switch (state) {

        case TelephonyManager.CALL_STATE_IDLE:
                            //Do your stuff
            break;

        case TelephonyManager.CALL_STATE_RINGING:
                             //Do your stuff
            break;

        case TelephonyManager.CALL_STATE_OFFHOOK:
                              //Do your stuff
            break;

        }
    }
}

}

Murali Ganesan
  • 2,925
  • 4
  • 20
  • 31
  • I already tried it..But for out going call i want to check the state..In this code only OFFHOOK and IDLE,These state is only coming for out going call.I want the RINGING State. – Ekanta Swain Sep 20 '13 at 07:19
  • Outgoing calls also it will come for state ringing `TelephonyManager.CALL_STATE_RINGING:` – Murali Ganesan Sep 20 '13 at 07:28
  • 1
    i check ur code but TelephonyManager.CALL_STATE_RINGING this line never calls.Is there any extra functionality i have to add.? – Ekanta Swain Sep 20 '13 at 07:36
  • Actually which state you are getting now – Murali Ganesan Sep 20 '13 at 07:49
  • 3
    i am getting CALL_STATE_OFFHOOK and after phone rejecting i am getting CALL_STATE_IDLE .but never getting CALL_STATE_RINGING:. – Ekanta Swain Sep 20 '13 at 08:32
  • 1
    this code is wrong! when you use broadCastReceiver, why you use listener in it? the `onReceive` method will called when state changed! when you declare a listener on it, it may be called multiple time in that, and will have wrong result on some devices, try to give state of broadcast by `state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);` – Amir Hossein Ghasemi Oct 07 '14 at 07:31