最近公司由于要参加国际上的某个show,需要集成Google Maps和Google Search的apk,注意是源码集成。在此过程中遇到一些坑,总结下来希望大家注意,以后遇到类似问题可以参考。
大家都知道,源码集成apk主要有两种形式,一种是预装到/system/app下边,一种是预装到/data/app下,当然还有一种比较特殊的是/system/priv-app。在集成之前,我先在某个应用市场下载了最新的几个Google的apk (我的系统环境是5.0.1),它们分别是:Google Play Service、Google Service Framework、Google Play Store、Google Maps以及Google Search。我刚开始的做法是将这些apk直接集成到/system/app,以google maps为例
LOCAL_PATH := $(PREBUILT_PATH) include $(CLEAR_VARS) LOCAL_MODULE := GoogleMaps LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := APPS LOCAL_CERTIFICATE := PRESIGNED LOCAL_MODULE_SUFFIX := .apk LOCAL_SRC_FILES := ../n5100/system/app/GoogleMaps/GoogleMaps.apk include $(BUILD_PREBUILT)
但是编译出来的rom在开机时会报错,主要是两种错误:一个是提示Google Play Service sopped;另一个是Google Maps安装位置不对。这两个问题困惑了我好久。关于Google Maps的错误,我发现在普通install也就是安装在/data/app目录下时是可以正常运行的,但是放到/system/app下就不行了。adb shell进去看目录结构,忽然发现app的目录中还有依赖的so文件,这时才恍然大误。/data/app下的apk会去自己目录下的lib/arm中找so,而/system/app会从/system/lib下寻找,我之前只把apk集成到了/system/app,而忽视了/system/lib下的so,遂adb pull出data/app下的依赖so,然后集成到/system/lib下。Google Play Service跟Google Search同样需要这一步,Google Play Store跟Google Service Framework就没有依赖的so。以Google Maps为例,添加以下so集成
LOCAL_PATH := $(PREBUILT_PATH) include $(CLEAR_VARS) LOCAL_MODULE := libcrashreporterer LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_CERTIFICATE := platform LOCAL_MODULE_SUFFIX := .so LOCAL_SRC_FILES := ../n5100/system/app/GoogleMaps/libs/libcrashreporterer.so include $(BUILD_PREBUILT) LOCAL_PATH := $(PREBUILT_PATH) include $(CLEAR_VARS) LOCAL_MODULE := libgmm-jni LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_CERTIFICATE := platform LOCAL_MODULE_SUFFIX := .so LOCAL_SRC_FILES := ../n5100/system/app/GoogleMaps/libs/libgmm-jni.so include $(BUILD_PREBUILT)
Ok,经过以上步骤,Google Maps不会报错了,但是Google Play Service还是报错,看log是Google Service Framework中的一些permission找不到,此时灵光一现将Google Service Framework集成到了/priv-app下,竟然鬼使神差般地work了。看来是得好好研究一下这几个目录的差异了。
LOCAL_PATH := $(PREBUILT_PATH) include $(CLEAR_VARS) LOCAL_MODULE := GoogleServiceFramework LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := APPS LOCAL_CERTIFICATE := PRESIGNED LOCAL_PRIVILEGED_MODULE := true LOCAL_MODULE_SUFFIX := .apk LOCAL_SRC_FILES := ../n5100/system/priv-app/GoogleServiceFramework/GoogleServiceFramework.apk include $(BUILD_PREBUILT)
经过以上步骤,所有的工作大功告成。但是,还是遇到了另外一个问题,系统还要集成国内某个厂商的导航软件,用以上这种方法会发现,该导航软件依赖的某个so库与系统原生的so会有命名冲突,看来应该是从某个android版本中抽取出来的so,鄙视一下也不改个名字,所以集成到/system/app下无望了,那就只能集成到 /data/app吧,关于集成apk到/data/app要远比/system/app麻烦,网上差了一些资料,无外乎以下原理:将apk保存到系统rom中的某个文件夹下,待系统第一次启动的时候通过init.rc中的某个daemon service执行一个脚本命令,将apk copy到/data/app下。
具体参考链接:http://blog.csdn.net/zuiaikg703/article/details/12445525
http://www.cnblogs.com/MMLoveMeMM/articles/4087014.html
http://blog.chinaunix.net/uid-29535415-id-4168539.html