[HOWTO] Fix CallerID matching issues in JB Phone and Messaging
How to fix CallerID matching issues in JellyBean Phone and Messaging apps
This guide is for everyone who has problems with incorrect Caller ID
matching in Phone and Messaging that happens mainly on stock JellyBean ROMs.
This can be easily fixed in the source code, I know, but this guide is dedicated to devices
that have no source code available. That's why we will be dealing with some smali hacking.
For devs: It took me couple of hours to identify the problem and fix it,
so please, if you decide to use this how-to to fix stuff in your custom roms,
I expect you to give proper credits. Thanks in advance.
The guide does not cover things like deodexing/decompiling/compiling/odexing jars and apks.
It expects you already are familiar with these processes.
There are already many guides for those out there.
As you already know, operator often sends the full Caller ID including country prefix
when receiving a call. If your contacts are stored without country prefix (in local format),
Phone app is unable to match the number provided by the operator to one in the Contacts database.
Example: you have a contact defined with phone number 0902 xxx yyy.
Operator sends +421 902 xxx yyy - you get mismatch and no caller indicated while ringing.
In Messaging, when you send SMS to contact that has not country prefix, and receive response,
operator will most likely use full number with country prefix in a received SMS.
The messaging app is unable to associate arriving message to existing conversation because of
a number mismatch and thus creates a new conversation thread.
Contacts are stored within Contacts Provider. One of the attribute for contact is a "min_match"
attribute which stores a part of the whole number (from right to left) that has to be used when matching Caller ID to
contact. The length of the min_match attribute is defined in the telephony framework.
It is good practice to keep the MIN_MATCH length to max 7 (typically it takes 6 numbers from the right
+ 1 number from local prefix - for our example above min_match would be: 2xxxyyy
However, some official ROMs have the MIN_MATCH constant too high making it impossible to match
numbers stored in local format to full caller ID received from operator. (It was 11 in my case!!!)
(+421 902 xxx yyy != 0902 xxx yyy)
Apart from this, there is also one boolean constant that defines the method of caller ID comparation:
If this constant is set to "true" MIN_MATCH doesn't play role and always full numbers have to match to
correctly map caller to contact - this is something we don't want.
Messaging app specific
Apart from min_match thing I've alredy described, there's another part in Messaging that plays role.
Contacts in messaging app are cached in a local cache. Each cached contact is identified by a key, which
is typically a phone number. Again, there's a constant that defines how much characters from right to left
of the phone number have to be used as a key. If this constant is too big (10 in my case!!!), you will get mismatch when
Messaging app is trying to associate arriving SMS with existing conversation resulting in creating new thread.
It is good practice to keep this constant at the length of 5.
I) Check for and fix comparation method
Firstly, we must assure that strict checking is turned off.
1) Decompile framework-res.apk
2) Open res/values/bools.xml and search for config_use_strict_phone_number_comparation variable
3) Make sure it's false
4) Recompile farmework-res.apk if you had to change the variable
II) Check for and fix MIN_MATCH constant in telephony framework
1) Decompile framework.jar
2) Open smali/android/telephony/PhoneNumberUtils.smali
3) Search for MIN_MATCH constant and set it to 0x7
.field static final MIN_MATCH:I = 0x7 (was 0xb in my case)
4) Since in smali, constant names are not used but they are translated to explicit values, we have
to search for all occurences where old MIN_MATCH constant is used (0xb in my case) and change the values to 0x7
a) one is in "compareLoosly" method:
.local v7, minMatchLen:I
const/16 v7, 0x7 (was 0xb in my case)
b) another one in "toCallerIDMinMatch" method:
.local v0, minMatchLen:I
const/16 v0, 0x7 (was 0xb in my case)
5) Save the file and recompile framework.jar
III) Fix messaging app
1) Decompile Mms.apk
2) Open smali/com/android/mms/data/Contact$ContactsCache.smali
3) Search for STATIC_KEY_BUFFER_MAXIMUM_LENGTH and set it to 0x5
.field static final STATIC_KEY_BUFFER_MAXIMUM_LENGTH:I = 0x5 (was 0xa in my case)
4) Search for all occurences where old STATIC_KEY_BUFFER_MAXIMUM_LENGTH constant is used (0xa in my case) and change the values to 0x5
a) one is in "key" method
const/16 v2, 0x5 (was 0xa in my case)
b) another one in "getKey" method (it is possible there is no such method, then ignore it)
const/16 v4, 0x5 (was 0xa in my case)
c) another one in "internalGet" method
const/16 v10, 0x5 (was 0xa in my case)
5) Save the file and recompile Mms.apk
After pushing your new files to phone it is necessary to re-add all of the contacts for fix to take effect.
This is because your contacts are still stored in a database with wrong min_match number.
It needs to be re-initialized according to new MIN_MATCH constant we have modified.
The fastest way is to go to Settings/Apps, locate Contacts Storage, open it and Clear data.
(this will delete all contacts from phone so make sure you have a backup
In case you have your contacts synced to Google account, no backup is necessary.
Your contacts will be synced a while after you clear data for Contacts Storage.
For Messaging it is necessary to delete all the old threads that are incorrectly splitted.
All new conversations created after fix has been applied will be grouped OK.