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);
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 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"/>
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 have audio recording, when a phone call come I need to stop the recording, how can I do this?
You have to use the PhoneStateListener:
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
tm.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
// somewhere else
private PhoneStateListener mPhoneListener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber) {
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// do something...
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// do something...
break;
case TelephonyManager.CALL_STATE_IDLE:
// do something...
break;
default:
Log.d(TAG, "Unknown phone state=" + state);
}
} catch (RemoteException e) {}
}
};
Make sure to include this permission in your Manifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
I've never tried to access the phone stuff on Android but check here -
http://developer.android.com/reference/android/telephony/package-summary.html
and here -
http://developer.android.com/reference/android/telephony/PhoneStateListener.html
and here -
http://developer.android.com/reference/android/telephony/TelephonyManager.html
I would like to get only active calls from PhoneStateListener.
I have created the listener with method onCallStateChanged.
Once I dial (and the call is picked up) the state is already off-hook.
Well, it doesn't really surprise me, because of the text in the API:
Device call state: Off-hook. At least one call exists that is dialing, active, or on hold, and no calls are ringing or waiting.
But is there a possibility to get only active calls?
From what I tried on my nexus one, active call wake CALL_STATE_OFFHOOK,
try use log file to watch the steps.
Try this ..
private PhoneStateListener mPhoneListener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "ringing goes here");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "Active call goes here");
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL STATE IDLE goes here");
break;
default:
Log.d(TAG, "Unknown state=" + state);
}
}
and then call it :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
tm.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
Don't forget add permission to your Mainifest file:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>