项目中遇到需要通过来电号码获取到联系人姓名的需求。

然而,简单地通过联系人数据库的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;
}

Android通过来电号码识别姓名。相关推荐

  1. android 改变来电号码,Android8.1 MTK平台 Dialer修改(来电全屏、归属地显示)

    来电默认全屏 默认情况下,来电android是以通知窗口的形式显示,只在屏幕的顶部显示,现在改为全屏显示 修改位置 alps\vendor\mediatek\proprietary\packages\ ...

  2. Android设置来电号码归属地

    FAQ Content [DESCRIPTION] 如何关闭MTK内置来电号码归属地? [SOLUTION]   MTK平台号码归属地分为两种:1.手机号码归属地:2.固话号码归属地:   手机号码归 ...

  3. android来电电话获取,Android获取来电号码代码

    对于Android平台的整个来电软件制作十分简单,Android平台在各方面都比较智能,加上一个BOOT_COMPLETED获取,保证开机自动运行,一个来电通就很容易的制作完成了. Android来电 ...

  4. android获取来电号码,Android获取来电号码代码详解

    对于Android平台的整个来电软件制作十分简单,Android平台在各方面都比较智能,加上一个BOOT_COMPLETED获取,保证开机自动运行,一个来电通就很容易的制作完成了. Android来电 ...

  5. Android 获取来电号码和去电号码

    转载请注明出处: http://blog.csdn.net/like_program/article/details/52662942 这篇博客将讲解 Android 如何获取来电号码和去电号码. 打 ...

  6. Android中来电号码归属地的显示

    昨日实现了360手机卫士的来电显示归属地的功能,具体的功能就是当来电的时候,界面会弹出来一个自定义的土司,显示当前号码的归属地,学习之后发现操作非常的简单,总结下加强自己的回忆. 具体细节大概为:别人 ...

  7. Android 号牌号码识别,支持新能源车牌,离线识别

    少废话,直接开始 项目地址https://github.com/ccc920123/LicensePlateDemo 方式一 项目build.gradle添加 allprojects { reposi ...

  8. android手机来电自动报名字,读短信来电报姓名

    读短信来电报姓名,帮助用户自动读短信.报出来电人姓名,让您在不方便的时候能够轻松查看短信信息,知晓来电人姓名.软件还拥有语音提醒.讲笑话.英语测评等特色功能,让您的生活更加便捷. 软件介绍: 开车的时 ...

  9. (转)Asterisk模拟线FXO的主叫号码识别(来电显示)

    CID (CallerID,CLID,主叫号码,来电显示)是在实际使用中常遇到的另外一个常见问题,主叫号码格式分为FSK(美规)或DTMF方式.主叫号码可能会在第一声振铃之前送过来,也可能在第一声振铃 ...

最新文章

  1. 结构化数据不应该被人工智能忘之脑后 !
  2. Unity3d中角色模型和角色名字保持相对位置
  3. python创建一个字典、关键字为只包含字母的字符串_探究Python源码,终于弄懂了字符串驻留技术...
  4. python 在主线程开线程_Python开启线程,在函数中开线程的实例
  5. 内部链接和外部链接【转】
  6. QWidget: Must construct a QApplication before a QPaintDevice
  7. python delete_python 使用 delete 方法时报错,可以正常删除
  8. IllegalArgumentException:@Body parameters cannot be used with form or multi-part encoding
  9. weakhashmap_Java WeakHashMap size()方法与示例
  10. python 线性规划问题_一学高数,线代就头疼?让python帮你解决(内含教程)
  11. MDI多窗体1130
  12. win98装python_Windows 上的 Python安装
  13. 数据库——实体联系模型
  14. 《别做正常的傻瓜》 读书笔记
  15. Android页面的跳转
  16. 1041 例题4-2 比较交换实数值
  17. 解决win10下PPT打不开,显示内容有问题,提示修复但修复不成功问题
  18. 基于c语言c8051f系列微控制器原理与应用,基于C语言C8051F系列微控制器原理与应用...
  19. Origin复制到PPT中无法打开
  20. 世界卫生组织国际癌症研究机构致癌物清单

热门文章

  1. 卷积神经网络权重,特征图计算
  2. [Python]等额本息房贷计算器
  3. 手机扫描答题卡阅卷的小程序
  4. 使用Hypothesis生成测试数据
  5. Mybatis-Plus根据时间段去查询数据
  6. mysql的连接配置时区语句
  7. 开源游戏服务器框架汇总
  8. yahoo邮箱foxmail收发
  9. mysql基本用法笔记
  10. End-to-End Object Detection with Fully Convolutional Network