Android对emoji表情的处理(二)
接上文 Android对emoji表情的处理
问题
之前一篇文章描述了,如何将android手机的emoji过滤掉,显示"/ufffd"(这个图标),可是人家又提问题了,说iphone手机显示的emoji数量和android机器上显示的不一致,不是1:1。
分析
在我个人看来,emoji有许多基础表情,都是用单个unicode进行编码的,比如 以下的
可是有些表情是由基础表情复合而成的,比如 国旗类,本身Android识别这些表情时,也会显示成2个字母图片
方框数字类本身就是由数字和方框图组成。
比如职业类(最复杂), 女农民
unicode是U + 1F469 U + 200D U + 1F33E
分别代表女+连接符+水稻
可以利用上篇讲到的string2Unicode方法,打印出来如下
\ud83d\udc69\u200d\ud83c\udf3e
在比如 最深色女农民
unicode是U + 1F469 U + 1F3FF U + 200D U + 1F33E
增加了1个肤色参数
\ud83d\udc69\ud83c\udfff\u200d\ud83c\udf3e
再比如 最深色女警
?U + 1F46E 警察(男)
?U + 1F3FF 最深色
U + 200D 连接符
♀U + 2640 女性
️U + FE0F 变化选择器
\ud83d\udc6e\ud83c\udfff\u200d\u2640\ufe0f
最容易的方法就是把所有表情添加到Matcher 中,找到后全部替换掉,但是表情太多,所以要找到一些规律,然后进行替换。
方法
为了不改变原来的思路,还是使用上篇的filterEmoji方法进行过滤,关键是找到过滤条件,这里用的是 正则表达式
单个表情过滤范围不变,多个表情需要找到规律进行过滤。
- 国旗类
国旗类是由2个字母组成,所以过滤条件为
[\ud83c\udde6-\ud83c\uddff][\ud83c\udde6-\ud83c\uddff]
- 数字框类
数字框是数字加框的组合
[\u0030-\u0039]\ufe0f\u20e3
- 职业类
职业类是最麻烦的,除了包括最先的一个编码,后面还可能有肤色,性别,物品等;期间还有\u200d连接符进行连接,所以我打算把除了第一个编码,后面编码全部替换为空,然后再进行2次过滤,就可以实现1:1了,确定范围如下:
"([\ud83c\udc00-\ud83c\udfff]\u200d(?:[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\ud83e\udc00-\ud83e\udfff]))" +"|([\ud83c\udffb-\ud83c\udfff]\u200d[\u2600-\uffff][\u2600-\uffff])" +"|\u200d[\u2600-\uffff][\u2600-\uffff]"+"|\u200d(?:[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\ud83e\udc00-\ud83e\udfff])"+"|[\u2640-\u2642]|[\ud83c\udffb-\ud83c\udfff]"
最终代码
最终,可以将iphone手机端的所有emoji表情可以1:1的替换为\ufffd(不支持)表情,在Android机器上显示。
比如在进行MFI认证的时候,认证机构就会要求正常显示emoji或者1:1显示不支持表情。
public class FilterEmoji
{private static FilterEmoji filterEmoji = null;private FilterEmoji(Context context){}public static FilterEmoji getInstance(Context context){if (filterEmoji == null){filterEmoji = new FilterEmoji(context);}return filterEmoji;}public String filterEmoji(String source){Log.d("FilterEmoji","before source.len --> "+source.length());if (source != null){Pattern emoji1 = Pattern.compile("([\ud83c\udc00-\ud83c\udfff]\u200d(?:[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\ud83e\udc00-\ud83e\udfff]))" +
// "|([\ud83c\udc00-\ud83c\udfff]\u200d[\ud83d\udc00-\ud83d\udfff])" +
// "|([\ud83c\udc00-\ud83c\udfff]\u200d[\ud83e\udc00-\ud83e\udfff])" +"|([\ud83c\udffb-\ud83c\udfff]\u200d[\u2600-\uffff][\u2600-\uffff])" +"|\u200d[\u2600-\uffff][\u2600-\uffff]"+"|\u200d(?:[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\ud83e\udc00-\ud83e\udfff])"+"|[\u2640-\u2642]|[\ud83c\udffb-\ud83c\udfff]",Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);Matcher emojiMatcher1 = emoji1.matcher(source);if (emojiMatcher1.find()){String s = string2Unicode(source);Log.d("FilterEmoji","before unincode --> "+s);// 空source = emojiMatcher1.replaceAll("");String s1 = string2Unicode(source);Log.d("FilterEmoji","after1 unincode --> "+s1);}Log.d("FilterEmoji","after1 source.len --> "+source.length());Pattern emoji = Pattern.compile("([\ud83c\udde6-\ud83c\uddff][\ud83c\udde6-\ud83c\uddff])|([\u0030-\u0039]\ufe0f\u20e3)|[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\ud83e\udc00-\ud83e\udfff]|[\u2500-\u29ff]|[\u20d0-\u20e2]|[\u20e4-\u20f0]|[\u2b00-\u2bff]|[\u3297-\u3299]|[\u2300-\u23ff]|[\u2190-\u21ff]|[\u24b6-\u24e9]",Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);Matcher emojiMatcher = emoji.matcher(source);if (emojiMatcher.find()){String s = string2Unicode(source);Log.d("FilterEmoji","unincode --> "+s);// \ufffdsource = emojiMatcher.replaceAll("\ufffd");String s2 = string2Unicode(source);Log.d("FilterEmoji","after2 unincode --> "+s2);return source;}Log.d("FilterEmoji","final after source.len --> "+source.length());return source;}return source;}/*** 字符串转换unicode*/public static String string2Unicode(String string){StringBuffer unicode = new StringBuffer();for (int i = 0; i < string.length(); i++){// 取出每一个字符char c = string.charAt(i);// 转换为unicodeunicode.append("\\u" + Integer.toHexString(c));}return unicode.toString();}
}
警告
如果是过滤列表的所有文字,因为比较比较耗时,可能会导致滑动列表卡顿,建议不要长期使用。
附
一些emoji的转化码
CN \ud83c\udde8\ud83c\uddf3 U+1F1E8 U+1F1F3
A U+1F1E6 \ud83c\udde6
Z U+1F1FF \ud83c\uddff3kaung \u33\ufe0f\u20e3
0 \u30\ufe0f\u20e3 U+0030 U+20E0女警颜色性别 \ud83d\udc6e\ud83c\udfff\u200d\u2640\ufe0f女警\ud83d\udc6e性别女 \u2640皮肤黑5 \ud83c\udfff 1F3FF黑4 \ud83c\udffe黑1 \ud83c\udffb男警黑4\ud83d\udc6e\ud83c\udffe工人皮肤女\ud83d\udc77\ud83c\udfff\u200d\u2640\ufe0f长帽皮肤女\ud83d\udc82\ud83c\udfff\u200d\u2640\ufe0f
侦探\ud83d\udc69\ud83c\udfff\u200d\u2695\ufe0f 女医生
\ud83d\udc69\ud83c\udfff\u200d\ud83c\udf3e 女农民
\ud83d\udc69\ud83c\udfff\u200d\ud83c\udf73 女厨师
\ud83d\udc69\ud83c\udfff\u200d\ud83c\udf93 女博士
\ud83d\udc69\ud83c\udfff\u200d\ud83c\udfa4 女歌手\ud83d\udc69\u200d\ud83d\udcbc 女包 女白领
\ud83d\udc69\ud83c\udffb\u200d\ud83d\udcbc连接 u200d ufe0f
Android对emoji表情的处理(二)相关推荐
- Android对emoji表情的处理
Android对emoji表情的处理 引言 UFT8 UFT16 举例 过滤emoji 参考 引言 公司有个项目,iphone手机连接android车机,在车机端进行ipod音乐播放,在进行MFI认证 ...
- 匹配表情emoji 正则_详解Android过滤emoji表情正则表达式
做了一些信息提交的操作,输入了Emoji表情时,后台数据库无法存储 原因:UTF-8编码有可能是两个.三个.四个字节.Emoji表情是4个字节,而Mysql的utf8编码最多3个字节,所以数据插不进去 ...
- 【笔记11】uniapp点击复制;mysql数据库存储emoji表情;Java 二维码生成;uniapp引入自定义图标
目录 前言 一.uniapp 实现点击复制某段文本 二.MySQL 数据库存储 emoji 表情 三.Layui 的富文本编辑器 四.谷歌 Java 二维码生成 (1) 引入 MAVEN 依赖 五.微 ...
- Android之Emoji表情开源库
上次做了一个表情的控件,不敢私藏,给大家分享 效果图如下,图片是新浪微博的,该有的功能应该都有了. 这其实就是一个Fragment,所以用起来很方便,只要 FaceFragment faceFragm ...
- 修改Android手机的emoji表情(NotoColorEmoji.ttf)
过程综述 1.Android手机需要root,因为需要访问/system/fonts/NotoColorEmoji.ttf修改 2.需要NotoColorEmoji.ttf对应的库,比如你想要修改成i ...
- php微信Emoji表情处理
一.适用场景 通过代码实现微信Emoji表情处理. 二.相关代码 1.字节转Emoji表情 /*** 字节转Emoji表情* @author php_elephant* @param $cp 数据* ...
- 【Android】显示Emoji表情字符
一.下载AndroidEmoji.ttf字体 地址1:Github Android Platform 地址2:AndroidEmoji.ttf.zip 二.使用 2.1 将字体拷贝到assets/fo ...
- 在Android系统中使用系统自带的emoji表情
一,对emoji表情的理解 emoji表情是一种表情符号,在代码中它现在其实是一组遵循Unicode的编码,即每一个表情符号都对应了一个Unicode编码.更进一步说,emoji表情实际上是一组Uni ...
- android 兼容ios emoji,Emoji表情符號兼容方案(適用ios,android,wp等平台)
emoji就是表情符號:詞義來自日語(えもじ,e-moji,moji在日語中的含義是字符) 表情符號現已普遍應用於手機短信和網絡聊天軟件. emoji表情符號,在外國的手機短信里面已經是很流行使用的一 ...
最新文章
- 2021人工智能年度评选结果揭晓!AI落地最佳参考在此奉上
- python编程入门书-读书笔记之《编程小白的第1本Python入门书》
- windows python读取grib2数据
- linux/CentOS 6忘记root密码解决办法
- php实现把es6转为es5,如何将ES6代码转化为ES5?
- Android Gradle和Gradle插件区别
- html离线地图,离线地图三维开发-添加HTML
- “轻量级的”Istio,微软开源了一个基于 Envoy 的服务网格
- 马化腾谈滴滴;苹果供应商研发柔性玻璃;丁磊谈沉迷手机 | 极客头条
- 等长子网划分、变长子网划分(网络整理)
- Python教程大纲
- 关于USB-Audio(USB麦克风)设备的录音验证
- iOS悬浮、可拖动、自动吸附屏幕边缘的按钮制作
- 关系图谱在反欺诈场景中的应用及实践
- git log 查找某天之后的提交
- java cursor_cursor的基本使用方法
- 第五章、DOS基本命令与批处理(千峰网络安全300课时笔记)
- 【独立版】翻牌领红包系统一物一码仿口味王验证码抽奖码得红包追溯码源码程序无加密
- 什么是注入式攻击,如何防止sql注入式攻击。
- SQL优化 - Group By 导致的慢sql