Java – CallLog.Calls.CACHED_NAME always returns null for some saved contacts

CallLog.Calls.CACHED_NAME always returns null for some saved contacts… here is a solution to the problem.

CallLog.Calls.CACHED_NAME always returns null for some saved contacts

I’m trying to display call log details in my app, but CallLog.Calls.CACHED_NAME always returns null for some contacts, even if it’s a saved name contact. The built-in call log correctly displays the names of these contacts.

Here is my code :

protected customAdapRecent doInBackground(Void... params) {

ContentResolver resolver = context.getContentResolver();
        final String[] PROJECTION = new String[] {
                                                    CallLog.Calls.CACHED_LOOKUP_URI,
                                                    CallLog.Calls.NUMBER,
                                                    CallLog.Calls.CACHED_NAME,
                                                    CallLog.Calls.TYPE,
                                                    CallLog.Calls.DATE,
                                                    CallLog.Calls.DURATION
                                                };

Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, PROJECTION, null, null, CallLog.Calls.DATE + " DESC");
        if(cursor.getCount() > 0)
        {
            int iNumber = cursor.getColumnIndex(CallLog.Calls.NUMBER);
            int iName = cursor.getColumnIndex(CallLog.Calls.CACHED_NAME);
            int iType = cursor.getColumnIndex(CallLog.Calls.TYPE);
            int iDate = cursor.getColumnIndex(CallLog.Calls.DATE);
            int iDuration = cursor.getColumnIndex(CallLog.Calls.DURATION);

DateFormat datePattern = DateFormat.getDateInstance(DateFormat.FULL);

String number;
            String name;
            String type;
            String date;
            String duration;
            String contactId;
            String callIs = "None";
            String prevDate = "";
            int callType;

while (cursor.moveToNext())
            {

if(cursor.getString(iName) == null)
                    Log.e("DEBUG: ", "Position: " + cursor.getPosition());

number = cursor.getString(iNumber);
                name = cursor.getString(iName);
                type = cursor.getString(iType);
                String tempdate = cursor.getString(iDate);
                Long tempDate = Long.parseLong(tempdate);
                date = datePattern.format(tempDate);

if(prevDate.equalsIgnoreCase(date))
                {
                    prevDate = date;
                    date = "";
                }
                else
                    prevDate = date;
                date = new Date(Long.valueOf(strdate));
                duration = cursor.getString(iDuration);
                callType = Integer.parseInt(type);
                switch (callType)
                {
                    case CallLog.Calls.OUTGOING_TYPE:
                        callIs = "OUT";
                        recentRow newRowO = new recentRow(number, name, date, duration, callIs);
                        listItem_recentOut.add(newRowO);
                        break;

case CallLog.Calls.INCOMING_TYPE:
                        callIs = "IN";
                        recentRow newRowI = new recentRow(number, name, date, duration, callIs);
                        listItem_recentIn.add(newRowI);
                        break;

case CallLog.Calls.MISSED_TYPE:
                        callIs = "MISS";
                        recentRow newRowM = new recentRow(number, name, date, duration, callIs);
                        listItem_recentMiss.add(newRowM);
                        break;

}

recentRow newRow = new recentRow(number, name, date, duration, callIs);
                recentRow newRow = new recentRow(number, name, callIs);
                listItem_recentAll.add(newRow);
            }
            cursor.close();
            cAdapRecent = new customAdapRecent(context, listItem_recentAll);
        }

return cAdapRecent;
    }

The debug statement given in Log.e() is also printed.

Am I doing something wrong in the lookup? Please. Suggest a way because I’m really blocked by this!

Thanks in advance….

Solution

I’m also experiencing this weird behavior and found that sometimes you can’t get a contact’s name right away, even though you can get everything else from CallLog.Calls. I noticed that about an hour or so after that call, you can get the name along with all the other CallLog.Calls data. It’s weird. If you need to refresh immediately after the call, you can get the name of the number from ContactsContract like this:

 fun getNameForNumber(context: Context, number: String): String? {

var res: String? = null
        try {
            val resolver = context.contentResolver
            val uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number))
            val c = resolver.query(uri, arrayOf(ContactsContract.PhoneLookup.DISPLAY_NAME), null, null, null)

if (c != null) {
                if (c.moveToFirst()) {
                    res = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
                }
                c.close()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

return res
    }

Oddly enough, after you get a name from ContactsContract, run an exception after getting the name through CallLog.Calls.CACHED_NAME the way you did this.

This is also the answer to @PeterB and @shyam002

Related Problems and Solutions