Hang up and reject incoming calls via custom activities [button] Android
I
just started learning Android and I stumbled upon this issue.
I want to do a “custom call screen”. My current solution is a class extended from BroadcastReceiver (IncomingCallInterceptor). In the IncomingCallInterceptor class, I override onReceive and start my activity (MainActivity) with layout when the phone rings.
In this activity, I have three buttons:
Answer, hang up, reject calls
These buttons should do what they say, answer, hang up, or decline.
I somehow got answering the call to work, but didn’t hang up and refuse.
Here’s my code:
list :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.uppgift.six.one.incoming61.sixone" >
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="IncomingCallInterceptor">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
<activity
android:name=". MainActivity"
android:label="@string/app_name" >
</activity>
</application>
</manifest>
IncomingCallInterceptor: extended from BroadcastReceiver
public class IncomingCallInterceptor extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Context appContext = context.getApplicationContext();
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String msg = "Phone state changed to " + state;
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
String incomingNumber = intent.getStringExtra
(TelephonyManager.EXTRA_INCOMING_NUMBER);
msg += ". Incoming number is this " + incomingNumber;
START MY ACTIVITY!
Intent i = new Intent(appContext, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
appContext.startActivity(i);
}
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}
Here’s my Activity (there’s nothing to post in Layout, it’s basically three buttons).
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnAnswer = (Button)findViewById(R.id.btnAnswer);
Button btnDecline= (Button)findViewById(R.id.btnDecline);
Button btnHangUp= (Button)findViewById(R.id.btnHangUp);
btnAnswer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(i, null);
}
});
btnDecline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Decline Call (I need help here)
}
});
btnHangUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Hang Up Call (I need help here)
}
});
}
In the MainActivity class, it’s marked with comments where I need help.
I also saw some information about the Interfacey solution, but I didn’t understand how it worked when I tested it.
Solution
Reject an incoming call:
try {
TelephonyManager tm = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm); Get the internal ITelephony object
c = Class.forName(telephonyService.getClass().getName()); Get its class
m = c.getDeclaredMethod("endCall"); Get the "endCall()" method
m.setAccessible(true); Make it accessible
m.invoke(telephonyService); invoke endCall()
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
}
}