The purpose of the code is to drop any incoming call. I am achieving this using a service which is started by the main activity. The service runs a simple code in new thread. The service is given below.
I've included all the necessary commenting but a brief explanation of what is happening is that the service starts a thread, the thread's run() function uses a TelephonyManager to register a listener to listen for any changes in phone state i.e. ringing, idle or in call. The run() has checks that stop the function whenever the bool 'running' is set to false thus effectively ending the thread.
The main activity has two buttons, one to start the service and the other to end it. The code works such that when the service is started any incoming call is dropped but the problem is that even once I've stopped the service using stopService() from the main activity, the thread continues to keep working(dropping any incoming calls). The thread stops on when the main activity is force shut(onDestroy() of main activity is called).
Can anyone explain why that is so??? Why does the thread not stop working when it's bool 'running' is set to false in the onDestroy() of the service ???
I've included all the necessary commenting but a brief explanation of what is happening is that the service starts a thread, the thread's run() function uses a TelephonyManager to register a listener to listen for any changes in phone state i.e. ringing, idle or in call. The run() has checks that stop the function whenever the bool 'running' is set to false thus effectively ending the thread.
Java:
public class Service_2 extends Service{
//Obj of THREAD, a class that extends Thread and implements the required run() function. Implemented at the end.
THREAD thread;
//Handler for handling msg sent from the thread; displays the msg sent using a toast
public Handler serviceHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Bundle bundle = msg.getData();
String string = bundle.getString("KEY");
Toast.makeText(Service_2.this, string, Toast.LENGTH_SHORT).show();
}
};
//No support for binding.
@Override
public IBinder onBind(Intent intent) {
return null;
}
//Simple toast to let the user know that the service has been created.
@Override
public void onCreate() {
Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
}
//Initiates the obj of THREAD class and starts the execution in a new thread.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
thread = new THREAD(this, serviceHandler);
thread.start();
return START_STICKY;
}
//Simple toast to let the user know that the service has been created.
//Also sets the boolean 'running' to false to stop the execution of the thread(Supposedly).
@Override
public void onDestroy() {
thread.running = false;
Toast.makeText(this,"Service Destroyed", Toast.LENGTH_SHORT).show();
}
}
class CallStateListener extends PhoneStateListener {
String number;
Handler extraHandler;
CallStateListener(Handler handler) {
extraHandler = handler;
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
//Store is number of the incoming call
number = incomingNumber;
//If phone is ringing
if (state == TelephonyManager.CALL_STATE_RINGING) {
Message msg = extraHandler.obtainMessage();
Bundle bundle = new Bundle();
String string = "Phone is Ringing";
bundle.putString("KEY",string);
msg.setData(bundle);
extraHandler.sendMessage(msg);
disconnectCallAndroid();
}
//If incoming call received
if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
Message msg = extraHandler.obtainMessage();
Bundle bundle = new Bundle();
String string = "Phone is Currently in a call";
bundle.putString("KEY",string);
msg.setData(bundle);
extraHandler.sendMessage(msg);
}
//If not ringing or idle
if (state == TelephonyManager.CALL_STATE_IDLE) {
Message msg = extraHandler.obtainMessage();
Bundle bundle = new Bundle();
String string = "Phone is neither Ringing nor in a call";
bundle.putString("KEY",string);
msg.setData(bundle);
extraHandler.sendMessage(msg);
}
}
//Function to disconnect call courtesy of Naeem Akram(http://aprogrammersday.blogspot.com)
public int disconnectCallAndroid()
{
Runtime runtime = Runtime.getRuntime();
int nResp = 0;
try
{
Log.d(Constants.LOGTAG, "service call phone 5 \n");
runtime.exec("service call phone 5 \n");
}catch(Exception exc)
{
Log.e(Constants.LOGTAG, exc.getMessage());
exc.printStackTrace();
}
return nResp;
}
}
//Thread is which the background operation on the service is performed
class THREAD extends Thread {
CallStateListener callStateListener;
Context threadContext;
Handler handler;
public boolean running;
THREAD(Context context, Handler handler) {
running = true;
threadContext = context;
this.handler = handler;
}
@Override
public void run() {
Looper.prepare();
if (!running) return;
TelephonyManager telephonyManager = (TelephonyManager) threadContext.getSystemService(Context.TELEPHONY_SERVICE);
callStateListener = new CallStateListener(handler);
if (!running) return;
telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
if (!running) return;
Looper.loop();
if (!running) return;
}
}
The main activity has two buttons, one to start the service and the other to end it. The code works such that when the service is started any incoming call is dropped but the problem is that even once I've stopped the service using stopService() from the main activity, the thread continues to keep working(dropping any incoming calls). The thread stops on when the main activity is force shut(onDestroy() of main activity is called).
Can anyone explain why that is so??? Why does the thread not stop working when it's bool 'running' is set to false in the onDestroy() of the service ???