I'm having problem in phone state listener. I want to call one activity from onCallStateChanged event. When i get an incoming call i want to call one activity and process the transaction of the current phone no(which i currently get by incoming call).
But i couldn't go to ShowPhoneStateDialogActivity activity using following code.Please correct me what is my mistake. Thanks in advance.
My code is,
case TelephonyManager.CALL_STATE_RINGING:
Log.d("PHONE:", "RINGING");
Log.w("Call STATE:", "RINGING");
if (!sess.getCallActive()) {
sess.setCallActive(true);
sess.setActiveMobileNo(incomingCallNumber);
this.endActivecall();
Intent intent = new Intent(context,ShowPhoneStateDialogActivity.class).setAction("incomingNumber");
intent.putExtra("Phoneno", incomingCallNumber);
Log.i("CURRENT ACTIVITY",this.getClass().getSimpleName());
Log.i("CURRENT CONTEXT","Context:"+context);
//intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(intent);
break;
} else {
this.endActivecall();
}
break;
And endActivecall function is,
public void endActivecall() {
TelephonyManager telephony = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(telephony);
// telephonyService.silenceRinger();
telephonyService.endCall();
Log.i("CALL STATE ACTION:", "Call end");
Log.i("ACTIVE_MOBILENO:", sess.getActiveMobileNo());
} catch (Exception e) {
e.printStackTrace();
}
Instead of the code context.startService(intent), try calling context.startActivity(intent) instead.
Related
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 making a phone call cancel app. Basically it cancel a upcoming call if your phone is in back position in table or ground (Accelerometer Data). I make a Broadcast Receiver and entry it on the manifest also gave action this android.intent.action.PHONE_STATE
public class PhoneCallReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Intent si=new Intent(context, MyService.class);
context.startService(si);
TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(telephony);
//telephonyService.silenceRinger();
telephonyService.endCall();
Log.e("in try catch", "yes");
Log.e("in try catch", "call cancel");
shrededit.putInt("newcallingstate", 0);
shrededit.commit();
context.stopService(si);
} catch (Exception e) {
e.printStackTrace();
}
Log.e("pr", "out side true block");
}
}
My code is running very well if i only use this code without the accelerometer service class but when i use accelerometer class and make a intent before this below code. My app not canceling the call or not giving any type or error. I think it but not completely sure it is context problem.
So please help me.
No,its not context problem all this code is perfectly fine you does just need a condition or use sharedpreferences for condition.
first make a sharedpreferences object in your service class or that which you show in intent. like this
SharedPreferences sharedpref=this.getSharedPreferences("your_file_name",Context.MODE_PRIVATE);
SharedPreferences.Editor sharededit=sharedpref.edit();
sharededit.putBoolean("String_name", true);
sharededit.commit();
Here boolean is not important you can choose and other data type it depends you.
Then in you Broadcast receiver class you have to again use these SharedPreference and SharedPreference.Editor function and you get the previous boolean value by this method
boolean value=sharededit.getBoolean("callingStop", true);
Than make a condition like this
if(value==true){TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(telephony);
//telephonyService.silenceRinger();
telephonyService.endCall();
} catch (Exception e) {
e.printStackTrace();
} }
This is all now your code is run without any error.
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 am catching the android.intent.action.PHONE_STATE change event by using following code snippet with android BroadCastReceiver. I could recognize the event successfully and handle the incoming calls also can be done by following code.
My requirement is identifying calls which are coming form a particular number, end that call through the code and invoke a web service for that incoming event.
In here this code runs twice for call receiving and ending events.
I want to stop calling this method for twice. How can i stop calling that code snippet for the second event (ending the call). It would be great-full if any one can help me on this.
if (intent.getAction().equals(
"android.intent.action.PHONE_STATE")) {
Log.i("INFO", "Call Received");
try {
TelephonyManager telephony = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
Bundle bundle = intent.getExtras();
Log.i("Calling database", "Creatinng DataHandler Object");
DatabaseHandler db = new DatabaseHandler(context);
String phoneNumber =db.getContact().getPhoneNumber();
Log.i("Retriving : ", "Retriving .."+ db.getContact().getPhoneNumber());
if ((bundle.getString("incoming_number").equals(phoneNumber))) {
Log.i("Test Call", "This is the test call");
#SuppressWarnings("rawtypes")
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
ITelephony telephonyService = (ITelephony) m
.invoke(telephony);
telephonyService = (ITelephony) m.invoke(telephony);
telephonyService.endCall();
// Call the web service and send log details
ServiceClient sc = new ServiceClient();
sc.serviceCall(context);
} else {
Log.i("Normal Call", "This is not the test call");
}
} catch (Exception e) {
Log.i("Exception Occured", "Exception in call code snipet");
}
}
}
I believe the issue you are having is that the phone state changes twice, once when the phone rings, then, after you end the call, when the phone goes idle.
You only want this code to run once so the best way to do that is to add an additional check of the phone state to see if it is ringing, if the phone is ringing then end the call.
This can be accomplished by adding the following the check:
if (intent.getAction().equals(
"android.intent.action.PHONE_STATE")) {
Log.i("INFO", "Call Received");
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
//your code here that starts with try block
}
Hope that helps
you can try doing something like this as soon as the receiver starts:
Bundle bundle = nIntent.getExtras();
String phoneNr= bundle.getString("incoming_number");
if(null == phoneNr)
{ // this is outgoing call so bail out
return;
}
You cannot terminate incoming call using third party application due to android security reason. Check in "android application development cookbook" page number "164 "
I know it's too late but I found a batter solution for this.
This normally happens on 5.0 and 5.1. You cannot stop it from calling twice but you can have a universal check to do all your work at one point. And this solution universally work on all OS.
Here is the code
public void onReceive(Context context, Intent intent) {
Object obj = intent.getExtras().get("subscription");
long subId;
if(obj == null) {
subId = Long.MIN_VALUE; // subscription not in extras
} else {
subId = Long.valueOf(obj.toString()); // subscription is long or int
}
if(subId < Integer.MAX_VALUE) {
// hurray, this is called only once on all operating system versions!
}}
for more info check this link.
i have used the following code:
Problem: It is working fine and blocking incoming call but phone ring for fraction of a second before disconnect the call. can there be a solution which i am looking for .
public class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle b = intent.getExtras();
incomingNumber1 = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
TelephonyManager telephony = (TelephonyManager)context
.getSystemService(Context.TELEPHONY_SERVICE);
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(telephony);
telephonyService.endCall();
}}
I have not found the answer to the problem yet. I want solution which work perfectly on Android 2.3. Incoming call is to be blocked fully there must not any ring.