UnifiedEmoji表情forAndroid

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Unified Emoji表情for Android

这个是我做Android以来碰到的最烦的东西,该死的emoji表情,恨之入骨。。无奈这个问题分配给我了。我也只能硬着头皮做。

0.吐个槽先

首先,你要明白什么是emoji表情,不知道的google,不需要支持emoji的可以绕道了。

emoji有很多不同的版本,我tm最讨厌的就是不同版本的了。

Unified DoCoMo KDDI Softbank Google

因为ios5升级了,emoji编码从softbank变成unified了。所以只能Android这边改了。伤心。

我要做的工作就是把消息中含有的unified的emoji编码过滤出来,然后映射出对应的表情资源显示出来。

1.准备工作。

google下emoji表情的历史,google code上有个源码,不过是java的,那么你要把它改成java的。。(记得当初解析gif表情时也是把java改成android,可怜的我为咩总是干这活。。)

这里有个link,上面有所有的编码对应转换。Emoji for PHP

然后google code里有所有对应的编码转换的xml。叫emoji4unicode.xml. 这里是

link:emoji4unicode

如果没兴趣我等下会直接贴代码的,但是最好你先自己弄明白解析的原理是什么,emoji 表情一直在增加,以后要兼容你就得自己想办法了。

2.举个例子

black sun with rays unified : U+2600 softbank: U+E04A

如果以前你解析过softbank,应该很熟悉了。好歹它还有个大致得顺序,解析得时候只要判断是否在这个unicode范围内就可以了。so easy

可是unified完全是无顺序得,所以必须得自己建好映射。

因为原始的emoji.xml很大,把所有的描述信息都放里面了,我不需要,所以我写了个java 把xml解析了一遍,然后重新生成了一个我需要的xml。贴个图出来大家看下。

you see , 这个原始的xml 实在太大了,有162K ,而且还是xml 解析。。你想想多耗内存和时间。所以必须把它再转换一遍。

so 这个过程做好了,就可以进行下一步真正的解析了。。

3 解析过程。

因为emoji 是有表情分组的,所以你要优先考虑解析出来的也是分好组的。

HashMap> emoMap = new HashMap

ArrayList>();

我是这么来分组的。

解析xml,然后把2600这样的字符串转换成unicode。这个很关键,映射对应不上肯定也解析不出来。要注意的一点是有的emoji是两个unicode组成的 U+1F1F0 U+1F1F7 这样。。所以么。又多了一个环节。

HashMap, String> convertMap = new HashMap, String>();

再定义一个map来存unicode和string字符的映射。

if (xmlpull.getName().equals("e")) {

fromAttr = xmlpull.nextText();

emos.add(fromAttr);

List fromCodePoints = new ArrayList();

if (fromAttr.length() > 6) {

String[] froms = fromAttr.split("\\_");

for (String part : froms) {

fromCodePoints.add(Integer.parseInt(part, 16));

}

} else {

fromCodePoints.add(Integer.parseInt(fromAttr, 16));

}

convertMap.put(fromCodePoints, fromAttr);

}

这样就把整个解析都写到内存里了。这个就做成单例咯,在程序一进来,application里初始化。

4,解析过程

这里我是把emoji表情解析出来,再改成[e]2600[/e]的形式。然后再用正则再解析一遍(为什么这样做。。因为消息里面不可能只有emoji表情的啊亲。。。你还要解析另外的表情。) 下面是过滤emoji表情的方法:

public String parseEmoji(String input) {

if (input == null || input.length() <= 0) {

return "";

}

StringBuilder result = new StringBuilder();

int[] codePoints = toCodePointArray(input);

List key = null;

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

key = new ArrayList()

if (i + 1 < codePoints.length) {

key.add(codePoints[i]);

key.add(codePoints[i + 1]);

if (convertMap.containsKey(key)) {

String value = convertMap.get(key);

if (value != null) {

result.append("[e]" + value + "[/e]");

}

i++;

continue;

}

}

key.clear();

key.add(codePoints[i]);

if (convertMap.containsKey(key)) {

String value = convertMap.get(key);

if (value != null) {

result.append("[e]" + value + "[/e]");

}

continue;

}

result.append(Character.toChars(codePoints[i]));

}

return result.toString();

}

看到这里,你可能觉得懵了。当时我也是卡了两三天,不停的网上找资料,反编译别人的代码。最后才找的解决方案的,代码其实没有很多,最重要的是要怎么去思考。

4.渲染成图片。

public static SpannableStringBuilder convetToHtml(String content, Context mContext) {

String regex = "\\[e\\](.*?)\\[/e\\]";

Pattern pattern = pile(regex);

String emo = "";

Resources resources = mContext.getResources();

String unicode = EmojiParser.getInstance(mContext).parseEmoji(content);

Matcher matcher = pattern.matcher(unicode);

SpannableStringBuilder sBuilder = new SpannableStringBuilder(unicode);

Drawable drawable = null;

ImageSpan span = null;

while (matcher.find()) {

emo = matcher.group();

try {

int id = resources.getIdentifier(

相关文档
最新文档