分析android预装apk以及相关的实现手段

原创 2015年07月09日 22:57:19

如果厂家代码完善的话,平时拿到厂家的BSP,需要预装apk的时候,只需往预定好的目录拷贝apk即可。但如果自己手动实现起来并不见得那么简单。所以这里为大家介绍两种实现方法。

预装的条件:

         出厂时候装上apk,需要删除apk的时候可以删除。

在android 下,除了使用android自带的apk安装程序进行安装apk外,对开发人员而言,可以使用 adb install 命令进行安装。

但要求是出厂预装,所以有三种方式可以实现,就是分别把apk放到以下目录下:

System/app
System/priv-app
Data/app

System/app 相信比较常用。源码out目录下的“system/app” 下,源码编译的时候,系统自带的许多apk都会放到这目录下来。不过此目录下的apk,用户不能通过 uinstall 的方式卸载,所以这种方式不能通过。

System/priv-app ,跟 “system/app”相类似。他们的区别主要是 “system/priv-app” 主要存放是系统的核心组件,如Settings.apk,而“system/app”是系统app 。其两者的相同之处是必须要root 才能把 apk 删除,用户是不具备这样的权限。

所以前两种方式安装apk不可行。

所以,最后的方法是,只能把apk 放在“data/app”目录下。

在讲解决方案前,先来讲一种失败的方案:

可能有一些人会想到如下操作:

        1、  在 mk 文件 COPY 动作的时候加上一句:

              Xxx.apk:data/app

         2、  重新编译system.img,然后烧录系统。

可是,当烧写完系统后,发现 “data/app”下空空如也,没有发现apk任何蛛丝马迹。

这种方式不可行,原因是没有搞清楚img 文件跟系统分区之间的关系:system.img 最终是会烧录到system 分区下,而烧录到 system 分区下的文件是不会在 data 分区生效的。详细情况可以研究android 的烧写脚本,看看分区跟 img 之间的关系。

 

经过探讨,这里提出两种实现方法。

方法一:通过烧录的方式,把apk烧录到“data/app”下。

安照上面所说的,那把apk 拷贝到“userdata.img”里面,然后烧录到 data 分区下不就可以了吗?

可以说,想法是好的,但是一般IC厂家都会把 data 分区分配较大的容量,所以,如果重新烧写“userdata.img”的话,开机就会发现,data 分区“缩水了”,所以不能这样实现。

接下来,方案一是在烧录的时候,“把apk拷贝到“data”分区下面”

由于我是使用烧录脚本进行烧写,所以可以修改烧录脚本:

+function copy_apk_to_data
+{
+	echo "copy apk to /data/"
+	umount ${node}* &> /dev/null
+	mkdir /mnt/android_image
+	mount ${node}${part}4 /mnt/android_image
+	mkdir /mnt/android_image/app
+	cp -rf ../ESFileExplorer_218.apk /mnt/android_image/app
+	sync
+	umount ${node}* &> /dev/null
+	rm -r /mnt/android_image
+	echo "copy apk to /data/ finish"
+}
+
 function format_android
 {
 	echo "formating sdcard"
@@ -146,6 +161,8 @@ function flash_android
     if [ "${android}" -ne "1" ]; then	  
     	copy_image_to_data  
     fi
+	copy_apk_to_data
 }

脚本内容不详细解释,大家可以去详细看看。

接下来修改 init.rc 文件,

     mkdir /data/app-asec 0700 root root
     mkdir /data/app-lib 0771 system system
-    mkdir /data/app 0771 system system
+#    mkdir /data/app 0771 system system
+	chown system system /data/app
+	chmod -R 0771 /data/app
+##################################################
     mkdir /data/app/ing 0771 root root
     mkdir /data/property 0700 root root
     mkdir /data/ssh 0750 root shell

因为在烧录的时候已经创建了 “data/app”目录,所以在init.rc里面就不需要重新创建。

方法一在这里已经可以满足需求,不过仔细考虑,通常情况下,我们在编译image 的时候普遍的做法是一个 image 已经包括所有的功能,不必需要一个apk 独立烧写,所以有必要提出第二种方式来实现。

 

方法二:

 一般我们烧写的image里面都包括system.img 所以,我们想必首先把apk往system.img里面存放。

总体思路:

首先在mk 文件里面把apk 拷贝到out/system/xxx 的一个目录下,然后init.rc 里面启动一个服务,服务的内容就是从out/system/xxx 目录下,把 apk 文件拷贝到“data/app”下。

但这种情况下,会发现,如果在系统运行的时候把 预装的apk 卸载掉,第二次开机的时候,apk会重新被预装上。其原因是 在 init.rc 里面的服务每次开机都会启动,都会从 out/system/xxx 目录下把apk 拷贝到“data/app”下。

那么我们要做的是,只要升级起来拷贝一次,第二次开机就不会进行拷贝动作。在这里,可以通过设置android属性来完成。下面是具体的实现过程:

首先,在mk 文件里面做拷贝动作:

<p>-        device/vendor/xxx/audio_effects.conf:system/vendor/etc/audio_effects.conf</p><p>+       device/vendor/xxx/audio_effects.conf:system/vendor/etc/audio_effects.conf\</p><p>+       device/vendor/xxx/apps/ESFileExplorer_218.apk:system/user/app/ESFileExplorer_218.apk\</p><p>+       device/vendor/xxx/install-app.sh:system/bin/install-app.sh</p>
 然后是在 init.rc 里面添加服务:

+service install-app /system/bin/install-app.sh
+	class main
+	oneshot
在system.proc里面申请属性:

+persist.sys.first_run=1
 编写脚本文件:

#!/system/bin/sh
FLAG=$(getprop persist.sys.first_run)
#FLAG=$?
if [ 1 -eq $FLAG ];then
	setprop persist.sys.first_run 0
	busybox cp /system/user/app/ESFileExplorer_218.apk /data/app/ESFileExplorer_218.apk
	chmod 777 /data/app/ESFileExplorer_218.apk
fi

最后想提一下,这样修改后,在编译的时候会提示:

        use BUILD_PREBUILT instead!.  Stop.

因为在Makefile 里面会对拷贝apk 的动作进行判断,执行把这几行代码注释掉即可:

-define check-product-copy-files
-$(if $(filter %.apk, $(1)),$(error \
-    Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!))
-endef
+#define check-product-copy-files
+#$(if $(filter %.apk, $(1)),$(error \
+#    Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!))
+#endef
好,两种预装apk的方法到此讲述完毕。





Android系统预装第三方apk

对于android系统预装第三方apk,分两种情况: 一、不包含so库的简单apk: 完全可以预装到system/app目录下(也就是系统app),运行时不会有找不到so库的错误; 二、包含so...

android 预装第三方apk的方法

预装第三方apk,并不是装到/system/app下,而是装到/data/app/下,这两者是有区别是, 前者用户是不可以卸载的,后者用户可以卸载,我们现在实现的就是后者。 1 pm.jar包...
  • BENKG
  • BENKG
  • 2013年10月08日 17:44
  • 3358

android 预装第三方apk的方法

预装第三方apk,并不是装到/system/app下,而是装到/data/app/下,这两者是有区别是, 前者用户是不可以卸载的,后者用户可以卸载,我们现在实现的就是后者。 1 pm.jar包中添...

Android 5.0 内置第三方apk

Android 5.0 内置第三方apk 举例说明内置百度apk到code中的方法 百度apk的名称为:baidu.apk 1.    将apk放置在可以编译到的路径下,如/ve...

android源码中预安装第三方的apk软件

android源码中预安装第三方的apk软件 热度 2已有 2578 次阅读2012-11-23 17:55 |系统分类:Android开发| android, 安装, 第三方 申...
  • sno_guo
  • sno_guo
  • 2014年06月25日 20:18
  • 7359

android添加第三方apk

只有一个apk文件,如何添加到Andorid源码中,开机之后这个apk已经安装好。 1.device/amlogic/f20ref/f20ref.mk中copy file到system/app目录下...

如何内置客制(第三方)的apk到ROM中

1,如何将带源码的 APK 预置进系统?                                                                                ...

Android系统内置第三方应用

从8月开始,我开始转向

编译第三方APK进Android(预装APK)

预装APK 第三方APK预装

预置第三方apk

一、如何将带源码的APK预置进系统? 1) 在 packages/apps 下面以需要预置的 APK的 名字创建一个新文件夹,以预置一个名为Test的APK 为例  2) 将 Test APK的S...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:分析android预装apk以及相关的实现手段
举报原因:
原因补充:

(最多只允许输入30个字)