I want to detect when the outgoing call has started and ended, and want to start an service when call has started and end the service when call has ended.
Here's the code i got from another question, but don't know where to put the start and stop activity to make it work.
public class CallListener {
private CallStateListener callStateListener = null;
private OutgoingReceiver outgoingReceiver = null;
public CallListener(Context context) {
this.context = context;
callStateListener = new CallStateListener();
outgoingReceiver = new OutgoingReceiver();
}
private class CallStateListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
doSomething1();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
doSomething2();
break;
case TelephonyManager.CALL_STATE_RINGING:
doSomething3();
break;
}
}
}
public class OutgoingReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
doSomething4();
}
}
public void start() {
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
context.registerReceiver(outgoingReceiver, intentFilter);
}
public void stop() {
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
context.unregisterReceiver(outgoingReceiver);
}}
And here's to add in the service to make it work:
public class MyService extends Service {
private CallListener call = null;
public MyService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
call = new CallListener(getApplicationContext());
call.start();
return(START_STICKY);
}
#Override
public void onDestroy() {
call.stop();
call.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Thanks so much for any help, i may know that this is easy but i just don't know.
Thanks and have a really good day..!! :)
I had already searched how to detect call events like ringing / idle / etc... no success :(
Unfortunately, there is no solution in Android at this time...
This is well explained in this previous question/summary post:
Detecting outgoing call answered on Android
Related
I am working on an application where i need to finish the activity from onResume if there is an incoming call. I have created a CallHelper class where i am detecting any incoming call using PhoneStateListener.
public class CallHelper {
/**
* Listener to detect incoming calls.
*/
private static class CallStateListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
System.out.println("RINGING");
OverlayActivity overlayActivity = OverlayActivity.getInstance();
overlayActivity.finish();
System.out.println("Activity has been closed!!");
break;
}
}
}
/**
* Broadcast receiver to detect the outgoing calls.
*/
public class OutgoingReceiver extends BroadcastReceiver {
public OutgoingReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(ctx,
"Outgoing: "+number,
Toast.LENGTH_LONG).show();
}
}
private Context ctx;
private TelephonyManager tm;
private CallStateListener callStateListener;
private OutgoingReceiver outgoingReceiver;
public CallHelper(Context ctx) {
this.ctx = ctx;
callStateListener = new CallStateListener();
outgoingReceiver = new OutgoingReceiver();
}
/**
* Start calls detection.
*/
public void start() {
tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
ctx.registerReceiver(outgoingReceiver, intentFilter);
}
/**
* Stop calls detection.
*/
public void stop() {
tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
ctx.unregisterReceiver(outgoingReceiver);
}
}
I need to detect inside onResume, if there is any call, i need to finish the activity if not i don't need to do anything.
I haven't found the solution yet, so what i did is, i have added the code for detecting the CallStateChange inside my Activity's onResume and using that code i am executing the task which i want to execute on CallStateChange.
I am not sure if this is a correct solution or not, but would be expecting views on the same from the community.
Here's the code which i am using:
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener callStateListener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber)
{
if(state==TelephonyManager.CALL_STATE_RINGING){
// Code i wanted to execute
}
}
};
telephonyManager.listen(callStateListener,PhoneStateListener.LISTEN_CALL_STATE);
I need my app to find out when a phone call is taking place.
It should work on when another phone is being called and also when a call is answered. I just need my app to get notified of exactly when the connection starts and when it stops (not the dialing, ringing, etc.).
Is this somehow possible?
You can use broadcast class to achieve this as below:
public class PhoneStateBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(new CustomPhoneStateListener(context),
PhoneStateListener.LISTEN_CALL_STATE);
}
}
class CustomPhoneStateListener extends PhoneStateListener {
// private static final String TAG = "PhoneStateChanged";
Context context; // Context to make Toast if required
public CustomPhoneStateListener(Context context) {
super();
this.context = context;
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
//WHEN PHONE WILL BE IDLE
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// when Off hook i.e in call
break;
case TelephonyManager.CALL_STATE_RINGING:
// when Ringing
break;
default:
break;
}
}
}
Hope this will help you.
I need a way to get the the status when a outgoing call is answered. However, in the OFFHOOK state I am also using to call for the outgoing call(ACTION_CALL). How can I add the awnsered state without overriding the outgoing call activity?
public class OutgoingBroadcastReceiver extends BroadcastReceiver {
private Intent mIntent;
private String phonenumber = null;
public static boolean wasRinging;
#Override
public void onReceive(Context context, Intent intent) {
mIntent = intent;
MyPhoneStateListener phoneListener = new MyPhoneStateListener(context);
TelephonyManager telephony = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
phonenumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}
public class MyPhoneStateListener extends PhoneStateListener {
private final Context context;
public MyPhoneStateListener(Context context) {
this.context = context;
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.e("%%%%%%%%%%%%%%%%%%%%%%%%%%%t", "OFFHOOK");
if (UIUDialer.isOutgoingCall() == true) {
//Do my work when outgoing call is detected
}
else if (!wasRinging)
{
Log.e("%%%%%%%%%%%%%%%%%%%%%%%%%%%t", "WASRINGING");
//Do my work when outgoing call is awnsered
}
context.sendBroadcast(new Intent("finish_incoming"));
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_RINGING:
wasRinging = true;
break;
}
}
}
}
There is no public API available for this.
Why don't you just use the boolean wasRinging?
(you'll have to make it static and remove the initialization, though)
I am writing a simple app to keep track of the periods when my phone has poor signal strength. I do this using an IntentService, which listens for PhoneStateListener.LISTEN_SIGNAL_STRENGTHS as follows:
public class PoorSignalIntentService extends IntentService {
private TelephonyManager mTelephonyManager;
private PhoneStateListener mPhoneStateListener;
public PoorSignalIntentService() {
super("PoorSignalIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
mPhoneStateListener = new PhoneStateListener(){
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
doSomething(signalStrength);
super.onSignalStrengthsChanged(signalStrength);
}
#Override
public void onServiceStateChanged(ServiceState serviceState) {
doSomething(serviceState);
super.onServiceStateChanged(serviceState);
}
};
mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS|PhoneStateListener.LISTEN_SERVICE_STATE);
}
private void doSomething(SignalStrength signalStrength){
Log.d(TAG, "Signal Strength changed! New strength = "+signalStrength.getGsmSignalStrength());
}
private void doSomething(ServiceState serviceState){
Log.d(TAG, "Service State changed! New state = "+serviceState.getState());
}
#Override
public void onDestroy() {
Log.d(TAG, "Shutting down the IntentService");
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
super.onDestroy();
}
}
However, I see that after the first signal strength changed notification is received, the onDestroy() is called (presumably, the IntentService calls stopSelf()).
This problem is not limited to PhoneStateListener. I have another simple app which uses the Proximity Sensor thus:
#Override
protected void onHandleIntent(Intent intent){
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
}
In this case too, only the first proximity change was notified, after which the Service stopped itself.
So, what is the pattern for registering listeners like these in a Service?
Ok, I found the solution. My bad. I should be using a Service rather than IntentService, since the latter calls stopSelf() after processing the intents it receives in onHandleIntent().
Here's the working code which extends Service:
public class PoorSignalService extends Service {
private TelephonyManager mTelephonyManager;
private PhoneStateListener mPhoneStateListener;
#Override
public IBinder onBind(Intent intent) {
// We don't want to bind; return null.
return null;
}
#Override
public void onCreate() {
mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
mPhoneStateListener = new PhoneStateListener(){
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
doSomething(signalStrength);
super.onSignalStrengthsChanged(signalStrength);
}
#Override
public void onServiceStateChanged(ServiceState serviceState) {
doSomething(serviceState);
super.onServiceStateChanged(serviceState);
}
};
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Register the listener here.
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS|PhoneStateListener.LISTEN_SERVICE_STATE);
return super.onStartCommand(intent, flags, startId);
}
private void doSomething(SignalStrength signalStrength){
Log.d(TAG, "Signal Strength changed! New strength = "+signalStrength.getGsmSignalStrength());
}
private void doSomething(ServiceState serviceState){
Log.d(TAG, "Service State changed! New state = "+serviceState.getState());
}
#Override
public void onDestroy() {
Log.d(TAG, "Shutting down the Service");
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
super.onDestroy();
}
}
This is my BroadcastReceiver
public class PlayAudio extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(new CustomPhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE);
}
}
This is my Custom PhoneStateListener Class
public class CustomPhoneStateListener extends PhoneStateListener {
Context context;
public CustomPhoneStateListener(Context context) {
super();
this.context = context;
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.d("PHONEA", "IDLE");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("PHONEA", "OFFHOOK");
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("PHONEA", "RINGING");
Intent intent = new Intent(this.context, AudioService.class);
context.startService(intent);
break;
default:
break;
}
}
}
and this is my service
public class AudioService extends Service{
private static final String TAG = "PHONEA";
MediaPlayer player;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate -> TODO");
}
}
My question is that every time I receive data in Broadcast receiver I create a new instance of the TelephonyManager. So when I view the logcat the first time I get "RINGING", the second time "RINGING" "RINGING" and so on. When should I create my telephonylistener in order to have only one instance?
Regards,
Nicos
You are getting call on your receiver(Asssuming you are listening for PhoneState) every time the phone state change.
You should put some check in your receiver and instatiate the TelephonyManager for the first time only.