分析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到data/app

对于第三方apk预装入系统时如果将apk装入system/app目录下,由于第三方apk带有自己的.so文件,此时会出现apk无法打开的情况。 解决方法: 1:解压apk,将里面的.so文件放入d...

Android 5.0 内置第三方apk

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

android 预装第三方apk的方法

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

android之使用signapk打包成系统应用,获取系统权限

有的时候在应用程序中需要获取一些特殊权限,比如写该系统时间,或者关机程序,这是后除了获取root权限方法之外,还可以使用在menifest.xml文件中添加android:sharedUserId="...

Android MTK 拷贝第三方App 内置apk文件到系统目录

MTK 的第三方App文件或者so库,都存在在Vendor目录下面 vendor\retch\thirdapp 我们要实现App 的拷贝,可以在pacakage\apps 下面去新建一个文件夹...

在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务

我们在Android系统增加硬件服务的目的是为了让应用层的APP能够通过Java接口来访问硬件服务。那么, APP如何通过Java接口来访问Application Frameworks层提供的硬件服务...

Android硬件抽象层(HAL)概要介绍和学习计划

Android的硬件抽象层,简单来说,就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空...

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

预装APK 第三方APK预装

用adb命令启动停止Android程序

我们都知道用"adb install filename.apk"命令可以安装一个android程序,那你知道在安装后如何启动你的程序吗? 试试下面的命令吧。 adb shell am start ...

Android系统预装第三方apk

对于android系统预装第三方apk,分两种情况: 一、不包含so库的简单apk: 完全可以预装到system/app目录下(也就是系统app),运行时不会有找不到so库的错误; 二、包含so...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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