再談Contacts中姓氏多音字排序錯誤問題,contacts多音字

來源:互聯網
上載者:User

再談Contacts中姓氏多音字排序錯誤問題,contacts多音字

說到中國人的名字,那就不得不考慮多音字的問題,比如'單',在作為姓氏時應該讀作'shan'而不是'dan'.但是在Contacts程式中卻使用的是'D'來作為bucket label!
這是為什嗎?如何解決這種多音字姓氏的問題?

從4.3版本開始,HanziToPinyin.java(ContactsProvider中)改為直接調用ICU的Transliterator來對漢字進行transliterate(詳見類中mPinyinTransliterator變數的使用).我們知道,ICU中的Han_Latin_Names.txt中儲存了一些漢字在作為姓氏時的讀音,如果在建立Transliterator對象時使用Han-Latin/Names作為id(可參考mPinyinTransliterator變數的初始化),將可以正確的獲得漢字作為姓氏時的讀音(僅限於Han_Latin_Names.txt中包含的漢字).也就是說,HanziToPinyin這個類在處理作為姓氏的多音字時是可以獲得正確獲得其讀音的.如在使用HanziToPinyin擷取'單田芳'的讀音為'shan tian fang'.就算這樣姓名為'單田芳'的連絡人依然被排在'D'下面!這是為什麼呢?
通過解析代碼可以發現,連絡人排在哪個字母下面是由raw_contacts表中的phonebook_label的值來決定的,而資料庫中phonebook_label的值確實是'D',主要是因為在獲得phonebook_label時使用的是AlphabeticIndex$ImmutableIndex的getBucketLabel函數,而這個函數是沒有對姓氏多音字做任何特殊處理的,所以最後得到的是'D'(phonebook_label的處理流程見附一).

目前,如果想比較省力的解決這個問題,可以在擷取phonebook_label時避免通過使用AlphabeticIndex$ImmutableIndex的getBucketLabel函數來擷取,而是改為用HanziToPinyin去獲得sortKeyPrimary的第一個字元的拼音(sortKeyAlternative暫不考慮).

貼一下代碼修改(基於4.4.4_r2)
-----------------------------------------------------------------------------
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -78,6 +78,7 @@ import android.text.util.Rfc822Tokenizer;
 import android.util.Log;
 
 import com.android.common.content.SyncStateContentProviderHelper;
+import com.android.providers.contacts.HanziToPinyin.Token;
 import com.android.providers.contacts.aggregation.util.CommonNicknameCache;
 import com.android.providers.contacts.database.ContactsTableUtil;
 import com.android.providers.contacts.database.DeletedContactsTableUtil;
@@ -85,6 +86,7 @@ import com.android.providers.contacts.database.MoreDatabaseUtils;
 import com.android.providers.contacts.util.NeededForTesting;
 import com.google.android.collect.Sets;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Set;
@@ -5388,8 +5390,25 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
         ContactLocaleUtils localeUtils = ContactLocaleUtils.getInstance();
 
         if (sortKeyPrimary != null) {
-            phonebookBucketPrimary = localeUtils.getBucketIndex(sortKeyPrimary);
-            phonebookLabelPrimary = localeUtils.getBucketLabel(phonebookBucketPrimary);
+            boolean flag = false;
+            if (displayNameStyle == FullNameStyle.CHINESE
+                    && HanziToPinyin.getInstance().hasChineseTransliterator()) {
+                String target = sortKeyPrimary.substring(0, 1);
+                ArrayList<Token> tokens = HanziToPinyin.getInstance().get(target);
+                if (tokens != null && tokens.size() > 0) {
+                    char label = tokens.get(0).target.charAt(0);
+                    if (label >= 'A' && label <= 'Z') {
+                        phonebookLabelPrimary = String.valueOf(label);
+                        phonebookBucketPrimary = localeUtils.getBucketIndex(phonebookLabelPrimary);
+                        flag = true;
+                    }
+                }
+            }
+
+            if (!flag) {
+                phonebookBucketPrimary = localeUtils.getBucketIndex(sortKeyPrimary);
+                phonebookLabelPrimary = localeUtils.getBucketLabel(phonebookBucketPrimary);
+            }
         }
         if (sortKeyAlternative != null) {
             phonebookBucketAlternative = localeUtils.getBucketIndex(sortKeyAlternative);

-----------------------------------------------------------------------------
通過上面的分析可以發現一個問題,那就是在Contacts首頁面用'dan tian fang'搜尋連絡人時是搜不到的,只能用'shan tian fang'來搜尋,但是在顯示時確是將該連絡人放在了'D'分組下面!根本原因就是NameLookupBuilder在調用appendNameShorthandLookup時實際上使用了HanziToPinyin來擷取讀音,這時得到的是作為姓氏時的讀音,而phonebook_label是使用AlphabeticIndex$ImmutableIndex的getBucketLabel函數來擷取的,而它沒有對姓氏多音字做任何特殊處理,這就導致了前面說的問題.
另外,用HanziToPinyin的一個問題是所有的可作為姓氏的漢字的讀音都是姓氏的讀音,如'單位單'的拼音是'shan wei shan'.如何解決這個問題呢?其實現有條件下沒有一個好的辦法(加詞庫的方法除外),只能盡量規避.我的方法是中文情況下名字中的第一個漢字作為姓氏去擷取讀音(使用Han-Latin/Names; Latin-Ascii; Any-Upper建立的Transliterator對象),而其它漢字則作為普通漢字去擷取讀音(使用Han-Latin; Latin-Ascii; Any-Upper建立的Transliterator對象,需在HanziToPinyin中再建立一個Transliterator對象).

附一
raw_contacts表中的phonebook_label的擷取流程:
raw_contacts表中的phonebook_label是通過調用ContactsDatabaseHelper的updateRawContactDisplayName函數來完成插入/更新的.使用的是phonebookLabelPrimary變數的值.而phonebookLabelPrimary是ContactLocaleUtils中getBucketLabel獲得的,getBucketLabel中實際調用的是ICU中ImmutableIndex的getBucketLabel來完成的().

PS:尋強力ROMTeam Dev.本人主要負責Dialer、Contacts相關模組,三年經驗.有意者可以email我: gaojx0809@gmail.com

 


EXCEL 姓名排序的問題 高分解決辦法

excel預設按多音字中的拼音首字母在A-Z序列中靠前的那個讀音排序


zhang,chang
會按照chang來參加排序如果只是排序的不論多音字都可以排序的。
如果要區分多音字排序只有自己多加標註區分。
祝你成功!
 
姓氏中的多音字解答

不好意思.還沒回答完.不小心按了提交

在姓氏中,“樸”讀(piáo)
在姓氏中,“折”讀(zhé)
在姓氏中,“單”讀(shàn )
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.