1. 程式人生 > >Android通過來電號碼識別姓名。

Android通過來電號碼識別姓名。

專案中遇到需要通過來電號碼獲取到聯絡人姓名的需求。

然而,簡單地通過聯絡人資料庫的Filter來獲取來電號碼在部分手機是獲取不到儲存的聯絡人的,比如三星S3,需要獲取通訊錄儲存的有+86等國區碼,而來電沒有+86的情況。部分手機也會出現儲存的沒有+86,來電有+86無法獲取的情況。

那麼,我們就需要通過獲取所有聯絡人的電話號碼,通過比較來電號碼來知道該來電號碼的姓名是誰。

來電號碼還有可能是國外的,因此還需要國家區碼。

(如果我們需要識別飛信或者是其他的字首,直接新增在countryCode即可。)

 因為要搜尋所有的聯絡人,那麼效率也是我們要考慮的問題,這裡的從資料庫獲取並判斷是否相等,

大部分手機能夠在20ms獲取到30多個聯絡人,那麼1s鍾能夠獲取到1500+的聯絡人,在三星s3上面30ms能夠獲取到22個聯絡人,1s大約能夠獲取到700個聯絡人。所以這個結果還是能夠接受的。

查取所有國家電話區號並構成一個數組。(從網上找到國家區號複製在txt文字,然後通過間斷的java程式就能把他們格式化。)

int[] countryCode = new int[]{
            86, 93, 355, 213, 376,//中國,阿富汗,阿爾巴尼亞,阿爾及利亞,安道爾,
244, 1264, 1268, 54, 374,//安哥拉,安圭拉島(),安地卡及巴布達,阿根廷,亞美尼亞,
297, 247, 61, 43, 994,//阿魯巴島,阿森鬆(),澳大利亞,奧地利,亞塞拜然,
1242, 973, 880, 1246, 375,//巴哈馬國,巴林,孟加拉國,巴貝多,白俄羅斯
, 32, 501, 229, 1441, 975,//比利時,貝里斯,貝南,百慕大群島(),不丹, 591, 267, 55, 673, 359,//玻利維亞,波札那,巴西,汶萊,保加利亞, 226, 257, 237, 1, 34,//布吉納法索,蒲隆地,喀麥隆,加拿大,加那利群島(西), 238, 235, 236, 56, 1345,//維德角,查德,中非,智利,開曼群島(), 619164, 619162, 57, 1767, 269,//聖誕島,科科斯島,哥倫比亞,多明尼加聯邦,葛摩, 242, 682, 506, 385, 53,//剛果,科克群島(),哥斯大黎加,克羅埃西亞,古巴, 357, 420, 45
, 246, 298,//塞普勒斯,捷克,丹麥,迪戈加西亞,法羅群島, 299, 253, 1809, 593, 20,//格陵蘭島,吉布提,多明尼加共和國,厄瓜多,埃及, 503, 240, 372, 251, 291,//薩爾瓦多,赤道幾內亞,愛沙尼亞,衣索比亞,厄利垂亞, 500, 679, 358, 33, 594,//福克蘭群島,斐濟,芬蘭,法國,法屬蓋亞那, 241, 220, 995, 49, 233,//加彭,甘比亞,喬治亞,德國,迦納, 350, 30, 1473, 1671, 502,//直布羅陀(),希臘,格瑞那達,關島(),瓜地馬拉, 245, 590, 224, 592, 509,//幾內亞比索,瓜得羅普島(),幾內亞,蓋亞那,海地, 504, 36, 354, 353, 91,//宏都拉斯,匈牙利,冰島,愛爾蘭,印度, 62, 98, 964, 972, 39,//印度尼西亞,伊朗,伊拉克,以色列,義大利, 225, 1876, 81, 962, 855,//象牙海岸,牙買加,日本,約旦,柬埔寨, 7, 254, 996, 686, 850,//哈薩克,肯亞,吉爾吉斯斯坦,吉里巴斯,朝鮮, 965, 856, 371, 961, 266,//科威特,寮國,拉脫維亞,黎巴嫩,賴索托, 231, 218, 4175, 370, 352,//賴比瑞亞,利比亞,列支敦斯登,立陶宛,盧森堡, 261, 265, 60, 960, 223,//馬達加斯加,馬拉維,馬來西亞,馬爾地夫,馬裡, 356, 1670, 692, 596, 230,//馬耳他,馬里亞納群島,馬紹爾群島,馬提尼克(),模里西斯, 269, 222, 691, 52, 1808,//馬約特島,茅利塔尼亞,密克羅尼西亞,墨西哥,中途島(), 373, 377, 212, 258, 95,//摩爾多瓦,摩納哥,摩洛哥,莫三比克,緬甸, 389, 976, 264, 674, 977,//馬其頓共和國,蒙古,納米比亞,諾魯,尼泊爾, 31, 64, 505, 227, 234,//荷蘭,紐西蘭,尼加拉瓜,尼日,奈及利亞, 683, 672, 47, 968, 92,//紐埃島(),諾福克島(),挪威,阿曼,巴基斯坦, 680, 507, 595, 51, 63,//帛琉,巴拿馬,巴拉圭,祕魯,菲律賓, 48, 351, 35196, 35191, 1787,//波蘭,葡萄牙,馬德拉群島(),亞速爾群島(),波多黎各(), 974, 262, 40, 7, 250,//卡達,留尼旺島(),羅馬尼亞,俄羅斯,盧安達, 684, 685, 378, 966, 221,//東薩摩亞(),西薩摩亞,聖馬利諾,沙烏地阿拉伯,塞內加爾, 248, 232, 65, 421, 386,//塞席爾,獅子山,新加坡,斯洛伐克,斯洛維尼亞, 677, 27, 252, 82, 34,//索羅門群島(),南非,索馬利亞,韓國,西班牙, 94, 290, 1758, 1784, 249,//斯里蘭卡,聖赫勒拿,聖露西亞,聖文森特島(),蘇丹, 597, 268, 46, 41, 963,//蘇利南,史瓦濟蘭,瑞典,瑞士,敘利亞, 7, 255, 66, 228, 690,//塔吉克,坦尚尼亞,泰國,多哥,托克勞群島(), 676, 216, 90, 993, 688,//湯加,突尼西亞,土耳其,土庫曼,吐瓦魯, 256, 44, 380, 598, 1,//烏干達,英國,烏克蘭,烏拉圭,美國(本土), 1808, 907, 998, 678, 3906698,//夏威夷,阿拉斯加,烏茲別克,萬那杜,梵蒂岡, 58, 84, 1284, 1340, 1808,//委內瑞拉,越南,維爾京群島(),維京京群島(),威克島(), 967, 381, 243, 260, 263,//葉門,南斯拉夫,扎伊爾,尚比亞,辛巴威, 259, 969, 689, 675, 1681,//桑給巴爾,原民主葉門地區,法屬波里尼西亞,巴布亞紐幾內亞,瓦里斯和富士那群島, 852, 853, 239, 306, 971,//香港,澳門,聖多美和普林西比,(馬爾維納斯群島),阿拉伯聯合大公國, 689, 967, 387, 1649, 1868,//波利尼西亞,原阿拉伯葉門地區,波斯尼亞和黑塞哥維那,特克斯和凱科斯群島,千里達及托巴哥, 508, 64672, 599, 687, 886,//聖皮埃爾島及密克隆島,南極,荷屬安的列斯群島,新喀里多尼亞群島(),臺灣, 1664, 1869,//蒙特塞拉特島(),聖克里斯托弗和尼維斯, }; /* 判斷國家區號,忽略+ */ private boolean isCorrectCountryCode(final String code) { try { String copyCode = code; if (code.startsWith("+")) { //如果只有一個+號,明顯地,相當於正確! if(code.length() == 1){ return true; } copyCode = copyCode.substring(1); } int int_code = Integer.parseInt(copyCode); for (int i = 0; i < countryCode.length; i++) { if (int_code == countryCode[i]) { return true; } } } catch (Exception e) { Log.d(TAG, e.toString()); } return false; }
//查詢避免由於區號引起拿不到聯絡人姓名的問題。(部分手機)
public String getContentUserName(String number) {
    Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            new String[]{
                    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null);
    Log.d(TAG, "get All phone Name!");
    String getName = null;
    String getNumber = null;
    try{
        for (; cursor != null && cursor.moveToNext(); )
        {
            getName = cursor.getString(0);
            getNumber = cursor.getString(1);
            if (getNumber == null) {
                continue;
            }
            //  \\D的原因是部分手機在電話號碼能夠填寫*#+-/等符號!
getNumber = getNumber.replaceAll("[\\D]", "");
            Log.d(TAG, "raw name is " + getName + "   raw number is " + getNumber);
            //完全相等,優先順序最高的情況。
if (getNumber.equals(number)) {
                Log.d(TAG, "equals! get the Correct Data! name is " + getName);
                cursor.close();
                return getName;
            } else if (getNumber.endsWith(number)) {
                //如果儲存的是+86+***,來電沒有+86+***的情況。
String code = getNumber.substring(0, getNumber.length() - number.length());
                Log.d(TAG, "getNumber.endsWith(number)! code is " + code);
                if (isCorrectCountryCode(code)) {
                    Log.d(TAG, "right! " + getName);
                    cursor.close();
                    return getName;
                }
            } else if (number.endsWith(getNumber)) {
                //如果儲存的是沒有+86+***,來電是+86+***的情況
String code = getNumber.substring(0, number.length() - getNumber.length());
                Log.d(TAG, "number.endsWith(getNumber)! code is " + code);
                if (isCorrectCountryCode(code)) {
                    Log.d(TAG, "right! " + getName);
                    cursor.close();
                    return getName;
                }
            }
        }
    }catch (Exception e){
        Log.d(TAG,e.toString());
    }finally {
        try{
            cursor.close();
        }catch (Exception e){
            Log.d(TAG,e.toString());
        }
    }

    return number;
}