Android对emoji表情的处理

Android对emoji表情的处理

  • 引言
  • UFT8
  • UFT16
    • 举例
  • 过滤emoji
  • 参考

引言

公司有个项目,iphone手机连接android车机,在车机端进行ipod音乐播放,在进行MFI认证的时候出了问题。认证机构给的列表和歌曲带有表情符号,结果软件就崩了,是底层转码时出问题了。后来底层转码用Unicode,发现android(4.4.2)显示的表情和iphone手机显示的不一样,这个可以参考https://apps.timwhitlock.info/emoji/tables/unicode,android根据码转为自带的表情。后来又发现android车机上显示不少长方形中间带×的符号在这里插入图片描述,推测可能是有些新的符号没有在android4.4中定义,所以显示了这个符号。为了过认证,我们尽量将所有符号,显示成◆带?的形式(Unicode:\ufffd)。

UFT8

在Java里UTF-8,只支持双字节即\u0000-\uFFFF,emoji(?) => “\uD83D\uDC34”
查Symbola表,我们的目标对象大致是从
1F300-1F3FF => “\uD83C\uDF00” - “\uD83C\uDFFF”
1F400-1F4FF => “\uD83D\uDC00” - “\uD83D\uDCFF”
1F500-1F5FF => “\uD83D\uDD00” - “\uD83D\uDDFF”
1F600-1F6FF => “\uD83D\uDE00” - “\uD83D\uDEFF”
1F700-1F7FF => “\uD83D\uDF00” - “\uD83D\uDFFF”

UFT16

UTF-16就利用保留下来的0xD800-0xDFFF区段的码位来对辅助平面的字符的码位进行编码

lead \ trail DC00 DC01 DFFF
D800 10000 10001 103FF
D801 10400 10401 107FF
D8FF 10FC00 10FC01 10FFFF

举例

例如U+10437编码:

0x10437减去0x10000,结果为0x00437,二进制为0000 0000 0100 0011 0111。
分区它的上10位值和下10位值(使用二进制):0000000001 and 0000110111。
添加0xD800到上值,以形成高位:0xD800 + 0x0001 = 0xD801。
添加0xDC00到下值,以形成低位:0xDC00 + 0x0037 = 0xDC37。

过滤emoji

public String filterEmoji(String source)
	{
		if (source != null)
		{
			Pattern emoji = Pattern
					.compile(
							"[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
							Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
			Matcher emojiMatcher = emoji.matcher(source);
			if (emojiMatcher.find())
			{
				// \ufffd  ◆?符号
				source = emojiMatcher.replaceAll("\ufffd");
				return source;
			}
			return source;
		}
		return source;
	}

这个代码已经能屏蔽大部分emoji表情,可是iphone手机还有其它表情:物体、符号、旗帜、旅行、活动、实物,
对着symbola表(链接:https://pan.baidu.com/s/1yVUIk9nZM5PGKVGRE1_Www 提取码:ef5q )2015版图片表情所对应的UNICODE
在手机端输入表情,然后日志打印出码,再写过滤范围。
这里需要注意把String转换为UNICODE:

	//字符串转换unicode
	public static String string2Unicode(String string)
	{

		StringBuffer unicode = new StringBuffer();

		for (int i = 0; i < string.length(); i++)
		{

			// 取出每一个字符
			char c = string.charAt(i);

			// 转换为unicode
			unicode.append("\\u" + Integer.toHexString(c));
		}

		return unicode.toString();
	}

最终过滤范围是

[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\ud83e\udc00-\ud83e\udfff]|[\u2500-\u29ff]|[\u20d0-\u20f0]|[\u2b00-\u2bff]|[\u3297-\u3299]|[\u2300-\u23ff]|[\u2190-\u21ff]|[\u24b6-\u24e9]

后续看下文 Android对emoji表情的处理(二)

参考

1.https://apps.timwhitlock.info/emoji/tables/unicode
2.symbola表(链接:https://pan.baidu.com/s/1yVUIk9nZM5PGKVGRE1_Www 提取码:ef5q )

你可能感兴趣的:(emoji)