《android2.2內建通訊錄》之連絡人按拼音排序以及按漢字首字母或全拼搜尋

來源:互聯網
上載者:User

     今天用了整整一下午去搗鼓這塊,為什麼模擬器上可以按拼音排序,中英文混排,及按字母搜尋連絡人,但到了開發板(平台是根據android2.2改過的)上就怎麼不行了呢,雖然現在還沒有解決,但也是知道了問題所在,離解決之路也就不遠了

     好吧,現在就解釋下android2.2是怎麼按拼音排序的。

     首先我們來看下android.2內建通訊錄的資料庫檔案contacts2.db的raw_contacts表。用sqlitedbviewer工具開啟後可以看到有這麼一個欄位:sort_key(sort_key_alt與之相似,只不過是英文環境下有個按given name還是first name排序的問題)。

 

 

正常狀況下,我們建立一個連絡人的話,如果是英文,則sort_key與display_name欄位顯示相同,如果輸入姓名是中文,如“你好”,sort_key則會顯示“ni 你 hao 好”,這樣開發人員既可以根據此欄位按拼音排序,中英文混排,以及按拼音搜尋連絡人拉。

現在就說下,android是如何將中文名的連絡人轉化為拼音存到sort_key裡面的:

 

if (displayNameStyle == FullNameStyle.CHINESE ||<br /> displayNameStyle == FullNameStyle.CJK) {<br /> sortKeyPrimary = sortKeyAlternative =<br /> ContactLocaleUtils.getIntanc).getSortKe(displayNamePrimary, displayNameStyle);}  

這段代碼是運行在contactsprovi2.Java的updateRawContactDisplayName()方法裡面,這段代碼我們用到了ContactLocaleUtils.java這個類,所以我們進入它以後最顯眼的就是ChineseContactUtils這個ContactLocaleUtils的子類,它重寫了ContactLocaleUtils的getSortKey()方法,如下:

public String getSortKey(String displayName) {</p><p> ArrayList<Token> tokens = HanziToPinyin.getInstance().get(displayName);</p><p> if (tokens != null && tokens.size() > 0) {</p><p> StringBuilder sb = new StringBuilder();</p><p> for (Token token : tokens) {</p><p> // Put Chinese character's pinyin, then proceed with the</p><p> // character itself.</p><p> if (Token.PINYIN == token.type) {</p><p> if (sb.length() > 0) {</p><p> sb.append(' ');</p><p> }</p><p> sb.append(token.target);</p><p> sb.append(' ');</p><p> sb.append(token.source);</p><p> } else {</p><p> if (sb.length() > 0) {</p><p> sb.append(' ');</p><p> }</p><p> sb.append(token.source);</p><p> }</p><p> }</p><p> return sb.toString();</p><p> }</p><p> return super.getSortKey(displayName);</p><p>}<br />        

   首先我們看 ArrayList<Token> tokens = HanziToPinyin.getInstance().get(displayName);,因為其他的無非就是插入格式的問題,我們暫時不用看。

android如何將漢字轉為拼音的?這就用到了HanziToPinyin這個類,好吧,我們先看下HanziToPinyin的getInstance()方法:

public static HanziToPinyin getInstance() {</p><p> synchronized(HanziToPinyin.class) {</p><p> if (sInstance != null) {</p><p> return sInstance;</p><p> }</p><p> // Check if zh_CN collation data is available</p><p> final Locale locale[] = Collator.getAvailableLocales();</p><p> for (int i = 0; i < locale.length; i++) {</p><p> if (locale[i].equals(Locale.CHINA)) {</p><p> sInstance = new HanziToPinyin(true);</p><p> return sInstance;</p><p> }</p><p> }</p><p> Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled");</p><p> sInstance = new HanziToPinyin(false);</p><p> return sInstance;</p><p> }</p><p> }<br />

現在說下我的開發板為什麼不能轉拼音;就是因為final Locale locale[] = Collator.getAvailableLocales()的Locale沒有一項equals(Locale.CHINA),所以到時候解決了這項,連絡人的按拼音排序也就解決了,如果大家不想用系統內建的,自己可以下載個pinyin4j.jar包自己實現吧。

好吧,繼續:

看方法名也只到,這個方法返回一個HanziToPinyin執行個體,我仔細研究了HanziToPinyin的構造方法,無論純如的布爾值是false還是true都不影響,返回的都一樣,只不過這個方法的Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled");可以提示是否支援漢字轉拼音,如果不能,android就會將displayname原封不動的插入sort_key裡面,如果能,就是剛才我說的 如“你好”,sort_key則會顯示“ni 你 hao 好”,這種形式,具體的如何轉拼音就是get()方法拉,直接插代碼:

 

 

 

 

 

 public ArrayList<Token> get(final String input) {<br /> ArrayList<Token> tokens = new ArrayList<Token>();<br /> if (!mHasChinaCollator || TextUtils.isEmpty(input)) {<br /> // return empty tokens.<br /> return tokens;<br /> }<br /> final int inputLength = input.length();<br /> final StringBuilder sb = new StringBuilder();<br /> int tokenType = Token.LATIN;<br /> // Go through the input, create a new token when<br /> // a. Token type changed<br /> // b. Get the Pinyin of current charater.<br /> // c. current character is space.<br /> for (int i = 0; i < inputLength; i++) {<br /> final char character = input.charAt(i);<br /> if (character == ' ') {<br /> if (sb.length() > 0) {<br /> addToken(sb, tokens, tokenType);<br /> }<br /> } else if (character < 256) {<br /> if (tokenType != Token.LATIN && sb.length() > 0) {<br /> addToken(sb, tokens, tokenType);<br /> }<br /> tokenType = Token.LATIN;<br /> sb.append(character);<br /> } else if (character < FIRST_UNIHAN) {<br /> if (tokenType != Token.UNKNOWN && sb.length() > 0) {<br /> addToken(sb, tokens, tokenType);<br /> }<br /> tokenType = Token.UNKNOWN;<br /> sb.append(character);<br /> } else {<br /> Token t = getToken(character);<br /> if (t.type == Token.PINYIN) {<br /> if (sb.length() > 0) {<br /> addToken(sb, tokens, tokenType);<br /> }<br /> tokens.add(t);<br /> tokenType = Token.PINYIN;<br /> } else {<br /> if (tokenType != t.type && sb.length() > 0) {<br /> addToken(sb, tokens, tokenType);<br /> }<br /> tokenType = t.type;<br /> sb.append(character);<br /> }<br /> }<br /> }<br /> if (sb.length() > 0) {<br /> addToken(sb, tokens, tokenType);<br /> }<br /> return tokens;<br /> }

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.