Good day!
A few months ago, I had a wonderful Volvo V50 car originally from Belgium. The on-board computer and the radio tape recorder were successfully flashed into Russian from an authorized dealer, but with the display of Russian names from the phone’s notebook, when using a standard speakerphone, there was a problem: all Cyrillic characters were shown as underscores. I use the Samsung Galaxy S3 firmware CyanogenMod 11, so the idea arose to correct the standard Bluetooth.apk to ensure the ability to see the name of the caller.
A small study found that basically cars use two kinds of profiles to get phonebook entries:
- PBAP - Phone Book Access Profile
- HFP - Handsfree Profile
The first one is more sophisticated and transmits data in the vCard format, which includes almost all contact data: name, surname, organization, email address, and so on.
The second sends only the name, phone number and notebook ID.
By analyzing the system logs, it turned out that my car uses HFP with communication via AT commands. The following file is responsible for this profile
/packages/apps/Bluetooth/src/com/android/bluetooth/hfp/AtPhonebook.javaAfter a brief search, we find the function
int processCpbrCommand (BluetoothDevice device) , at the end of which the command response line is formed:
record = "+CPBR: " + index + ",\"" + number + "\"," + regionType + ",\"" + name + "\""; record = record + "\r\n\r\n"; atCommandResponse = record; log("processCpbrCommand - atCommandResponse = "+atCommandResponse); mStateMachine.atResponseStringNative(atCommandResponse, getByteAddress(device));
It is here that it would be nice to fix the transmitted name. In my case, it was decided to transliterate it. For these purposes, I added an array of matching characters to the AtPhonebook class, as well as the function of translation:
private static final String[] charTable = new String[65536]; static { charTable[''] = "A"; charTable[''] = "B"; charTable[''] = "V"; charTable[''] = "G"; charTable[''] = "D"; charTable[''] = "E"; charTable[''] = "E"; charTable[''] = "ZH"; charTable[''] = "Z"; charTable[''] = "I"; charTable[''] = "I"; charTable[''] = "K"; charTable[''] = "L"; charTable[''] = "M"; charTable[''] = "N"; charTable[''] = "O"; charTable[''] = "P"; charTable[''] = "R"; charTable[''] = "S"; charTable[''] = "T"; charTable[''] = "U"; charTable[''] = "F"; charTable[''] = "H"; charTable[''] = "C"; charTable[''] = "CH"; charTable[''] = "SH"; charTable[''] = "SH"; charTable[''] = "'"; charTable[''] = "Y"; charTable[''] = "'"; charTable[''] = "E"; charTable[''] = "U"; charTable[''] = "YA"; for (int i = 0; i < charTable.length; i++) { char idx = (char) i; char lower = new String(new char[] {idx}).toLowerCase().charAt(0); if (charTable[i] != null) { charTable[lower] = charTable[i].toLowerCase(); } } } public static String toTranslit(String text) { char charBuffer[] = text.toCharArray(); StringBuilder sb = new StringBuilder(text.length()); for (char symbol : charBuffer) { String replace = charTable[symbol]; sb.append(replace == null ? symbol : replace); } return sb.toString(); }
After that, you need to call the function when sending the command:
record = "+CPBR: " + index + ",\"" + number + "\"," + regionType + ",\"" + toTranslit(name) + "\""; record = record + "\r\n\r\n";
Now it only remains to compile the Bluetooth application and insert it into the archive with the CM firmware.
Tests after flashing showed full performance solutions. Now all the names from the notebook are displayed in transliteration.
In the process of finding a ready-made solution, it turned out that there are problems with the PBAP profile, again with Volvo cars, for example, the XC60.
The speakerphone module in this car uses the CP1251 encoding, while the standard Bluetooth phone application on Android transmits data over the PBAP profile, indicating the UTF-8 encoding, which is reflected in the display of data with underscores.
')
To solve this problem, you can change the BluetoothPbapVcardComposer class constructor (
/packages/apps/Bluetooth/src/com/android/bluetooth/pbap/BluetoothPbapVcardComposer.java )
public BluetoothPbapVcardComposer(final Context context, final int vcardType, long filter, final boolean careHandlerErrors) { super(context, vcardType, "CP1251", careHandlerErrors); mVCardType = vcardType; mCharset = "CP1251"; mFilter = filter; }
Here you can explicitly set the encoding for the superclass.
In principle, you can try to crank the transliteration trick here, you need to dig in the direction of forming a vCard (buildVCard function)
Unfortunately, I do not yet have an XC60 or another machine using PBAP, so I could not verify it.
I attach a couple of options for reassembled Bluetooth.apk
- Translite HFP ( http://yadi.sk/d/QlGKIPfXLMNXx )
- CP1251 PBAP ( http://yadi.sk/d/qrbUVrtuLMRan )
This solution can also help the owners of other cars with built-in speakerphone that does not understand Russian.