【wwwmgm8001】处理方式,官方兼容库

同样是 Tumblr 上的热门相册,Emoji IRL.
LOL.是设计师
Liza Nelson 的作品。她选择用真实世界还原表达 emoji。「BECAUSE SOMEBODY
HAD TO DO IT.」

EmojiCompat Support Library 的诞生

正是由于上文提到的兼容问题,Google 官方的 EmojiCompat Support
Library
诞生了。

目前这个库能向下兼容到 Android 4.4,其主要目标就是为了让我们的 Android
设备能够支持最新的 emoji 表情,防止最新的 emoji
表情在我们的手机上显示为☐。

Emoji 对照

EmojiCompat 通过 CharSequence 文本中的 emoji 对应的 unicode 编码来识别
emoji 表情,将他们替换成 EmojiSpans ,最后再将 EmojiSpan 渲染成对应的
emoji 表情符号。

emojiCompat处理过程

对于 EmojiCompat 的使用,有两种配置方式:

1:andriod和iOS的emoji并不相同,相同的编码
可能在iOS上是太阳,而在andriod上是阴天,解决这种问题方式最好做下iOS和andriod下的emoji映射,同时可以在web上通过js转义处理。

你或许要向别人解释为何喜欢「御姐」、为何喜欢「黑长直」、为何喜欢「双马尾」,但你不需要解释为何喜欢
emoji。图形和表情比纯文字更能表达情感,这几乎是一个不需要学术报告来支撑的论点了。当然,作为一种社交语言,emoji
的流行也要归功于「社会镜子」(social mirroring)。

Bundled fonts configuration

Bundled fonts【wwwmgm8001】处理方式,官方兼容库。 即打包字体,就是使用本地打包好的 emoji 字体库来兼容
emoji 表情。

目前官方使用的是 NotoColorEmojiCompat.ttf 字体文件。


从上面的信息,从数据库层面如果不是特别看重存储,性能,运维并能解决上下游的问题,数据库是完全可以支持emoji的,但是有个新问题没有解决,emoji在iOS上展示OK,andriod设备如何展示emoji表情?

对,我说的就是乌克兰艺术家 Nastya Nudnik 的 Emoji Nation
的作品。将经典名画与网络时代相结合,恐怕最严肃的评论家看到这毫无违和感的画作,也要大呼一声「Déjà
vu」啦。

添加依赖库

首先我们在 build.gradle 中配置我们的依赖包,由于我们使用的是 Bundled
fonts 的配置,所以我们需要先引入我们的 emoji bundle 库:

dependencies {
    ...
    compile "com.android.support:support-emoji-bundled:$version"
}

这里我 $version 设置的版本是
26.0.0-beta1,如果编译过程中提示找不到依赖库,需要在 repositories
仓库配置中加入 Google 的 maven 地址:

allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
    }
}

接着我们引入 EmojiCompat 的组件库:

dependencies {
    ...
    compile "com.android.support:support-emoji:26.0.0-beta1"
}

该组件库对应的 emojiCompat 组件:

<android.support.text.emoji.widget.EmojiTextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

<android.support.text.emoji.widget.EmojiEditText
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

<android.support.text.emoji.widget.EmojiButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

如果你使用的是 AppCompat 库, 也可以直接添加 emojiCompat 的 compat
组件库

dependencies {
      compile "com.android.support:support-emoji-appcompat:26.0.0-beta1"
}

该引用库对应的组件:

<android.support.text.emoji.widget.EmojiAppCompatTextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

<android.support.text.emoji.widget.EmojiAppCompatEditText
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

<android.support.text.emoji.widget.EmojiAppCompatButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

【wwwmgm8001】处理方式,官方兼容库。compat 库跟非 compat
库之间的差别主要就是在使用的组件名称上,其他的方式基本一致。

解决方案:过滤解决

不同于 Unicode 协会官方的严肃做派,在对待 emoji
这件趣物上,全世界有创造力的人们可没有这么「正襟危坐」。Emoji 这种俨然化身为新生语言的小小表情块,已成为了一种「谜米/梗」(meme)。艺术圈、时尚圈、科技圈、平民圈,到底有多爱,还是要看脑洞有多开,有没有彻底将其玩坏。

Downloadable fonts configuration

【wwwmgm8001】处理方式,官方兼容库。Downloadable fonts【wwwmgm8001】处理方式,官方兼容库。 是 Android O 新增的一个功能,支持通过 google
mobile service 远程拉取需要的字体库到本地来进行使用。

由于国内屏蔽了 Google Service
,所以这种方式在国内我们使用不了,这里我们就不做详细介绍了。

emoji介绍

2014 年,一个字:「❤」。

不通过组件使用 emojiCompat 兼容库

EmojiCompat 库通过 EmojiSpan 来渲染正确的表情图片,因此需要先将文本
CharSequence 根据 emoji 编码转换成对应的 EmojiSpan Spanned 实例。

EmojiCompat 专门提供了一个
process() 方法用于CHarSequence
实例的转换

使用这种方法,我们可以缓存处理过的实例而不是原始字符串,在需要使用的地方直接调用该实例,从而提高应用程序的性能。

TextView regularTextView = findViewById(R.id.regular_text_view);

CharSequence processed = EmojiCompat.get().process("neutral face \uD83D\uDE10");

regularTextView.setText(processed);

1:unicode emoji转softbank的emoji。

嘿,是不是有种小九九都被揭穿的感觉?开了又开的脑洞,多了又多的表情,emoji
家族真是日益丰富了。从 Unicode 6.0 时的 722 个表情包,到 2014 年 6
月发布 7.0 版本后新增的 250
个表情,如今你看到的所有日常物件,几乎都能找到对应的小图像了。比如,2013
年 iOS 6 更新时就多了这个:

什么是 emoji?

emoji 是一种
表情符号,来自日语词汇“絵文字”(假名为“えもじ”,读音即
emoji)

它的创造者是日本人栗田穰崇 ( Shigetaka Kurita )
,他将目光投向儿时的各种元素以获取灵感,如日本漫画和日本汉字等。“日本漫画中有许多不同的符号。漫画家会画出一些表情,表现一个人满头大汗或是迸发出一个想法时头上出现一个灯泡。”同时,从日本汉字中他获得了一种能力,用简单的字符来表达“秘密”和“爱”等抽象概念。

image.png

早期的 emoji 表情并没有一套统一的规范,日本的三大电信运营商,NTT
DoCoMo,au/KDDI,Softbank 都各自有一套关于 Emoji
的编码规范,导致运营商用户之间发送 emoji 表情时无法显示。

直到2010年10月,随着 Unicode6.0 的发布,Emoji
的编码以及对应的表情图片正式被规范化,核心 Emoji 表情包含722个 Emoji
编码。

之后 2014年6月15日发布的 Unicode 7.0 规范以及 2016年6月22日发布的
Unicode 9 规范都不断地加入新的 emoji 表情,目前整个 emoji
表情已经达到了一千多个。

感兴趣的同学可以到这里查看所有表情对应的编码

emoji
表情列表


面临问题:

那为什么 emoji 表情中人脸都是黄色的?咦,好像 QQ
表情也是黄色?难道是因为分别起源于日本、中国,黄种人开挂后的选择吗?

Android 对 emoji 表情的兼容

很多同学可能并没有注意到 Android 设备上的 Emoji 表情

一般情况下,我们在手机上进行操作时, 只有使用了输入法自带的表情及 emoji
表情才会在文本中产生 emoji 编码。

image.png

image.png

在 Android 4.4 之前, Android 并不支持 emoji
表情,当时的解决方案主要是通过 imageSpan 配合
spannableString,来替换掉文字中的 emoji unicode 编码符号。

从 Android 4.4 开始, 官方开始了 emoji
表情的支持,实现原理基本就是通过把 emoji 表情内置在系统的 ttf
字体库中,对文本进行过滤后显示出 emoji 表情。

由于不同 Android 版本内置的 ttf 字体库对 emoji
表情的版本支持程度不同,导致老版本的 Android 对最新的 emoji
表情支持不全,所以一些 在新的 unicode 版本规范中被加入的 emoji
表情在老的 Android 设备上会显示方框乱码。

为了处理这个问题,除去上文提到的 spannable
的处理方案,我们还可以通过定义自己的 ttf 字体库给文本空间指定字体来显示
emoji 表情。


然后,修改 MySQL 的配置文件 /etc/my.cnf,修改连接默认字符集为 utf8mb4
,如果是自己写的 PHP 脚本,也可以在连接数据库以后首先执行一句 SQL: SET
NAMES utf8mb4;。这时候,PHP 应该就可以正常保存 Emoji 到数据库了。

创造力满满的不限于软件,最热的硬件概念也来了。有人尝试在众筹网站
Kickstarter 集资开发 iOS 8 的专用键盘 Next
Keyboard,其键盘右上方的
emoji 快捷键就是为表情狂魔特意准备:emoji
秒发、爽快,情绪表达一点也误不了。

总结

看了上面的使用步骤,EmojiCompat 的使用是不是很方便呢?

目前来说,EmojiCompat 只兼容 Android 4.4 以上的设备,对于 4.4
以下的设备,它的行为跟普通的 Android 组件没有差异。

EmojiCompat 的初始化时间大约只需要 150
毫秒,内存的占用大概在200kb,所以你可以放心大胆地去使用它。

这里是官方的 Demo 地址:
https://github.com/googlesamples/android-EmojiCompat

里面包含了 downloadable fonts 的使用,因为比较完善 ,所以就不放我自己的
Demo 啦,感兴趣的小伙伴赶紧去下载看看吧!

比如emoji的太阳符号,他的unicode
emoji编码为U+2600,在存入数据库时,可以把它转换成 UBB 代码
[emoji]2600[/emoji]
保存,读取的时候,可以转换回来。当然针对不同的设备,比如andriod我们可以转义成andriod可以处理的emoji符号。

好奇之下,我一并测试了其他搜索引擎,发现百度搜索也能识别
emoji,但机制却不同。百度会将 emoji
直接作为关键词,结果显示含有同样表情的网页,是相对本地化的做法(毕竟
emoji
对应的默认语义是英文)。那么谷歌呢?嗯,不支持……不过还好,反正大家用不到。

EmojiCompat 的使用

接下来我们来看看如何使用 emojiCompat 库

参考资料

当然,热情最高涨的,还是科技圈。打开 Product Hunt
搜索关键词「emoji」能得到 61 个 App
搜索结果。除了一般的图片类
App 外,还有不少的趣味小应用。比如:LinkedIn 前员工做的文字与 emoji
的阅后即焚应用「Addappt」;emoji 键盘「Keymoji」;可以输入文字自动转换为
emoji 的「Emojimo」;以及能用 emoji
的情绪来推荐音乐的「Strings.fm」。那个只能用绘文字聊天的网站emoji.ly也上线了手机应用;当然,「得幸」于只能用
emoji 设置用户名的「洁癖」设定,你恐怕已注册不到想要的萌萌哒名字咯。

自定义 EmojiCompat 组件

除了上面提到的通过 EmojiCompat 的 process 方法转换 spanned
实例外,我们还可以通过官方提供的两个 widget helper 类来自定义我们的
TextView 以及 EditTextView 组件:

android.support.text.emoji.widget.EmojiTextViewHelper
android.support.text.emoji.widget.EmojiEditTextHelper

示例代码:

自定义Emoji TextView

public class MyTextView extends AppCompatTextView {
   ...
   public MyTextView(Context context) {
       super(context);
       init();
   }
   ...
   private void init() {
       getEmojiTextViewHelper().updateTransformationMethod();
   }

   @Override
   public void setFilters(InputFilter[] filters) {
       super.setFilters(getEmojiTextViewHelper().getFilters(filters));
   }

   @Override
   public void setAllCaps(boolean allCaps) {
       super.setAllCaps(allCaps);
       getEmojiTextViewHelper().setAllCaps(allCaps);
   }

   private EmojiTextViewHelper getEmojiTextViewHelper() {
       ...
   }
}

自定义 Emoji EditText

public class MyEditText extends AppCompatEditText {
   ...
   public MyEditText(Context context) {
       super(context);
       init();
   }
   ...
   private void init() {
       super.setKeyListener(getEmojiEditTextHelper().getKeyListener(getKeyListener()));
   }

   @Override
   public void setKeyListener(android.text.method.KeyListener keyListener) {
       super.setKeyListener(getEmojiEditTextHelper().getKeyListener(keyListener));
   }

   @Override
   public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
       InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
       return getEmojiEditTextHelper().onCreateInputConnection(inputConnection, outAttrs);
   }

   private EmojiEditTextHelper getEmojiEditTextHelper() {
       ...
   }
}

性能:由于以上原因,加上字符集大,utf8mb4的性能可能比utf8系列的collations低,可以参考stackoverfolow上的一个测试结果:http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci,差异不是特别大。

如此正式严谨,Unicode 协会颇有种最高「行业标准」的感觉。在 2014 年 11
月,Unicode 就发布了一份新草案,支持 emoji
显示不同肤色,而不再是之前单一的黄色。该草案由苹果和谷歌工程师提出,而他们也是
Unicode 协会的总裁。注重多样性开发,发起 emoji 界的「平权运动」,Unicode
标准似乎真的会有提纲挈领的效果。

初始化 EmojiCompat

在正式使用 EmojiCompat 之前我们还需要对其进行初始化

public class MyApplication extends Application {
@Override
    public void onCreate() {
       super.onCreate();
       EmojiCompat.Config config = new BundledEmojiCompatConfig(this);
       EmojiCompat.init(config);
    }
}

此时我们便可以使用上一步添加的 emojiCompat 组件来替换原有的 TextView、
EditText 以及 Button 组件了,当文本中遇到对应的 emoji
表情编码时就会自动替换为 emoji 表情了。

device-2017-06-30-134851.png

这种转移,可以很好解决iOS和Andriod显示emoji的问题,但是还存在几个问题。

一个小表情,「你懂的」,以后妹子再也不用尴尬地说「他有男朋友了」。可正当我想为
emoji 的机智点赞时,一个吃货对我咆哮了:

unicode定义的emoji是四个字符,softbank为3个字符,emoji的四个字符从存储到展示对应没有做过考虑的系统来说,简直就是灾难。

而究竟哪些表情可以纳入 emoji 标准,还是要由 Unicode
协会决定。我很正经地讲哦:你可以自己画个「辣条」,但想要被 Unicode
采纳,必须填写一份申请表,并提供证明,该 emoji
已被广泛使用、且仍会被继续使用,然后等待一段长期的、正式的审批过程。一个标准化的提案可能需要几年时间,每个申报字符的所有细节都会被仔细检查。

把emoji直接过滤掉,简单方便有效。虽然损失了几个emoji字符,但强过不至于导致整条记录丢失。

相关文章