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
Setresult Does Not Work When Back Button Pressed
Android Displaymetrics Returns Incorrect Screen Size in Pixels on Ics
Handling Buttons Inside Android Notifications
How to Store SQLite Database Directly on Sdcard
Simple Mediaplayer Play Mp3 from File Path
Upgrade Realm in an Android Project
Add Views Below Toolbar in Coordinatorlayout
How to Implement the Material-Design Elevation for Pre-Lollipop
How to Get the Current Location in Google Maps Android API V2
Extract Code Country from Phone Number [Libphonenumber]
Add a Search Filter on Recyclerview with Cards
Android - Supportmapfragment with Googlemaps API 2.0 Giving Illegalargumentexception
Horizontal Scrolling Grid View
Class Java.Util.Map Has Generic Type Parameters, Please Use Generictypeindicator Instead
Android Music Seekbar Is Not Working (Idle)
Recyclerview Gridlayoutmanager: How to Auto-Detect Span Count
Android - Startactivityforresult Immediately Triggering Onactivityresult