新建一个系统bin在开机的时候来实现apk的拷贝。具体实现如下:
1. 这是一个feature,为了控制各个项目方便开启和关闭此功能,需定义宏控制;
在code\rgt_projects\g502h_tnx (这里以田纳西项目为例)目录下的ProjectConfig.mk文件中添加:
RGK_PREINSTALL_APP_UNINSTALL = yes
2. 在code\external下新建一个文件夹:
这个文件夹里放置我们这个bin所需的文件。名字自定,不要和现有的bin重名。这里我们设置为userapp,在userapp下创建一个C文件,主要实现拷贝apk功能:
创建copyapp.c:
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <dirent.h>
#define BUFFER_SIZE 1024
static void copy_file(char* src, char* dst)
{
intsrc_fd,dst_fd;
intbytes_read,bytes_write;
charbuffer[BUFFER_SIZE];
char*ptr;
if((src_fd= open(src,O_RDONLY)) == -1){
}
if((dst_fd= open(dst,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1){
}
while(bytes_read= read(src_fd,buffer,BUFFER_SIZE))
{
if((bytes_read == -1)&&(errno != EINTR))
{
break;
}
else if(bytes_read > 0)
{
ptr=buffer;
while(bytes_write = write(dst_fd,ptr,bytes_read))
{
if((bytes_write == -1)&&(errno !=EINTR))
{
break;
}
else if(bytes_write == bytes_read)
break;
else if(bytes_write > 0)
{
ptr+=bytes_write;
bytes_read -= bytes_write;
}
}
if(bytes_write == -1)
{
break;
}
}
}
close(src_fd);
close(dst_fd);
}
int main() {
int fdcheck = 0;
if((fdcheck =open("/data/app/copyapp.txt",O_RDONLY)) < 0)
{
struct dirent **dataapplist;
int app_num = -1;
app_num = scandir("/data/app", &dataapplist, 0,alphasort);
if (app_num < 0)
{
;
}
else
{
int i =0;
for(;i <app_num;i++)
{
charapp_name[256]="/data/app/";
strcat(app_name,dataapplist[i]->d_name);
remove(app_name);
free(dataapplist[i]);
}
free(dataapplist);
}
}
else
{
close(fdcheck);
return EXIT_SUCCESS;
}
structdirent **namelist;
intfile_num = scandir("/system/pre_install", &namelist, 0,alphasort);
if(file_num < 0)
{
;
}
else
{
int ret =mkdir("/data/app",S_IRWXU|S_IRWXG|S_IRWXO);
if(ret != 0)
{
}
int i =0;
for(;i < file_num;i++)
{
char src_name[256]="/system/pre_install/";
char dst_name[256]="/data/app/";
if(strstr(namelist[i]->d_name,".apk"))
{
strcat(src_name,namelist[i]->d_name);
strcat(dst_name,namelist[i]->d_name);
//copy /system/pre_install/xx.apk to/data/app/xx.apk
copy_file(src_name,dst_name);
}
free(namelist[i]);
}
free(namelist);
}
fdcheck =open("/data/app/copyapp.txt",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
close(fdcheck);
returnEXIT_SUCCESS;
}
3. 在userapp下创建一个mk文件:
创建Android.mk:
ifeq ($(strip $(RGK_PREINSTALL_APP_UNINSTALL)), yes)
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=copyapp.c
LOCAL_MODULE:=userapp
include $(BUILD_EXECUTABLE)
endif
4. 在init.rc中加入我们实现的bin;在code/mediatek\config\ratech75cu_nand_gb2下的init.rc中加入:
service userapp /system/bin/userapp
oneshot
表示我们的bin在开机初始化的时候执行一次。
5. 在code/build/core目录下的user_tags.mk文件中加入:
GRANDFATHERED_USER_MODULES+= userapp
6. 在code\vendor目录下创建pre_install目录,里面存放我们预装可卸载的应用APP文件,在新建一个Android.mk文件:
Android.mk内容为:
ifeq ($(strip$(RGK_PREINSTALL_APP_UNINSTALL)), yes)
include $(CLEAR_VARS)
LOCAL_PATH:= vendor/pre_install
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/QQSecure2.0_android.apk:system/pre_install/QQSecure2.0_android.apk
endif
7. 需要去掉code\vendor\third_party目录中Android.mk文件中相关APP的拷贝语句。
end end end///
-------- 做成可卸载的应用
1 add userapp/Android.mk
ifeq ($(strip $(RGK_PREINSTALL_APP_UNINSTALL)), yes)
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
#LOCAL_MODULE_PATH := $(TARGET_OUT)/bin
LOCAL_SRC_FILES:=copyapp.c
LOCAL_MODULE:=userapp
#LOCAL_MODULE_TAGS:=optional #eng user
include $(BUILD_EXECUTABLE)
endif
2 add external/userapp/copyapp.c
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <dirent.h>
#define BUFFER_SIZE 1024
static void copy_file(char* src, char* dst)
{
int src_fd,dst_fd;
int bytes_read,bytes_write;
char buffer[BUFFER_SIZE];
char *ptr;
if((src_fd = open(src,O_RDONLY)) == -1){
}
if((dst_fd = open(dst,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1){
}
while(bytes_read = read(src_fd,buffer,BUFFER_SIZE))
{
if((bytes_read == -1)&&(errno != EINTR))
{
break;
}
else if(bytes_read > 0)
{
ptr=buffer;
while(bytes_write = write(dst_fd,ptr,bytes_read))
{
if((bytes_write == -1)&&(errno != EINTR))
{
break;
}
else if(bytes_write == bytes_read)
break;
else if(bytes_write > 0)
{
ptr+=bytes_write;
bytes_read -= bytes_write;
}
}
if(bytes_write == -1)
{
break;
}
}
}
close(src_fd);
close(dst_fd);
}
int main() {
int fdcheck = 0;
if((fdcheck = open("/data/app/copyapp.txt",O_RDONLY)) < 0)
{
struct dirent **dataapplist;
int app_num = -1;
app_num = scandir("/data/app", &dataapplist, 0, alphasort);
if (app_num < 0)
{
;
}
else
{
int i =0;
for(;i < app_num;i++)
{
char app_name[256]="/data/app/";
strcat(app_name,dataapplist[i]->d_name);
remove(app_name);
free(dataapplist[i]);
}
free(dataapplist);
}
}
else
{
close(fdcheck);
return EXIT_SUCCESS;
}
struct dirent **namelist;
int file_num = scandir("/system/pre_install", &namelist, 0, alphasort);
if (file_num < 0)
{
;
}
else
{
int ret = mkdir("/data/app",S_IRWXU|S_IRWXG|S_IRWXO);
if(ret != 0)
{
}
int i =0;
for(;i < file_num;i++)
{
char src_name[256]="/system/pre_install/";
char dst_name[256]="/data/app/";
if(strstr(namelist[i]->d_name,".apk"))
{
strcat(src_name,namelist[i]->d_name);
strcat(dst_name,namelist[i]->d_name);
//copy /system/pre_install/xx.apk to /data/app/xx.apk
copy_file(src_name,dst_name);
}
free(namelist[i]);
}
free(namelist);
}
fdcheck = open("/data/app/copyapp.txt",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
close(fdcheck);
return EXIT_SUCCESS;
}
3 add build/core/user_tags.mk
add the end:
#port this by chenweiwei
ifeq ($(strip $(RGK_PREINSTALL_APP_UNINSTALL)), yes)
GRANDFATHERED_USER_MODULES += userapp
endif
4 rgt_projects/g503hh_d_qc/ProjectConfig.mk
#add by chenweiwei for qingcheng 20120630
RGT_G503HH_D_CUSTOM_QC_SUPPORT=yes
#Preinstalled applications can be uninstalled
RGK_PREINSTALL_APP_UNINSTALL = yes
RGK_PREINSTALL_APP_UNINSTALL
ifeq ($(strip $(RGK_PREINSTALL_APP_UNINSTALL)), yes)
include $(CLEAR_VARS)
LOCAL_PATH:= vendor/pre_install
ifeq ($(RGT_G503HH_D_CUSTOM_QC_SUPPORT), yes)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/BaiduSearch_QC/apk/BaiduSearch_QC.apk:system/pre_install/BaiduSearch_QC.apk \
$(LOCAL_PATH)/QQ_QC/apk/QQ2012_QC.apk:system/pre_install/QQ2012_QC.apk \
$(LOCAL_PATH)/TouchPal_QC/apk/TouchPal_QC.apk:system/pre_install/TouchPal_QC.apk \
$(LOCAL_PATH)/QingChengPlay_QC/apk/QingChengPlay.apk:system/pre_install/QingChengPlay.apk
endif
endif
add in the end :
#port by chenweiwei 20120713 start
service userapp /system/bin/userapp
oneshot
#port by chenweiwei 20120713 end