I need to end the call after the ring has been made (kind of like a missed call). I used BroadcastReceiver and PhoneStateListener to monitor the states.
The problem is I'm receiving a broadcast and also the phonenumber, and the listener works well - it goes inside the switch and executes the case intended, but it doesn't execute the endCall method of the ITelephony interface. Here's my code:
Manifest:
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<receiver
android:name=".EndCall"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
EndCall.java
public class EndCall extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("Debug", "Received a broadcast...");
String phonenumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i("Debug", "Phone number: " + phonenumber);
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
EndCallListener callListener = new EndCallListener(context, tm);
tm.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
EndCallListener.java:
public class EndCallListener extends PhoneStateListener {
Context context;
TelephonyManager tm;
public EndCallListener(Context context, TelephonyManager tm) {
this.context = context;
this.tm = tm;
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.i("Debug", "OFFHOOK");
try {
Log.i("Debug", "Inside try...");
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
ITelephony telephonyService = (ITelephony) m.invoke(tm);
//nothing happens after this...
if(telephonyService.endCall()) {
Log.i("Debug", "Call ended...");
} else {
Log.i("Debug", "Call not ended...");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.i("Debug", "IDLE");
break;
}
}
}
ITelephony.aidl
package com.android.internal.telephony;
interface ITelephony {
boolean endCall();
void answerRingingCall();
void silenceRinger();
}