检测Unicode字符是否被支持?

7
我正在尝试制作一个小型Android应用程序,可以随机向用户返回表情符号。我的意图是只使用实际的Unicode表情符号,并将它们作为Unicode字符串字符返回。
我构建了一个完整的Unicode字符串数组,可以从中随机选择许多字符并正确显示。然而,有些字符显示为不支持的字符(一个带有x的矩形)。
显然,不是每个平台都支持每个Unicode表情符号,但如果可能的话,我想知道如何确定哪些是受支持的字符。理想情况下,可以查询支持的字符列表,但测试单个字符也可以胜任。

你找到解决方案了吗?谢谢! - Maragues
1
@Maragues 很遗憾,我只能放弃了。我决定使用一个常量数组,手动定义一些安全的表情符号,这样才能保证它们能够正常工作。 - SuperBiasedMan
看起来Android 23确实包含了一些东西(https://developer.android.com/reference/android/graphics/Paint.html#hasGlyph(java.lang.String)),但是代码调用了一个本地函数,所以我想我运气不好。感谢您的快速回复。 - Maragues
@Maragues,你为什么这么倒霉?是因为你需要支持API 23之前的版本还是因为“hasGlyph”对你不起作用? - Suragch
我甚至都不记得我当时在尝试做什么了 :( - Maragues
3个回答

6
此外,还可以查看API 23中添加的Paint.hasGlyph(String)。您可以使用它来测试是否有一个字符(比如表情符号)可用。
以下是文档中的说明:

boolean hasGlyph (String string)

确定绘制的字体是否支持字符串中的字符。最简单的情况是字符串只包含一个字符,在这种情况下,此方法将确定字体是否具有该字符。对于多个字符,如果存在表示连字的单个字形,则该方法返回true。例如,如果输入是一对区域指示符号,则确定该对是否有一个表情旗帜。

最后,如果字符串包含变量选择器,则该方法仅在字体包含特定于该变量的字形时才返回true。

检查是在整个回退链上进行的,而不仅仅是立即引用的字体。

另请参见:

那是在Paint上。 - clwhisk

5
因此,当你谈论一个字符“不支持”时,听起来你的意思是当前字体没有该字符的字形(并且应用程序没有回退逻辑来查找另一个具有该字形的字体,或者系统没有任何具有该字形的字体)。
在常规Java中,这很容易:给定java.awt.Font的实例,您可以使用 canDisplay方法查看它是否具有给定Unicode字符的字形。
出于某种原因,Android API似乎没有公开一种方法来确定您实际使用的字体。 (android.graphics.Typeface将该信息保留为私有信息:请参见“在Android中检查Typeface对象的系列”。) 但是,您可以尝试像new java.awt.Font("SansSerif", java.awt.Font.PLAIN, 12)这样的东西,以获得基本的12点无衬线字体。当然,您需要测试,以查看是否对于真正的字体将能够显示的表情符号,它是否提供了可用的近似值。

你对我的意思理解得非常准确。感谢提供的信息!似乎Android API根本不包括java.awt.Font,所以我无法导入它并使用该方法。但我会尝试使用Typeface,并将其转换为更可用的字体,或者仅在我知道字形不受支持的情况下尝试设置默认字体。 - SuperBiasedMan
哦,奇怪 - 我没有意识到Android省略了JDK的一些部分。(如果你没注意到,我不是一个Android开发者。:-P) - ruakh

3
您可以使用Character.isDefined来检查设备上Unicode版本中是否定义了字符。

啊,这是一个好的线索。谢谢!不幸的是它只偶尔能捕捉到问题。有很多误报,这让我觉得它在Android上没有被正确实现。 - SuperBiasedMan
Character.isDefined 的意思是“JVM 知道这个字符是什么类型的吗?”(例如,它是否为空格、数字或其他类型),而 OP 想要知道“当前字体是否有这个字符的字形?” - ruakh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接