I have been browsing a lot of code examples and questions/answers for starting a phone call from my activity, however, i can not find a way to stop that call i made.
The purpose is to make a test call for 10 seconds for example and stop it.
Have someone done this before , any ideas ?
As #milapTank guided me, to answer my question for someone else's use :
Download ITelephony.java file depending on android version.
create a package named : com.android.internal.telephony and put interface file in it.
The Code
//iTelephony
try {
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
Class cl = Class.forName(telephonyManager.getClass().getName());
Method method = cl.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephonyService = (ITelephony) Method.invoke(telephonyManager);
telephonyService.endCall();
} catch (Exception e) {
//manage exception...
}
It's working fine with
- Android Studio 1.5
- Android 4.0 As minimum SDK and android 6.0 as Target and Compile SDK.
button.setOnClickListener(this);
#Override
public void onClick(View view) {
if(view == ok){
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + num));
activity.startActivity(intent);
}
And must in the manifest:
<uses-permission android:name="android.permission.CALL_PHONE" />
..
EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
private class EndCallListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if(TelephonyManager.CALL_STATE_RINGING == state) {
Log.i(LOG_TAG, "RINGING, number: " + incomingNumber);
}
if(TelephonyManager.CALL_STATE_OFFHOOK == state) {
//wait for phone to go offhook (probably set a boolean flag) so you know your app initiated the call.
Log.i(LOG_TAG, "OFFHOOK");
}
if(TelephonyManager.CALL_STATE_IDLE == state) {
//when this state occurs, and your flag is set, restart your app
Log.i(LOG_TAG, "IDLE");
}
}
}
In the manifest :
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Related
I have made a sample app and the PhoneStateListener
TelephonyManager telephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
telephony.listen(new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.i("brian", "call state = " + state + " incoming number " + incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
break;
case TelephonyManager.CALL_STATE_RINGING:
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
}
}
}, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager
Log.i("brian", "READ_PHONE_STATE = " + ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_PHONE_STATE));
Works as expected, but when I add the above code to my much larger application the onCallStateChanged is only called when it is subscribed initially. No phone state changes are notified to me. On both projects the bottom log line "READ_PHONE_STATE = " was always granted and I'm targeting sdk 22 so no runtime permissions I think. In my larger app I have the code pasted in both the main activity and a long standing service, neither get state change events. They both work when I run my code on an android < 7.0 and I have no idea why. Don't see anything substantial in the warning or error logs.
As Vairavan mentioned in this answer, there was an internal change in how the PhoneStateListener is referenced:
Local reference to PhoneStateListener is kept track internally only by
a weak reference. This makes it eligible for garbage collection upon
function exit and once the listener is finalized, apps will not
receive any further updates. Solution is to keep a reference to
PhoneStateListener via class member variable.
See: https://github.com/aosp-mirror/platform_frameworks_base/commit/f5d7c587e86c64e657a15a12ad70e75d47c48d99#diff-5af2ac899de823cf60597e554bf67fe0.
Try registering your listener in onCreate method of your service. It's works for me.Find example code below :
private TelephonyManager tm;
#Override
public void onCreate() {
super.onCreate();
//Set listener for TelephonyManager tm.
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
tm.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING) {
Log.i(LOG_TAG,"State : RING RING");
}
if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
Log.i(LOG_TAG,"State : OFFHOOK");
}
if (state == TelephonyManager.CALL_STATE_IDLE) {
Log.i(LOG_TAG,"State : IDLE");
}
}
};
I want to receive incoming call pro-grammatically from my apps.
I tried some code but it's not working.
Below is my code for end call.
TelephonyManager tm = (TelephonyManager) ctx
.getSystemService(Context.TELEPHONY_SERVICE);
try {
if (tm == null) {
// this will be easier for debugging later on
throw new NullPointerException("tm == null");
}
tm.getClass().getMethod("endCall").invoke(tm);//answerRingingCall
} catch (Exception e) {
Log.e("sdsd", "Unable to use the Telephony Manager directly.", e);
}
}
Using this code I can able to end any of the incoming call, But when I change "endCall" to "answerRingingCall". it's not receive call from my app can you please help how to resolve this issue.
Regarding Permission I am not able to apply this permission on apps.
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
See attach screen shot.
it's showing Permission is only granted to System apps. How to resolve this.
Thanks in advance
This may help
private class CallStateListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// called when someone is ringing to this phone
Toast.makeText(ctx,
"Incoming: "+incomingNumber,
Toast.LENGTH_LONG).show();
break;
}
}
}
tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
I managed to prepare an activity when the phone is ringing. Now I need to know how to cancel this activity, when I answer the phone or I reject the call.Do I call EXTRA_STATE_IDLE or EXTRA_STATE_OFFHOOK ?
Any ideas?
Manifest
<receiver android:name=".IncomingBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
IncomingBroadcastReceiver java Class
public class IncomingBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
// If an incoming call arrives
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { //Did my work }
The above answer is completely wrong in case of outgoing calls. In Android there is no way by which one detect whether the call was actually answered (in case of outgoing calls). The moment you dial a number, the off_hook state is fired. This is one of the drawbacks of Android programming.
in your onReceive:
PhoneStateChangeListener pscl = new PhoneStateChangeListener();
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(pscl, PhoneStateListener.LISTEN_CALL_STATE);
separate class:
private class PhoneStateChangeListener extends PhoneStateListener {
public static boolean wasRinging;
String LOG_TAG = "PhoneListener";
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.i(LOG_TAG, "RINGING");
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.i(LOG_TAG, "OFFHOOK");
if (!wasRinging) {
// Start your new activity
} else {
// Cancel your old activity
}
// this should be the last piece of code before the break
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.i(LOG_TAG, "IDLE");
// this should be the last piece of code before the break
wasRinging = false;
break;
}
}
}
All you need to do is write some code to check if the previous state was 'ringing'.
If the current state is idle and the previous state was ringing, they cancelled the call.
If the current state is offhook and the previous state was ringing, they answered the call.
Following are the states which it goes through in different scenarios:
1) Answering Received call
CALL_STATE_RINGING => CALL_STATE_OFFHOOK (After Answering call) => CALL_STATE_IDLE (After End call)
2) Rejecting / Not Answering (Missed) Received call
CALL_STATE_RINGING => CALL_STATE_IDLE (After End call)
3) Dialing call
CALL_STATE_OFFHOOK (After dialing) => CALL_STATE_IDLE (After End call)
Code
int prev_state=0;
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
#Override
public void onCallStateChanged(int state, String incomingNumber){
if(incomingNumber!=null&&incomingNumber.length()>0) incoming_nr=incomingNumber;
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "CALL_STATE_RINGING");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "CALL_STATE_OFFHOOK");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_nr);
NumberDatabase database=new NumberDatabase(mContext);
if((prev_state==TelephonyManager.CALL_STATE_OFFHOOK)){
prev_state=state;
//Answered Call which is ended
}
if((prev_state==TelephonyManager.CALL_STATE_RINGING)){
prev_state=state;
//Rejected or Missed call
}
break;
}
}
}
In your receiver
onReceive(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager
Bundle bundle = intent.getExtras();
String phoneNr= bundle.getString("incoming_number");
mContext=context;
}
below is a code of detecting outgoing call by accessibility events -
Add a class which extends AccessibilityService in your projects -
public class CallDetection extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
acquireLock(this);
Log.d("myaccess","after lock");
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
Log.d("myaccess","in window changed");
AccessibilityNodeInfo info = event.getSource();
if (info != null && info.getText() != null) {
String duration = info.getText().toString();
String zeroSeconds = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(0)});
String firstSecond = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(1)});
Log.d("myaccess","after calculation - "+ zeroSeconds + " --- "+ firstSecond + " --- " + duration);
if (zeroSeconds.equals(duration) || firstSecond.equals(duration)) {
Toast.makeText(getApplicationContext(),"Call answered",Toast.LENGTH_SHORT).show();
// Your Code goes here
}
info.recycle();
}
}
}
#Override
protected void onServiceConnected() {
super.onServiceConnected();
Toast.makeText(this,"Service connected",Toast.LENGTH_SHORT).show();
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
info.notificationTimeout = 0;
info.packageNames = null;
setServiceInfo(info);
}
#Override
public void onInterrupt() {
}
}
But to get the function event.getSource() working you have to specify some of your service configuration through xml, so create a xml folder in your project and add a xml file called serviceconfig.xml (you can give any name you want.
The content of serviceconfig is below -
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="#string/callDetection"
android:accessibilityEventTypes="typeWindowContentChanged"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>
You can find more about serviceconfig in Here
Now add your service in you Manifest file like this -
<service android:name=".CallDetection"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:label="#string/callDetection">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/serviceconfig" />
</service>
And youre done, just run the app and go to Accessibility settings in your phone, you will find an option named as detection (or whatever name you have given as your service description), switch that on to give accesibility permissions for you app.
Now you will see a toast when call is answered.
you can Code any code you want in there, also you can call a callback function in your activity
Most important - Dont call your call window(android dialer window) untill the call is answered, otherwise this will not work.
Note - As android doesn't provide any solution to detect if the call is answered or not, this is the best alternative i have made, hope it works for you.
//
public class myService extends InCallService
{
// Here... :)
#Override public void onCanAddCallChanged(boolean canAddCall)
{
super.onCanAddCallChanged(canAddCall);
}
}
To detect that a call is received, you can detect a "hello" voice. "hello" voice is the frequency (voice activity) outside of Call progress Frequency. For reference you can have a look at this datasheet part: https://www.cmlmicro.com/products/call-progress-and-voice-detector/
i need to make a phone call from my application to some predefined phone number, and after some time interval, lets say 10 seconds after it starts ringing, i want to automatically terminate this call, leaving a miscall. is this possible?
i used the following code to start the phone call
try {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:"+phoneNumber);
startActivity(callIntent);
} catch (ActivityNotFoundException e) {
Log.e("helloandroid dialing example", "Call failed", e);
}
but i have no idea how to stop this particular call.
After initiating the call successfully. you can always use endCall() for disconnecting it after your desired interval of time has passed.
Read this thread and search for similar ones on this site:
https://stackoverflow.com/a/9987399/2021499
First of all,you need to initiate a call and monitor its state and then upon particular time,end the call programmatically .
You already know how to initiate the call,I have added a PhoneStateListener to monitor its state,and I have also added a code snippet which describes how to end call programmatically.
initiate the call,
private void establishCall()
{
TelephonyManager tManager = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
if (tManager .getSimState() != TelephonyManager.SIM_STATE_ABSENT)
{
try {
Intent callIntent = new Intent(Intent.ACTION_CALL).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callIntent.setData(Uri.parse("tel:"+phoneNumber));
startActivity(callIntent);
ListenToPhoneState listener = new ListenToPhoneState();
tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
} catch (Exception e) {
Log.e("Call failed", e.toString());
}
}
else
{
Toast.makeText(this, "Insert a Simcard into your device.", Toast.LENGTH_LONG).show();
}
}
here is the code of listener,
private class ListenToPhoneState extends PhoneStateListener {
boolean callEnded=false;
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
UTILS.Log_e("State changed: " , state+"Idle");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
UTILS.Log_e("State changed: " , state+"Offhook");
callEnded=true;
break;
case TelephonyManager.CALL_STATE_RINGING:
UTILS.Log_e("State changed: " , state+"Ringing");
//apply your logic here to wait for few seconds before calling killCall(this) function to end call
break;
default:
break;
}
}
}
here is the code for ending current call
public boolean killCall(Context context) {
try {
// Get the boring old TelephonyManager
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Get the getITelephony() method
Class classTelephony = Class.forName(telephonyManager.getClass().getName());
Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");
// Ignore that the method is supposed to be private
methodGetITelephony.setAccessible(true);
// Invoke getITelephony() to get the ITelephony interface
Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
// Get the endCall method from ITelephony
Class telephonyInterfaceClass =
Class.forName(telephonyInterface.getClass().getName());
Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");
// Invoke endCall()
methodEndCall.invoke(telephonyInterface);
} catch (Exception ex) { // Many things can go wrong with reflection calls
Logger.e("PhoneStateReceiver **" + ex.toString());
return false;
}
return true;
}
inside manifest following permissions will be required,
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
I hope it will be helpful !!
I managed to prepare an activity when the phone is ringing. Now I need to know how to cancel this activity, when I answer the phone or I reject the call.Do I call EXTRA_STATE_IDLE or EXTRA_STATE_OFFHOOK ?
Any ideas?
Manifest
<receiver android:name=".IncomingBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
IncomingBroadcastReceiver java Class
public class IncomingBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
// If an incoming call arrives
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { //Did my work }
The above answer is completely wrong in case of outgoing calls. In Android there is no way by which one detect whether the call was actually answered (in case of outgoing calls). The moment you dial a number, the off_hook state is fired. This is one of the drawbacks of Android programming.
in your onReceive:
PhoneStateChangeListener pscl = new PhoneStateChangeListener();
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(pscl, PhoneStateListener.LISTEN_CALL_STATE);
separate class:
private class PhoneStateChangeListener extends PhoneStateListener {
public static boolean wasRinging;
String LOG_TAG = "PhoneListener";
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.i(LOG_TAG, "RINGING");
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.i(LOG_TAG, "OFFHOOK");
if (!wasRinging) {
// Start your new activity
} else {
// Cancel your old activity
}
// this should be the last piece of code before the break
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.i(LOG_TAG, "IDLE");
// this should be the last piece of code before the break
wasRinging = false;
break;
}
}
}
All you need to do is write some code to check if the previous state was 'ringing'.
If the current state is idle and the previous state was ringing, they cancelled the call.
If the current state is offhook and the previous state was ringing, they answered the call.
Following are the states which it goes through in different scenarios:
1) Answering Received call
CALL_STATE_RINGING => CALL_STATE_OFFHOOK (After Answering call) => CALL_STATE_IDLE (After End call)
2) Rejecting / Not Answering (Missed) Received call
CALL_STATE_RINGING => CALL_STATE_IDLE (After End call)
3) Dialing call
CALL_STATE_OFFHOOK (After dialing) => CALL_STATE_IDLE (After End call)
Code
int prev_state=0;
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
#Override
public void onCallStateChanged(int state, String incomingNumber){
if(incomingNumber!=null&&incomingNumber.length()>0) incoming_nr=incomingNumber;
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "CALL_STATE_RINGING");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "CALL_STATE_OFFHOOK");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_nr);
NumberDatabase database=new NumberDatabase(mContext);
if((prev_state==TelephonyManager.CALL_STATE_OFFHOOK)){
prev_state=state;
//Answered Call which is ended
}
if((prev_state==TelephonyManager.CALL_STATE_RINGING)){
prev_state=state;
//Rejected or Missed call
}
break;
}
}
}
In your receiver
onReceive(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager
Bundle bundle = intent.getExtras();
String phoneNr= bundle.getString("incoming_number");
mContext=context;
}
below is a code of detecting outgoing call by accessibility events -
Add a class which extends AccessibilityService in your projects -
public class CallDetection extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
acquireLock(this);
Log.d("myaccess","after lock");
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
Log.d("myaccess","in window changed");
AccessibilityNodeInfo info = event.getSource();
if (info != null && info.getText() != null) {
String duration = info.getText().toString();
String zeroSeconds = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(0)});
String firstSecond = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(1)});
Log.d("myaccess","after calculation - "+ zeroSeconds + " --- "+ firstSecond + " --- " + duration);
if (zeroSeconds.equals(duration) || firstSecond.equals(duration)) {
Toast.makeText(getApplicationContext(),"Call answered",Toast.LENGTH_SHORT).show();
// Your Code goes here
}
info.recycle();
}
}
}
#Override
protected void onServiceConnected() {
super.onServiceConnected();
Toast.makeText(this,"Service connected",Toast.LENGTH_SHORT).show();
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
info.notificationTimeout = 0;
info.packageNames = null;
setServiceInfo(info);
}
#Override
public void onInterrupt() {
}
}
But to get the function event.getSource() working you have to specify some of your service configuration through xml, so create a xml folder in your project and add a xml file called serviceconfig.xml (you can give any name you want.
The content of serviceconfig is below -
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="#string/callDetection"
android:accessibilityEventTypes="typeWindowContentChanged"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>
You can find more about serviceconfig in Here
Now add your service in you Manifest file like this -
<service android:name=".CallDetection"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:label="#string/callDetection">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/serviceconfig" />
</service>
And youre done, just run the app and go to Accessibility settings in your phone, you will find an option named as detection (or whatever name you have given as your service description), switch that on to give accesibility permissions for you app.
Now you will see a toast when call is answered.
you can Code any code you want in there, also you can call a callback function in your activity
Most important - Dont call your call window(android dialer window) untill the call is answered, otherwise this will not work.
Note - As android doesn't provide any solution to detect if the call is answered or not, this is the best alternative i have made, hope it works for you.
//
public class myService extends InCallService
{
// Here... :)
#Override public void onCanAddCallChanged(boolean canAddCall)
{
super.onCanAddCallChanged(canAddCall);
}
}
To detect that a call is received, you can detect a "hello" voice. "hello" voice is the frequency (voice activity) outside of Call progress Frequency. For reference you can have a look at this datasheet part: https://www.cmlmicro.com/products/call-progress-and-voice-detector/