How to Implement a Contentobserver for Call Logs

How to implement a ContentObserver for call logs

Here is the answer. Dont forget to register the content observer with this method:

registerContentObserver (Uri uri, boolean notifyForDescendents, ContentObserver observer)

And then you can create it like this.

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getApplicationContext()
.getContentResolver()
.registerContentObserver(
android.provider.CallLog.Calls.CONTENT_URI, true,
new MyContentObserver(handler));
}

class MyContentObserver extends ContentObserver {
public MyContentObserver(Handler h) {
super(h);
}

@Override
public boolean deliverSelfNotifications() {
return true;
}

@Override
public void onChange(boolean selfChange) {
Log.d(LOG_TAG, "MyContentObserver.onChange("+selfChange+")");
super.onChange(selfChange);

// here you call the method to fill the list
}
}

android content observer - onChange method check if last call is missed call or not

I would suggest to try the following code in order to determine 'if last call is missed call or not':

@Override
public void onChange(boolean selfChange, Uri uri) {

if (null == uri) {
onChange(selfChange);
return;
}

super.onChange(selfChange, uri);

final Cursor c = context.getContentResolver().query(uri,null,null, null, null);
final int type = c.getColumnIndex(CallLog.Calls.TYPE);
final int dircode = c.getInt(type);

switch (dircode) {
case CallLog.Calls.MISSED_TYPE:
flag++;
break;
}
}

It would be faster than checking all calls in case if You need to check only latest call. However, if where will be no uri, then provided way looks fine.

Another suggestion is to implement Service to do checking of missed calls count, so You will not have long processing in ContentObserver.

How to implement ContentObserver?

It seems ok to me, every time your URI CONTENT_URI gets updated (insert, delete or modify) your ContentObserver should be triggered, if your onChange() method is not getting called, make sure that you are pointing to the right URI in your ContentProvider.

One thing you should add is the unregister of your content observer, in your onPause() method you should do the following:

getContentResolver().unregisterContentObserver(myObserver);

Hope it helps!

Listen for changes in CallLog.Calls

If there is an Intent that is fired on an incoming call you could get your app to respond by using a BroadcastReceiver and create an IntentFilter in your manifest.

Or just query the provider when your app launches...

Edit:

ACTION_PHONE_STATE_CHANGED is a TelephonyManager intent you can listen for and check if it is TelephonyManager.CALL_STATE_RINGING.

How to know if their is change in call log using contentOberser.

If there is an Intent that is fired on an incoming call you could get your app to respond by using a BroadcastReceiver and create an IntentFilter in your manifest.

Or just query the provider when your app launches...

ACTION_PHONE_STATE_CHANGED is a TelephonyManager intent you can listen for and check if it is TelephonyManager.CALL_STATE_RINGING.

Registering ContentObserver for Android CallLog causes crash

The problem lies with the update to Android O. Permissions are grouped together and since Android O permission behaviour was changed because of incorrect handling of permission requests.

In my example I had added the permissions READ_CALL_LOG/WRITE_CALL_LOG and CALL_PHONE to the manifest, but requested only CALL_PHONE at first startup of the app. This caused the permission group PHONE to be accepted, but neither of the call-log permissions. So when the registerContentObserver method was called, Android implicitly accepted it to be used because of accepting the group PHONE.

When my user upgraded from N to O, and registerContentObserver was called again, it would crash (justly). Solution: check for the READ_CALL_LOG/WRITE_CALL_LOG permisions before calling registerContentObserver.

Workaround for users on Android O who're still using the old - crashing- code: Manually turn off & on the specific permission in the Android settings of the app (so the PHONE permission group in this case). This causes all permissions in this group to be accepted (or at least those permissions in that group that are required by the app)

How to load call logs faster like other apps and display like attached image

I have tried without using data base its working fine and more faster as compare to last uploaded check following answer.

But I have issue with Name and photo uri of call log because Cached data may not be available or may not be updated after any contact changed. Is their any Other way to deal with it.

 private void setCallLogs(Cursor curLog) {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE);
int sr_id = 0;
while (curLog.moveToNext()) {
String callNumber = curLog.getString(curLog
.getColumnIndex(CallLog.Calls.NUMBER));
callNumber = Utilities.correctNumber(callNumber);
String ids = curLog.getString(curLog
.getColumnIndex(CallLog.Calls._ID));

String name = curLog.getString(curLog
.getColumnIndex(CallLog.Calls.CACHED_NAME));

String callname = "Unknown";
String photoUri = "";
if (name != null)
callname = name;

String callType = curLog.getString(curLog
.getColumnIndex(CallLog.Calls.TYPE));

String dateString = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.format(new Date(Long
.parseLong(curLog.getString(curLog.getColumnIndex(CallLog.Calls.DATE)))));
//dateString = CallHistoryFragment.setdateToLog(dateString);

sr_id = sr_id + 1;
if (mainDialerhistory.size() == 0) {

club_id = 1;
count = 1;

mainDialerhistory.add(new HistoryController(ids, String.valueOf(sr_id), callname, callNumber.replace(" ", ""), dateString,
callType, "", "", count, photoUri, String.valueOf(club_id)));

} else {
count = 0;
int mainArraySize = mainDialerhistory.size() - 1;
if (mainDialerhistory.get(mainArraySize).getPhone().equals(callNumber.replace(" ", ""))) {

if (mainDialerhistory.get(mainArraySize).getcallType().equals(callType)) {
count = mainDialerhistory.get(mainArraySize).getCount() + 1;
club_id = Integer.parseInt(mainDialerhistory.get(mainArraySize).getGr_id());

mainDialerhistory.add(new HistoryController(ids, String.valueOf(sr_id), callname, callNumber.replace(" ", ""), dateString,
callType, "", "", count, photoUri, String.valueOf(club_id)));

} else {
String lastType = mainDialerhistory.get(mainArraySize).getcallType();

if (lastType.equals("3") && (callType.equals("10") || callType.equals("2") || callType.equals("1"))) {
count = 0;
club_id = Integer.parseInt(mainDialerhistory.get(mainArraySize).getGr_id()) + 1;

mainDialerhistory.add(new HistoryController(ids, String.valueOf(sr_id), callname, callNumber.replace(" ", ""), dateString,
callType, "", "", 1, photoUri, String.valueOf(club_id)));

} else if ((lastType.equals("10") || lastType.equals("2") || lastType.equals("1")) && callType.equals("3")) {
club_id = Integer.parseInt(mainDialerhistory.get(mainArraySize).getGr_id()) + 1;

mainDialerhistory.add(new HistoryController(ids, String.valueOf(sr_id), callname, callNumber.replace(" ", ""), dateString,
callType, "", "", count + 1, photoUri, String.valueOf(club_id)));

} else {
count = 0;
count = mainDialerhistory.get(mainArraySize).getCount() + 1;
club_id = Integer.parseInt(mainDialerhistory.get(mainArraySize).getGr_id());

mainDialerhistory.add(new HistoryController(ids, String.valueOf(sr_id), callname, callNumber.replace(" ", ""), dateString,
callType, "", "", count, photoUri, String.valueOf(club_id)));

}
}
} else {
club_id = Integer.parseInt(mainDialerhistory.get(mainArraySize).getGr_id()) + 1;
mainDialerhistory.add(new HistoryController(ids, String.valueOf(sr_id), callname, callNumber.replace(" ", ""), dateString,
callType, "", "", 1, photoUri, String.valueOf(club_id)));

}
}

}
curLog.close();
endTime = System.currentTimeMillis();
long MethodeDuration = (endTime - startTime);
Log.e("MethodeDuration", "-count-" + mainDialerhistory.size());
Log.e("MethodeDuration", "-log-" + MethodeDuration);
AccountController.getInstance().mAccountHistory.addAll(mainDialerhistory);

sendBroadcast(new Intent("log_updated"));

stopService(new Intent(this, CallLogIntentService.class));
}


Related Topics



Leave a reply



Submit