Question

I'm trying to get the call I just made/received. For that I'm using BroadcastReceiver and IntentServices.

It happens like this:

In my BroadcastReceiver class, I check if the state is OFFHOOK, if yes, I set the flag in SharedPreferences, so When the state becomes IDLE, I check if this flag is still true, if it is, I call the IntentService that goes in CallLog *ContentProvider* and get the lates data like this:

cursor = getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, mCursorFields, null, null, android.provider.CallLog.Calls.DATE + " DESC");

cursor.moveToFirst();
cursor.getString(cursor.getString(cursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
...

Until now it happens perfectly, the only problem is:

"It doesn't get the latest entry. It gets the next entry, that is the call made before this."

So, If I made a call before to person 'X', in the CallLog is registered this call to person 'X'. And now, if I make a call to person 'Y', instead of it get the call to person 'Y', it get's the call to person 'X', that was the call I made before this.

I don't know what can be happening. It was working perfectly when using ContentObserver but I thought it would be more efficiently built with BroadcastReceiver.

Any idea?

Thanks in advance.


Just a comment about using ContentObserver:

The problem with using ContentObserver is that, If I change the name of a contact, it detects a change in the CallLog, because the users in the CallLog with the old name will be updated to the new name, and the change will occur and call the class. For that I need to make verifications, for check if it really changed, which I think annoying.

Was it helpful?

Solution

Try delaying the call a bit. I believe it takes "a while" until the call log is added. ContentObserver is the correct way of handling this as you will be notified when the change occurs. If you want to work this way, you will need to delay this in a few seconds after the phone is idle.

OTHER TIPS

You are keeping track of calls using shared perefernces this is not efficient. Instead of you have to take one static variable and then you have to set its value whenever the state of call changed I had put a below code for keep track of call states and fetch new call log data from internal database This code is working fine for me.

public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);

switch (state) {
    case TelephonyManager.CALL_STATE_IDLE:
        // Toast.makeText(context, "CALL_STATE_IDLE", Toast.LENGTH_LONG).show();
        /**this condition will check that last state was not CALL_STATE_IDLE means that 
        * recently there was disconneted call
        */
        if(UDF.phoneState != TelephonyManager.CALL_STATE_IDLE) {
            //You can query for new call log
        } 
        break;
    case TelephonyManager.CALL_STATE_OFFHOOK:
         //Toast.makeText(context, "CALL_STATE_OFFHOOK", Toast.LENGTH_LONG).show();
        break;
    case TelephonyManager.CALL_STATE_RINGING:
         //Toast.makeText(context, "CALL_STATE_RINGING", Toast.LENGTH_LONG).show();
        endCallIfBlocked(incomingNumber);
        break;

    default:
        break;
}
UDF.phoneState = state;
}

i just fixed making postdelay upto 4000ms while retrieve from db in idle state.

handler.postdelay(new Runnable(run() {
    //write code here
}), 4000);

it works fine to me...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top