2009年4月29日星期三

Android中文联系人排序及检索补丁的原理

转自http://blog.sunner.cn/2009/04/android_pinyin_sorting/


2009年4月26日,更新了源码和相关文件

很久以前做了这个补丁,有幸的是朋友们都还算喜爱它,没白费功夫。不少朋友来信问它的原理,现在就讲一下。不过里面很多地方要靠回忆,未必很精确。如果你不能重现我所写的,欢迎提醒。另外要说明的是,下面所有的一切都是针对android 1.0的。

整个补丁的制作分五个步骤。

1. 制作支持中文排序和文字转换拼音的icudt38l.dat文件

先说一下icu4c。这是一个非常强大的开源软件,基本上把所有多语言要处理的问题都解决了。android对语言的处理主要就是调用它,但并没有包括中文相关的数据。所以先要把中文数据加进去。

android编译过程中直接将external/icu4c/stubdata/icudt38l.dat做为数据文件编译到目标代码中。所以只要向此文件添加中文的东西就行了。

我用的方法是直接下载icu4c的源代码,然后修改data/coll/en.txt,把data/coll/zh.txt的内容“合理地”替换进去。为了减少体积,只替换pinyin相关的东西。编译。

参考external/icu4c/stubdata/helper.sh,用新做好的coll/en.res替换icudt38l.dat里的coll/en.res,并将icu4c目标文件里的translit/root.res添加进去。

制作好的icudt38l.dat文件可以从这里下 载。放到external/icu4c/stubdata/目录下,用“make libicudata”编译android,应该很快就能得到新生成的libicudata.so。用它替换ROM的同名文件,就已经能中文排序了(只对 新增或修改过的联系人有效,详见第4步)。

2. 打开icu4c的translit功能

打开这个功能才能实现中文到拼音的转换,也才能实现快速检索。

打开的方法应该是修改external/icu4c下的某个编译配置文件。但具体改哪个,改成什么我记不清了。源代码也没在随时可以查看的机器上。等查到了,再来补写吧。

icu4c.diff里可以看到打开的方法,涉及到数个文件的简单修改。

3. 改变android为联系人建索引的方式

在联系人数据库中有一个peopleLookup表。它只有两个字段,第一个是token,第二个是联系人id。只要从键盘输入的字符和token能对应上,就会将改id的联系人显示在检索结果中。所以,只要把联系人的拼音写到token,就能实现用硬键盘快速检索。

所有的修改都集中于external/sqlite/android/sqlite3_android.cpp。这个文件为sqlite增加了一些 android需要的功能,其中就有一个_TOKENIZE()函数。它的功能就是在指定的表中建立对给定id和字符串的索引。它还能对字符串进行分割, 比如sunner sun,会建立三个索引“sunner”,“sun”和“sunner sun”。这就是android联系人功能的初始形态。

_TOKENIZE()的实现是tokenize()函数。我在这里面调用了icu4c的功能,把中文转换成拼音字串,然后再建索引,于是就能拼音检索了。就这么简单,代码也不长,在sqlite3_android.diff中。不过现在不在手边,以后再放上来。

4. 制作数据库刷新脚本

将上述修改编译后,替换到ROM中,并不能马上使用这些功能。因为现存联系人的各种索引信息都是旧的,必须更新一下它们。更新的方法很简单,就是把每个联系人的名字都写回一遍,然后把联系人数据库中的索引都更新一下。细节都在ROM升级文件的updatedb.sh中。

5. 制作ROM升级文件

替换system分区中的文件最好是在系统启动前,否则很可能会造成空间丢失。所以最终把这个补丁做成了一个update.zip,可以用刷机的方式刷上。

做它主要用到的工具是JF’s Build Environments(http://forum.xda-developers.com/showthread.php?t=475381)里的testsign.jar。

分析已有的update.zip文件,就能知道它的基本结构,很简单。按这个结构放好几个要替换的文件,写好update-script脚本(关于这个脚本的语法,只能从android源码获得,在recovery/commands.c里),打成zip包,然后

java -jar testsign.jar src.zip dst.zip

这里的src.zip是前面做好的压缩包,dst.zip就是最终产品。

大概就是这样。

3.21版的补丁在这里下载。

Android相关项目

转自
http://www.zymose.com/android/projects/index.html

Apache Commons Codec

Codec 包含一些通用的编码解码算法。包括一些语音编码器, Hex, Base64, 以及URL encoder.

Apache commons logging

Apache的Common Logging是一个高层的日志框架,本身并没有实现真正的写日志能力,而是依赖其它的日志系统如Log4j或者java本身的 java.util.logging。可以通过配置文件来设定最终使用log4j还是java.util.logging。

Apache Harmony

Apache Harmony 的提案在 2005 年 5 月被 Apache 软件基金会(ASF)接受,并且按照 ASF 惯例成为一个孵化器(incubator)项目。
Harmony 为自己定了两个目标,首先是开发出一个独立并且与现有 JDK 兼容的 Java SE 5 实现,并且以 Apache 软件许可证 2.0 版发行;其次是建立一个开放的模块化运行时架构,包括虚拟机和类库之间及其内部的模块化,并通过这个平台,允许社区在此基础上自由定制自己的 Java 实现,或者对某个模块单独进行创新。
Apache Harmony 项目的成立以及它的这两个目标具有很大的现实意义。首先,由于商业JDK的流行性,它们几乎成为事实上的标准,所以 Harmony 必须与它们保持高度的兼容,才能够使应用程序的迁移成本最低,也就相对容易被用户所接受;其次,Harmony 存在的重要意义之一就在于这是一个属于开源社区的 Java 平台,在这个平台上,社区可以自由的移植和创新,而一个开放的模块化的架构,将为移植和创新带来最大的便利性;最后,Apache 软件许可证是一个对商业公司和开源社区都比较友好的开源许可证,因此 Harmony 可以给最大范围的开发人员和用户带来便利。本文和本系列后续文章将详细介绍 Harmony 在兼容性和模块化方面的努力,以及这些目标带来的价值。
也许正是基于以上一些原因,Harmony 项目成立仅仅一年多一点的时间,就得到了广泛的支持和关注,并且得以飞速发展。目前,Apache Harmony 已经拥有了一个活跃的开发社区,并且接受了来自公司,学校和个人的多次捐赠。IBM 在 developerWorks 上提供了一个 Java 虚拟机环境的免费下载,以支持 Harmony 项目的开发,还多次捐赠了核心类库的实现和测试代码,在 IBM 英国 Hursley 软件开发实验室和中国软件开发中心各有一个开发团队积极参与 Harmony 项目。此外 Harmony 项目还接受了三个 Java 虚拟机实现的捐赠,另外还有一个开源 Java 虚拟机 SableVM 正在积极的与 Harmony 社区合作以实现与 Harmony 类库的集成。Java SE 实现难度最大的是其规模庞大的类库,而最近的类库 API 覆盖率统计表明,Harmony 的 J2SE 1.4.2 类库 API 的覆盖率已经超过 80%,Java SE 5 的覆盖率已经达到 79% 以上。目前经不完全测试,在 Harmony 上已经可以良好运行 Eclipse、JEdit、Ant 等流行的 Java 工具,并且可以部分运行 Tomcat 和 Geronimo 等企业应用。

Apache HttpClient

HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient
    以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。
  • 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
  • 支持自动转向
  • 支持 HTTPS 协议
  • 支持代理服务器等

Apache HttpComponents

HttpComponents 为那些要用到HTTP协议的程序(包括客户端和服务器端)提供支持.包括Web浏览器,网络爬虫,HTTP代理.Web Services等.

bluez

该项目为Linux下的蓝牙无线协议的实现.源代码用GPL协议发布.

Bouncy Castle Crypto

Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包。它支持大量的密码术算法,并提供 JCE 1.2.1 的实现。因为 Bouncy Castle 被设计成轻量级的,所以从 J2SE 1.4 到 J2ME(包括 MIDP)平台,它都可以运行。它是在 MIDP 上运行的唯一完整的密码术包。

Google Apps APIs

Google Apps是Google 推出的在线的应用应用服务。说得通俗一点,通过 Goolge Apps ,你可以向你的用户提供带有私人标志的电子邮件、即时通信(网上聊天),日历工具,网站设计工具,协同办公工具等。当然,这些服务都是由 Google 托管,而不需要你安装或维护任何软硬件,并且和 Google 的其他服务一样,它们都是免费的。

Google Calendar APIs and Tools

Google日历API支持多种语言程序,包括Java、.NET、PHP、Python和JavaScript等,通过Google日历API, 可以在浏览器客户端实现对日历的完全控制,如进行日程的读取、创建、编辑或删除等操作。

Google data APIs

GData是一种简单的标准协议,用于网络数据的读写。它结合了常见的基于xml的数据聚合格式(Atom与RSS)以及基于 Atom发布协议的Feed发布体系,并扩展了部分功能用于处理查询功能。有时,我们需要发送一个查询请求给服务器,并得到服务器返回的相符的查询结果, 而目前的Atom和RSS标准都不具备这一功能。GData让用户可以使用聚合(syndication)的机制来发送请求并接收结果,它使你可以发送数 据给Google,更新那些Google已经拥有的数据。 这些技术化的说明听起来似乎有点让人头晕。不过,简单地理解,GData扩展了原有的RSS和Atom协议,使其从一种单向的聚合变成了双向的互动,这似 乎是大家都在探索的feed的未来发展方向,比如微软的SSE。 Google 一直以来给人的感觉是对RSS和Atom都不太热心,这次为什么突然提出这个新标准。国外的blogger众说纷纭,Joe Gregorio认为,GData是将RSS、Atom,尤其是Atom发布协议(Atom Publishing Protocol)与Amazon的Openserch标准相结合;Maurice Codik认为GData标准使Google的数据更加开放,各种应用之间可以更方便地利用这一标准来使用数据;甚至有人认为这使得基于Google各种 应用的企业门户雏形开始显现。

Google Map API

Google Maps API是Google公司提供的地图编程接口,使用这个API你可以方便的把Google的地图信息和你自己的数据整合建立你的地理信息服务。

Google Spreadsheets Data API

Google Spreadsheets Data API允许第三方应用程序以Google data API ("GData") 的形式访问Google Docs & Spreadsheets 里的文件数据,包括: 上传本地计算机中的Word 文档或电子表格文档。

ICU(International Components for Unicode)

International Component for Unicode (以下简称 ICU) 是一套稳定成熟、功能强大、轻便易用和跨平台支持Unicode 的开发包,使得开发人员在 C/C++ 和 Java 上开发全球化软件产品更容易,ICU 是由 IBM 发布和维护,并且是开放源代码的。
ICU 可以根据客户端的语言环境给客户返回最接近语言的字符串,也就是说客户端可能与服务器端的语言环境不一致,不能只根据服务器端的语言来返回字符串。而且将 来单独增加或维护资源文件,不需要重新生成可执行文件或动态链接库。为了提高重用性,最好将所有资源信息统一管理,不是每个模块各自维护管理。
ICU是实现Unicode标准最好的开源类库(没有“之一”),目前有ICU4C和ICU4J两个主要版本。IBM作为ICU最重要的支持力量,为它多年的发展做了很大贡献。

JSon

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
    JSON建构于两种结构:
  • “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表 (hash table),有键列表(keyed list),或者关联数组 (associative array)。
  • 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

KXML

KXML是一个只占很小存储空间的XML语法分析程序,对于J2ME应用程序非常适合。它有一个非常独特的DOM操作方法和被称为Pull的语法分析方法。
    它有以下性能:  
  • 支持XML名称空间
  • 用"松散"模式分析HTML或其它SGML格式
  •   
  • 占用很少的存储空间(21 kbps)
  • 基于Pull的分析
  • 支持XML写操作
  • 可选的DOM支持
  • 可选的WAP支持

mobile control

mobile-control project为移动设备提供基于Java的M2M解决方案。

OpenGL

OpenGL是用于开发简捷的交互式二维和三维图形应用程序的最佳环境,任何高性能的图形应用程序,从3D动画、CAD辅助设计到可视化访真,都可以利用 OpenGL高质量、高性能的特点。OpenGL自1992年出现以来,逐渐发展完善,已成为一个唯一开放的,独立于应用平台的图形标准,一个典型的 OpenGL应用程序可以在任何平台上运行--只需要使用目标系统的OpenGL库重新编译一下。

SQLite

SQLite是一个支持事务的小型数据库。

WebKit

WebKit是一款开源浏览器引擎。WebKit开始于一个Html与Javascript代码支持的KDE项目,2003年 Steve Jobs在Macworld上宣布正式采用Webkit,现在WebKit是Mac OS X系统架构下Safari、Dashboard、Mail和其它应用程序的Framework名称。   除了Google的Android,WebKit现在应用于苹果的iPhone,以及NOKIA的Symbian S60手机平台中,例如N和E系列中自带的Web Browser for S60。   在桌面领域,基于WebKit的Safari现在拥有3%至5%的浏览器市场占有率,使它成为除微软IE,Mozilla的Firefox之外的第三 大浏览器

XmlPull v1

XmlPull v1 API 是非常好用的XML推解析API。该API非常简单,而且具有很好的性能。可以用在J2ME上。也可以用作服务器端。XML拉解析允许增量解析。解析可以随时中断和恢复解析(当程序获得更多输入的时候)。

2009年4月28日星期二

G1之旅

还真是不少会玩的人,看看吧。
如果你手头有个G1手机,好几千块大洋呢,
你就甘心只是打打电话、发发短信?
那你就是太暴珍天物了。

先看人家是怎么玩的,
然后屁颠屁颠地折腾他丫的,
把那几千大洋赚回来再说。
第一步,获取root权限。

体验过当皇帝的感觉吗?
反正我没有,
可是如果你玩过linux,没有root权限,那还玩的什么劲呢。

拿到root权限后的玩法就多啦去了,
自己编译修改google最新的源代码,然后安装到G1里去,
对开发人员而言,尤其是开源社区的人员而言,
这是一个多么贴心的诱惑,我是很忍不住的啦。

想在自己的G1手机上加入multi-tap的支持吗?

如果野心更大一点,
自己做一个add-ons发布给别人做开发平台,
真是心有多高,
梦就有多远。