I noticed in the class TelephonyManager there are CALL_STATE_IDLE, CALL_STATE_OFFHOOK and CALL_STATE_RINGING. They seem to be used for incoming calls.
What I actually want to do is to be notified when an outgoing call is made, is received, or timed out. How to do that?
I don't know if you can detect a timed call, but differentiate when the call started is possible.
You can do it like this, in the CALL_STATE_IDLE:
Uri allCalls = Uri.parse("content://call_log/calls");
String lastMinute = String.valueOf(new Date().getTime() - DAY_IN_MILISECONDS);
//before the call started
Cursor c = app.getContentResolver().query(allCalls, null, Calls.DATE + " > "
+ lastMinute, null, Calls.DATE + " desc");
c.moveToFirst();
if (c.getCount() > 0) {
int duration = Integer.parseInt(c.getString(c.getColumnIndex(Calls.DURATION)));
}
if duration is > 0 then then it call was answered.
Obviously there are other flags that you should use to determine that CALL_STATE_IDLE is called after a call was made.
Hope that helps and put you in the corret way for what you are trying to do.
From what I understand, you can detect that an outgoing call has been initiated because the phone state changes from idle to offhook. However, from there, knowing the state of that call- ie knowing if the call you are placing is ringing, being transferred to voice mail, actually picked up or just timed out appears to be something that we cannot detect.
Now I'm not sure if it is just undetectable in the SDK, but is communicated over the network and possibly detectable from the radio receiver itself, or if that information just plain isn't being transmitted.
The minimum that is need to do is:
public class CallCounter extends PhoneStateListener {
public void onCallStateChanged(int state, String incomingNumber) {
switch(state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.d("Tony","Outgoing Call finished");
// Call Finished -> stop counter and store it.
callStop=new Date().getTime();
context.stopService(new Intent(context,ListenerContainer.class));
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("Tony","Outgoing Call Starting");
// Call Started -> start counter.
// This is not precise, because it starts when calling,
// we can correct it later reading from call log
callStart=new Date().getTime();
break;
}
}
public class ListenerContainer extends Service {
public class LocalBinder extends Binder {
ListenerContainer getService() {
return ListenerContainer.this;
}
}
#Override
public void onStart(Intent intent, int startId) {
TelephonyManager tManager =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
CallCounter callCounter=new CallCounter(this);
tManager.listen(callCounter,PhoneStateListener.LISTEN_CALL_STATE);
Log.d("Tony","Call COUNTER Registered");
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients. See
// RemoteService for a more complete example.
private final IBinder mBinder = new LocalBinder();
}
public class myReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
context.startService(new Intent(context,ListenerContainer.class));
}
}
}
Related
I managed to prepare an activity when the phone is ringing. Now I need to know how to cancel this activity, when I answer the phone or I reject the call.Do I call EXTRA_STATE_IDLE or EXTRA_STATE_OFFHOOK ?
Any ideas?
Manifest
<receiver android:name=".IncomingBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
IncomingBroadcastReceiver java Class
public class IncomingBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
// If an incoming call arrives
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { //Did my work }
The above answer is completely wrong in case of outgoing calls. In Android there is no way by which one detect whether the call was actually answered (in case of outgoing calls). The moment you dial a number, the off_hook state is fired. This is one of the drawbacks of Android programming.
in your onReceive:
PhoneStateChangeListener pscl = new PhoneStateChangeListener();
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(pscl, PhoneStateListener.LISTEN_CALL_STATE);
separate class:
private class PhoneStateChangeListener extends PhoneStateListener {
public static boolean wasRinging;
String LOG_TAG = "PhoneListener";
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.i(LOG_TAG, "RINGING");
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.i(LOG_TAG, "OFFHOOK");
if (!wasRinging) {
// Start your new activity
} else {
// Cancel your old activity
}
// this should be the last piece of code before the break
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.i(LOG_TAG, "IDLE");
// this should be the last piece of code before the break
wasRinging = false;
break;
}
}
}
All you need to do is write some code to check if the previous state was 'ringing'.
If the current state is idle and the previous state was ringing, they cancelled the call.
If the current state is offhook and the previous state was ringing, they answered the call.
Following are the states which it goes through in different scenarios:
1) Answering Received call
CALL_STATE_RINGING => CALL_STATE_OFFHOOK (After Answering call) => CALL_STATE_IDLE (After End call)
2) Rejecting / Not Answering (Missed) Received call
CALL_STATE_RINGING => CALL_STATE_IDLE (After End call)
3) Dialing call
CALL_STATE_OFFHOOK (After dialing) => CALL_STATE_IDLE (After End call)
Code
int prev_state=0;
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
#Override
public void onCallStateChanged(int state, String incomingNumber){
if(incomingNumber!=null&&incomingNumber.length()>0) incoming_nr=incomingNumber;
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "CALL_STATE_RINGING");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "CALL_STATE_OFFHOOK");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_nr);
NumberDatabase database=new NumberDatabase(mContext);
if((prev_state==TelephonyManager.CALL_STATE_OFFHOOK)){
prev_state=state;
//Answered Call which is ended
}
if((prev_state==TelephonyManager.CALL_STATE_RINGING)){
prev_state=state;
//Rejected or Missed call
}
break;
}
}
}
In your receiver
onReceive(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager
Bundle bundle = intent.getExtras();
String phoneNr= bundle.getString("incoming_number");
mContext=context;
}
below is a code of detecting outgoing call by accessibility events -
Add a class which extends AccessibilityService in your projects -
public class CallDetection extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
acquireLock(this);
Log.d("myaccess","after lock");
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
Log.d("myaccess","in window changed");
AccessibilityNodeInfo info = event.getSource();
if (info != null && info.getText() != null) {
String duration = info.getText().toString();
String zeroSeconds = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(0)});
String firstSecond = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(1)});
Log.d("myaccess","after calculation - "+ zeroSeconds + " --- "+ firstSecond + " --- " + duration);
if (zeroSeconds.equals(duration) || firstSecond.equals(duration)) {
Toast.makeText(getApplicationContext(),"Call answered",Toast.LENGTH_SHORT).show();
// Your Code goes here
}
info.recycle();
}
}
}
#Override
protected void onServiceConnected() {
super.onServiceConnected();
Toast.makeText(this,"Service connected",Toast.LENGTH_SHORT).show();
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
info.notificationTimeout = 0;
info.packageNames = null;
setServiceInfo(info);
}
#Override
public void onInterrupt() {
}
}
But to get the function event.getSource() working you have to specify some of your service configuration through xml, so create a xml folder in your project and add a xml file called serviceconfig.xml (you can give any name you want.
The content of serviceconfig is below -
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="#string/callDetection"
android:accessibilityEventTypes="typeWindowContentChanged"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>
You can find more about serviceconfig in Here
Now add your service in you Manifest file like this -
<service android:name=".CallDetection"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:label="#string/callDetection">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/serviceconfig" />
</service>
And youre done, just run the app and go to Accessibility settings in your phone, you will find an option named as detection (or whatever name you have given as your service description), switch that on to give accesibility permissions for you app.
Now you will see a toast when call is answered.
you can Code any code you want in there, also you can call a callback function in your activity
Most important - Dont call your call window(android dialer window) untill the call is answered, otherwise this will not work.
Note - As android doesn't provide any solution to detect if the call is answered or not, this is the best alternative i have made, hope it works for you.
//
public class myService extends InCallService
{
// Here... :)
#Override public void onCanAddCallChanged(boolean canAddCall)
{
super.onCanAddCallChanged(canAddCall);
}
}
To detect that a call is received, you can detect a "hello" voice. "hello" voice is the frequency (voice activity) outside of Call progress Frequency. For reference you can have a look at this datasheet part: https://www.cmlmicro.com/products/call-progress-and-voice-detector/
I'm developing on android framework,
I want to fire an event when an outgoing call is received by the callee , and also when the call is ended (from any of the two sides)
Inorder to know wheter the calling party has recieved the call, you will need to create a listener.
class PhoneInfo extends BroadcastReceiver {
/**
* Getting the System Telephony Service and registering a listener for Voice Call state
*/
#Override
public void onReceive(Context context, Intent intent) {
IncomingCallListener phoneListener = new IncomingCallListener();
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
class IncomingCallListener extends PhoneStateListener {
public void onCallStateChanged(int state, String incomingNumber) {
Log.i(logcat,"CALL_STATE changed " + callflag);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.i(logcat,"CALL_STATE_IDLE");
//This is where call ends.
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//This is where we know call is established
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.i(logcat,"CALL_STATE_RINGING");
break;
}
}
}
Register this with your activity as
phoneInfo = new PhoneInfo(this);
registerReceiver(phoneInfo, new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL));
Now with Logs u can see how states are changed when a call is dialed or received.
In the OnReceive method I have something like this:
Bundle bundle=intent.getExtras();
String phonenumber=intent.getStrngExtra(Intent.EXTRA_PHONE_NUMBER);
How to chech if the dialing call is still on or the client hanged up the call?
How to check if the call was answered?
I need to print up a toat when the client hanged up the call or when the called client answered to the call.
You will need a broadcast receiver registered for action android.intent.action.PHONE_STATEiF THE phone state has not changed to idle once it is offhook, it means the call is still going on.
the call was answered if the state in read phone state broadcast receiver changes to offhook. Put a toast as need in these states.
public class CallDurationReceiver extends BroadcastReceiver {
static boolean flag =false;
static long start_time,end_time;
#Override
public void onReceive(Context arg0, Intent intent) {
String action = intent.getAction();
if(action.equalsIgnoreCase("android.intent.action.PHONE_STATE")){
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_RINGING)) {
//tOAST FOR INCOMING CALL, NOT YET PICKED UP
}
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_IDLE)) {
end_time=System.currentTimeMillis();
//Total time talked =
long total_time = end_time-start_time;
//Store total_time somewhere or pass it to an Activity using intent
} if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_OFFHOOK)) {
start_time=System.currentTimeMillis();
}
}
}
Register your receiver in your manifest file like this:
<receiver android:name=".CallDurationReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
}
Also add the uses permission:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Well all I find out a solution for this and I successfully implemented it.Its not possible to fetch the exact time when the callee has accepted an outgoing call.
Before picking up a call in the other end it has already passed through 2 stages namely on_State_idle and on_state_offhook. On_state_ringing is not working for the outgoing calls.
Let's assume a phone is ringing for 40sec (this am not sure) continuously if the person at the other side didn't pick the call.
Start a timer along with the starting stage of on_State_idle and on_state_offhook.
Two cases if the timer cross above 40sec means the person at the other hand pick my call.
If on_State_idle->on_state_offhook->on_State_idle worked within 40sec means the other hand didn't pick my call.
If the second case is true, fetch the call talk duration from the call log.
Totaltimer running time - time in call log gives you the exact time of picking of the outgoing Call!
you can use the below code for handling call state:::
private Runnable callMonitor = new Runnable() {
public void run() {
try {
EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)m_activity.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
} catch(Exception e) {
Log.e("callMonitor", "Exception: "+e.toString());
}
}
};
private class EndCallListener extends PhoneStateListener {
private boolean active = false;
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if(TelephonyManager.CALL_STATE_RINGING == state) {
Log.i("EndCallListener", "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.
active = true;
Log.i("EndCallListener", "OFFHOOK");
}
if(TelephonyManager.CALL_STATE_IDLE == state) {
//when this state occurs, and your flag is set, restart your app
Log.i("EndCallListener", "IDLE");
if (active) {
active = false;
// stop listening
TelephonyManager mTM = (TelephonyManager)m_activity.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(this, PhoneStateListener.LISTEN_NONE);
// restart the inbox activity
// Intent intent = new Intent(m_activity, MDInboxActivity.class);
// m_activity.startActivity(intent);
}
}
}
}
I managed to prepare an activity when the phone is ringing. Now I need to know how to cancel this activity, when I answer the phone or I reject the call.Do I call EXTRA_STATE_IDLE or EXTRA_STATE_OFFHOOK ?
Any ideas?
Manifest
<receiver android:name=".IncomingBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
IncomingBroadcastReceiver java Class
public class IncomingBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
// If an incoming call arrives
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { //Did my work }
The above answer is completely wrong in case of outgoing calls. In Android there is no way by which one detect whether the call was actually answered (in case of outgoing calls). The moment you dial a number, the off_hook state is fired. This is one of the drawbacks of Android programming.
in your onReceive:
PhoneStateChangeListener pscl = new PhoneStateChangeListener();
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(pscl, PhoneStateListener.LISTEN_CALL_STATE);
separate class:
private class PhoneStateChangeListener extends PhoneStateListener {
public static boolean wasRinging;
String LOG_TAG = "PhoneListener";
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.i(LOG_TAG, "RINGING");
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.i(LOG_TAG, "OFFHOOK");
if (!wasRinging) {
// Start your new activity
} else {
// Cancel your old activity
}
// this should be the last piece of code before the break
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.i(LOG_TAG, "IDLE");
// this should be the last piece of code before the break
wasRinging = false;
break;
}
}
}
All you need to do is write some code to check if the previous state was 'ringing'.
If the current state is idle and the previous state was ringing, they cancelled the call.
If the current state is offhook and the previous state was ringing, they answered the call.
Following are the states which it goes through in different scenarios:
1) Answering Received call
CALL_STATE_RINGING => CALL_STATE_OFFHOOK (After Answering call) => CALL_STATE_IDLE (After End call)
2) Rejecting / Not Answering (Missed) Received call
CALL_STATE_RINGING => CALL_STATE_IDLE (After End call)
3) Dialing call
CALL_STATE_OFFHOOK (After dialing) => CALL_STATE_IDLE (After End call)
Code
int prev_state=0;
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
#Override
public void onCallStateChanged(int state, String incomingNumber){
if(incomingNumber!=null&&incomingNumber.length()>0) incoming_nr=incomingNumber;
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "CALL_STATE_RINGING");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "CALL_STATE_OFFHOOK");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_nr);
NumberDatabase database=new NumberDatabase(mContext);
if((prev_state==TelephonyManager.CALL_STATE_OFFHOOK)){
prev_state=state;
//Answered Call which is ended
}
if((prev_state==TelephonyManager.CALL_STATE_RINGING)){
prev_state=state;
//Rejected or Missed call
}
break;
}
}
}
In your receiver
onReceive(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager
Bundle bundle = intent.getExtras();
String phoneNr= bundle.getString("incoming_number");
mContext=context;
}
below is a code of detecting outgoing call by accessibility events -
Add a class which extends AccessibilityService in your projects -
public class CallDetection extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
acquireLock(this);
Log.d("myaccess","after lock");
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
Log.d("myaccess","in window changed");
AccessibilityNodeInfo info = event.getSource();
if (info != null && info.getText() != null) {
String duration = info.getText().toString();
String zeroSeconds = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(0)});
String firstSecond = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(1)});
Log.d("myaccess","after calculation - "+ zeroSeconds + " --- "+ firstSecond + " --- " + duration);
if (zeroSeconds.equals(duration) || firstSecond.equals(duration)) {
Toast.makeText(getApplicationContext(),"Call answered",Toast.LENGTH_SHORT).show();
// Your Code goes here
}
info.recycle();
}
}
}
#Override
protected void onServiceConnected() {
super.onServiceConnected();
Toast.makeText(this,"Service connected",Toast.LENGTH_SHORT).show();
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
info.notificationTimeout = 0;
info.packageNames = null;
setServiceInfo(info);
}
#Override
public void onInterrupt() {
}
}
But to get the function event.getSource() working you have to specify some of your service configuration through xml, so create a xml folder in your project and add a xml file called serviceconfig.xml (you can give any name you want.
The content of serviceconfig is below -
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="#string/callDetection"
android:accessibilityEventTypes="typeWindowContentChanged"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>
You can find more about serviceconfig in Here
Now add your service in you Manifest file like this -
<service android:name=".CallDetection"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:label="#string/callDetection">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/serviceconfig" />
</service>
And youre done, just run the app and go to Accessibility settings in your phone, you will find an option named as detection (or whatever name you have given as your service description), switch that on to give accesibility permissions for you app.
Now you will see a toast when call is answered.
you can Code any code you want in there, also you can call a callback function in your activity
Most important - Dont call your call window(android dialer window) untill the call is answered, otherwise this will not work.
Note - As android doesn't provide any solution to detect if the call is answered or not, this is the best alternative i have made, hope it works for you.
//
public class myService extends InCallService
{
// Here... :)
#Override public void onCanAddCallChanged(boolean canAddCall)
{
super.onCanAddCallChanged(canAddCall);
}
}
To detect that a call is received, you can detect a "hello" voice. "hello" voice is the frequency (voice activity) outside of Call progress Frequency. For reference you can have a look at this datasheet part: https://www.cmlmicro.com/products/call-progress-and-voice-detector/
I'm trying to build an application that logs when I accept and reject calls. Therefor I'm using a PhoneStateListener.
When I start the listener in the onCreate() method it is stopping its activity after some time. As far as I know Android closes the App because it has no focus.
I tried to work around that behavior with starting a service. All the code I wrote works fine and doesn't get killed by android...but the PhoneStateListener doesn't recieve any events.
How I start the Service:
public class RunningService extends IntentService {
/**
* A constructor is required, and must call the super IntentService(String)
* constructor with a name for the worker thread.
*/
public RunningService() {
super("RunningService");
}
/**
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns,
* IntentService stops the service, as appropriate.
*/
#Override
protected void onHandleIntent(Intent intent) {
//...some code...creating a notification
startForeground(12345, notification);
TelephonyManager telephonyManager = (TelephonyManager) this
.getSystemService(TELEPHONY_SERVICE);
telephonyManager.listen(new PhoneStateListenerImpl(),
PhoneStateListener.LISTEN_CALL_STATE);
while (true) {
...some code to do...until Exit is called by user
}
}
}
The PhoneStateListener with basic output:
public class PhoneStateListenerImpl extends PhoneStateListener {
public PhoneStateListenerImpl() {
super();
Log.v("psListener", "constructor");
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.v("PhoneStateListener", "IDLE");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.v("PhoneStateListener", "OFFHOOK");
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.v("State", "Ringing");
break;
default: {
Log.v("Status", "something");
}
}
}
}
I get the Log output frome the Listeners constructor, but whenever something changes (like I'm calling someone) nothing happens.
The same Listener started from onCreate() works fine.
Maybe I'm missing something
I just tried:
I tried to ask the TelephonyManager for the phone state in the while loop of the Service. This works fine. But I guess this is just a dirty workaround.
Has anybody an idea what could be the problem?
you are registering your PhoneStateListener on onHandleIntent instead of that register your listener in onStartCommand or onCreate functions, and make sure you have mentioned following permissions in your project's manifest