将 phone 号码与来自任何国家 (algorithm/library/anything) 的来电 phone 电话号码进行比较

Compare phone number with incoming phone call number from ANY country (algorithm/library/anything)

如何让我的应用程序知道正在呼叫哪个联系人姓名?如果可能的话,我希望该应用程序能够检查整个号码。我在 SO 上看到有人说只检查数字的一部分,这是一个部分解决方案。但是是否可以检查整个数字?我想一定是这样,因为 Dialer 总是知道谁在给我打电话(除非他们通过获取 phone 的国家或其他东西在某个地方作弊)。

例如在葡萄牙,我们有 +351 123 456 789。在其他国家,号码或大或小,代码也不同。从我在这里看到的 (https://en.wikipedia.org/wiki/E.164):

As described in by the ITU, the E.164 general format must contain only digits split as follows:

- Country code (1 to 3 digits)
- Subscriber number (max 12 digits)

所以我无法检查删除前 3 位数字,因为有些国家/地区有 1 位或 2 位数字。我也无法检查 12 位数字,因为一开始,在葡萄牙我们只有 9 位。我读到有 7 位数字的国家,所以这是最小值,12 位是最大值。但我必须输入最小值,否则可能会弄错数字。但拨号器应用程序总是以某种方式知道。有谁知道如何正确地做到这一点?

我已经考虑过检查所有国家/地区的所有代码(需要一个列表)并检查第一位数字以查看是否与任何国家/地区代码匹配。但是出现了两个问题:我必须更新它,更重要的是,假设一个国家/地区的代码为 +35。然后这个人的号码以1开头。那是+351,来自葡萄牙。不知道如何避免这些情况。

希望有更简单的方法,甚至可能是 Google 中我不知道的一些 class,或者一些图书馆,如果不知道,也许有人有更好的想法。

以防万一它可能有用,这里有来自维基百科的 link 所有国家代码:https://en.wikipedia.org/wiki/National_conventions_for_writing_telephone_numbers.

如有任何帮助,我们将不胜感激!

注意: 我还没有把 Android 放在标签上,但我正在努力。这对问题无关紧要,因为我只需要知道算法,除非有一些更简单的方法来检查 Android 库中的 phone 数字或与 Android 相关的任何内容,并且在那种情况下,我优先考虑 Android 解决方案。

更新: 我可以从头到尾检查两个数字,看看它们是否匹配,直到较小的一端。例如 +351 123 456 789 呼叫,我只保存了 123 456 789。但在另一个国家,号码可能是 +35 1123 456 789,在这种情况下,我会排除一些国家的国家代码。还有其他想法吗?

为什么要删除国家/地区代码?他们属于phone号。

有没有国家代码你不用搞清楚。来电与通讯录比较时,只需检查来电号码的长度和通讯录中的号码即可。

如果主叫号码较长,只需将 delta 替换为 0(因为来自国内的电话将以 0 作为前缀)。然后进行比较数字。 如果你保存了一个国际号码,它也会存储国家代码,这样你就可以比较它们。

例如:

打电话: +351 123 456 789 -> 长度为 13 位数字(包括 +)

保存的联系人: 0123 456 789 -> 长度为 10 个数字

+35 将替换为 0,数字相同。

我在 GitHub 上从 Google 本身发现了这个存储库:https://github.com/google/libphonenumber. Seems it's what they use since Android 4. Then I found out the library is already in the Android SDK (since API 1, so I'm confused on when they started using this, but anyways): android.telephony.PhoneNumberUtils (https://developer.android.com/reference/android/telephony/PhoneNumberUtils)。上面有一个 compare() 方法说:

Compare phone numbers a and b, and return true if they're identical enough for caller ID purposes.

不知道“足够”是什么意思,但这是 Google,据我所知,拨号器工作得很好,所以我相信它实际上已经足够好了。

另外 [作为对我所写内容的更新,我刚刚发现] 有 2 个 compare() 方法。由于我无法从 Android 开发者网站理解需要上下文的人实际上在做什么,所以我偶然找到了这个答案,它解释了它: (inside thread ). Very good idea to read that. The conclusion from there seems to be to use the method that requires the context, so that the phone can get if the carrier allows you to use the strict method (the compare(String, String) method always uses the loose comparision, at least for now: "We've used loose comparation at least Eclair, which may change in the future."). Strict would be the best, it seems (search "1-650-555-1234" here: https://android.googlesource.com/platform/frameworks/base/+/master/telephony/java/android/telephony/PhoneNumberUtils.java 并阅读了那里的内容,但没有'发生在松散的比较上(我在对上面链接的答案的评论中测试了这一点)。

如果您有内部方法并且 类 显示,您可以强制应用程序使用它,就像我刚才做的那样 xD。只是不确定这是否有缺点,因为我强迫它,但它似乎工作,即使我的运营商似乎不允许它(我所做的知道这是我上面链接的答案)。当我直接调用 compareStrictly(String, String) 时,完全按照我所说的搜索源代码的方式工作。

现在。该方法还有另一个版本:compareStrictly(String, String, boolean),其中 boolean 参数显示为 acceptInvalidCCCPrefix。我可以用 false 来称呼它,但我不知道我实际上在做什么,因为对该方法的调用总是带有 true 的源代码 PhoneNumberUtils。想知道我是否可以将其设为 false,以便它检测得更好,或者如果它是 true 因为它还没有准备好或其他什么,如 compareStrictly(String, String, boolean) 源代码中所读,下面 4 行 if (okToIgnorePrefix) {(我不明白他们在那里的意思) - 如果有人知道我是否可以把它说成假的,请说些什么(如果有人知道 CCC 前缀是什么意思,也请说些什么,因为我没有找到任何 conciso Google 我可以肯定是那样的人)。

GitHub上的库不仅在Java中,所以我已经删除了语言来自线程的标记。它是在 C++、Java 和 JavaScript 中正式使用的,并且有其他语言的端口,如 Go、C#、Objective-C、PHP、Python、 ......,所有链接都在 Google 存储库中。希望存储库中的库包含 Android 源代码的所有内容(我没有检查,但我想它应该包含所有内容)。