admin管理员组文章数量:1600487
很久没有记录了,持之以恒做一件事,需要一定的毅力呐!
最近遇到了一个需求,要求恢复出厂设置保留内置sd卡下某个目录的文件。思来想去,从驱动那边备份校准信号文件得到了一些思路。因为带通话设置的装置需要进行校准,我们会将校准的文件保存在/data下。具体做法呢,在执行恢复出厂设置时,将此文件copy到tmp分区,然后在恢复完成时,再次copy回/data分区。因为我们是备份文件夹,所以我们需要对copy函数进行修改。下面贴出部分代码。
diff --git a/bootable/recovery/recovery.cpp b/bootable/recovery/recovery.cpp
index 598840c..3693cf1 100644
--- a/bootable/recovery/recovery.cpp
+++ b/bootable/recovery/recovery.cpp
@@ -111,6 +111,8 @@ static const char *OTA_FLAG_FILE = "/cache/recovery/last_ota_flag";
#ifdef STK_BACKUP_OFFSET
//要备份的文件夹
+static const char *BACKUP_APK_PATH = "/system/third";
//临时存储路径
+static const char *TEMP_APK_BACKUP_PATH = "/tmp/third_app";
#endif
// Number of lines per page when displaying a file on screen
@@ -286,6 +288,116 @@ static int stk_copy_file(const char *src,const char *dstFilePath)
printf("stk_copy_file end src=%s,dst=%s\n",src,dstFilePath);
return 0;
}
//拷贝文件夹的主体函数
+void error_quit(const char *msg)
+{
+ perror(msg);
+ //printf("something is error %s \n",msg);
+}
+
+void change_path(const char *path)
+{
+ printf("Leave %s Successed . . .\n",getcwd(NULL,0));
+
+ if(chdir(path)==-1){
+ error_quit(path);
+ printf("chdir(path)==-1 %s \n",path);
+ return;
+ }
+
+ printf("Entry %s Successed . . .\n",getcwd(NULL,0));
+}
+
+
+void _copy_file(const char *old_path,const char *new_path)
+{
+ FILE *in,*out;
+ size_t len;
+ char buf[64];
+ char *p=getcwd(NULL,0);
+
+ if((in=fopen(old_path,"rb"))==NULL){
+ error_quit(old_path);
+ printf("(in=fopen(old_path %s \n",old_path);
+ return;}
+ change_path(new_path);
+
+ if((out=fopen(old_path,"wb"))==NULL){
+ error_quit(old_path);
+ printf("out=fopen(old_path %s \n",old_path);
+ return;}
+
+ while(!feof(in))
+ {
+ bzero(buf,sizeof(buf));
+
+ len=fread(&buf,1,sizeof(buf)-1,in);
+ fwrite(&buf,len,1,out);
+ }
+
+ fclose(in);
+ fclose(out);
+
+ change_path(p);
+}
+
+char *get_rel_path(const char *dir,const char *path)
+{
+ char *rel_path;
+ unsigned long d_len,p_len;
+
+ d_len=strlen(dir);
+ p_len=strlen(path);
+ bzero(rel_path,d_len+p_len+2);
+
+ strncpy(rel_path,path,p_len);
+ strncat(rel_path,"/",sizeof(char));
+ strncat(rel_path,dir,d_len);
+
+ return rel_path;
+}
+
+void copy_dir(const char *old_path,const char *new_path)
+{
+ DIR *dir;
+ struct stat buf;
+ struct dirent *dirp;
+ char *p=getcwd(NULL,0);
+
+ if((dir=opendir(old_path))==NULL){
+ error_quit(old_path);
+ printf("dir=opendir(old_path) %s \n",old_path);
+ return;
+ }
+ if(mkdir(new_path,0777)==-1){
+ error_quit(new_path);
+ printf("mkdir(new_path %s \n",new_path);
+ return;
+ }
+
+ change_path(old_path);
+
+ while((dirp=readdir(dir)))
+ {
+ if(strcmp(dirp->d_name,".")==0 || strcmp(dirp->d_name,"..")==0)
+ continue;
+ if(stat(dirp->d_name,&buf)==-1){
+ error_quit("stat");
+ printf("stat(dirp->d_name %s \n",stat);
+ return;
+ }
+ if(S_ISDIR(buf.st_mode))
+ {
+ copy_dir(dirp->d_name,get_rel_path(dirp->d_name,new_path));
+ continue;
+ }
+
+ _copy_file(dirp->d_name,new_path);
+ }
+
+ closedir(dir);
+ change_path(p);
+}
#endif
// command line args come from, in decreasing precedence:
// - the actual command line
@@ -1326,6 +1438,7 @@ main(int argc, char **argv) {
}
#ifdef STK_BACKUP_OFFSET
//在开始进入恢复出厂时,进行一次拷贝
+ copy_dir(BACKUP_APK_PATH,TEMP_APK_BACKUP_PATH);
#endif
device->StartRecovery();
property_get("UserVolumeLabel", gVolume_label, "");
@@ -1567,8 +1680,11 @@ main(int argc, char **argv) {
finish_recovery(send_intent);
#ifdef STK_BACKUP_OFFSET
//在恢复出厂完成时,我们再次将其拷贝回来
+ copy_dir(TEMP_APK_BACKUP_PATH,BACKUP_APK_PATH);
+ //赋予权限操作
+ chmod(BACKUP_APK_PATH, 0666);
+ chown(BACKUP_APK_PATH, 1000, 1000); // system system
#endif
#ifdef FOTA_UPDATE_SUPPORT
if (perform_fota == 1) {
我们只要重点关注在finish_recovery(send_intent);与device->StartRecovery();这两个函数身上即可。我测试过直接从/mnt/sdcard下拷贝,这样是不行的。因为在执行恢复出厂设置时,这个分区此时还未挂载,我通过代码让其先挂载,但是无效。当然也可能在恢复出厂设置时,我们所要备份的文件夹并不存在,所以贴出代码片中的一些判空都进行了return。否则会无法开机,串口log一直重复打印log。
如果各位有其他办法,欢迎留言。有不对之处,欢迎指出。
版权声明:本文标题:Android客制化-恢复出厂设置但保留文件 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1726035646a1052897.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论