Android客制化-恢复出厂设置但保留文件

很久没有记录了,持之以恒做一件事,需要一定的毅力呐! 
最近遇到了一个需求,要求恢复出厂设置保留内置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);#endifdevice->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_SUPPORTif (perform_fota == 1) {


我们只要重点关注在finish_recovery(send_intent);与device->StartRecovery();这两个函数身上即可。我测试过直接从/mnt/sdcard下拷贝,这样是不行的。因为在执行恢复出厂设置时,这个分区此时还未挂载,我通过代码让其先挂载,但是无效。当然也可能在恢复出厂设置时,我们所要备份的文件夹并不存在,所以贴出代码片中的一些判空都进行了return。否则会无法开机,串口log一直重复打印log。 
如果各位有其他办法,欢迎留言。有不对之处,欢迎指出。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/468940.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

form 窗体增加边框_C#控件美化之路(13):美化Form窗口(上)

在开发中最重要的就是美化form窗口,在开发中,大多都是用会用自主美化的窗口开发程序。本文只是点多,分为上中下节。分段讲解。本文主要讲解窗口美化关键步骤。首先美化窗体,就需要自己绘制最大化 最小化 关闭按钮。其次就是界面样…

第四周数据结构

转载于:https://www.cnblogs.com/bgd150809329/p/6650255.html

gdb x命令_gdb基本命令

参考自:gdb基本命令(非常详细)_JIWilliams-CSDN博客_gdb命令​blog.csdn.net本文介绍使用gdb调试程序的常用命令。 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试…

cmds在线重定义增加列

--输出信息采用缩排或换行格式化EXEC DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, PRETTY, TRUE);--确保每个语句都带分号EXEC DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, SQLTERMINATOR, TRUE);--关闭表索引、外键等关联&…

YOLOX-PAI: An Improved YOLOX, Stronger and Faster than YOLOv6

YOLOX-PAI:一种改进的YOLOX,比YOLOv6更强更快 原文:https://arxiv.org/pdf/2208.13040.pdf 代码:https://github.com/alibaba/EasyCV 0.Abstract We develop an all-in-one computer vision toolbox named EasyCV to facilita…

Linux Shell 重定向到文件以当前时间命名

我们经常在编译的时候,需要把编译的过程日志保留下来,这时候这个命令就非常重要了。 make |tee xxx_$(date %y%m%d%H%M%S).txt

安装一直初始化_3D max 软件安装问题大全

纵使3D虐我千百遍,我待3D如初恋!大家好,我是小文。快节奏生活的今天,好不容易有点学习的热情,打开电脑学习下,没想到被简单的软件安装问题浇灭!这不是耽误了一位伟大的世界设计师诞生的节奏吗&a…

让vim显示空格,及tab字符

1、显示 TAB 键 文件中有 TAB 键的时候,你是看不见的。要把它显示出来: :set list 现在 TAB 键显示为 ^I,而 $显示在每行的结尾,以便你能找到可能会被你忽略的空白字符在哪里。 这样做的一个缺点是在有很多 TAB 的时候看起来很…

TCP/IP 协议栈 -- 编写UDP客户端注意细节

上节我们说到了TCP 客户端编写的主要细节&#xff0c; 本节我们来看一下UDP client的几种情况&#xff0c;测试代码如下&#xff1a; server&#xff1a; #include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h>…

RuntimeError: Address already in use

问题描述&#xff1a;Pytorch用多张GPU训练时&#xff0c;会报地址已被占用的错误。其实是端口号冲突了。 因此解决方法要么kill原来的进程&#xff0c;要么修改端口号。 在代码里重新配置 torch.distributed.init_process_group()dist_init_method tcp://{master_ip}:{mast…

python读取数据流_python3+pyshark读取wireshark数据包并追踪telnet数据流

一、程序说明本程序有两个要点&#xff0c;第一个要点是读取wireshark数据包(当然也可以从网卡直接捕获改个函数就行)&#xff0c;这个使用pyshark实现。pyshark是tshark的一个python封装&#xff0c;至于tshark可以认为是命令行版的wireshark&#xff0c;随wireshark一起安装。…

Windows环境下的安装gcc

Windows具有良好的界面和丰富的工具&#xff0c;所以目前linux开发的流程是&#xff0c;windows下完成编码工作&#xff0c;linux上实现编译工作。 为了提高工作效率&#xff0c;有必要在windows环境下搭建一套gcc,gdb,make环境。 MinGW就是windows下gcc的版本。 下载地址ht…

RuntimeError: NCCL error in:XXX,unhandled system error, NCCL version 2.7.8

项目场景&#xff1a; 分布式训练中遇到这个问题&#xff0c; 问题描述 大概是没有启动并行运算&#xff1f;&#xff1f;&#xff1f;&#xff08; 解决方案&#xff1a; &#xff08;1&#xff09;首先看一下服务器GPU相关信息 进入pytorch终端&#xff08;Terminal&#x…

Codeforces Round #371 (Div. 2) C. Sonya and Queries —— 二进制压缩

题目链接&#xff1a;http://codeforces.com/contest/714/problem/C C. Sonya and Queriestime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputToday Sonya learned about long integers and invited all her friends to …

一张倾斜图片进行矫正 c++_专业性文章:10分钟矫正骨盆前倾

如今&#xff0c;骨盆前倾(又称“下交叉综合征”)非常多&#xff0c;大部分是由于以下两个原因而变得越来越突出&#xff1a;经常久坐不良的运动习惯后面我们讲到纠正骨盆前倾的四个基本步骤&#xff0c;让你快速解决&#xff0c;提高生活质量知识型和系统型的内容&#xff0c;…

vue.js源码学习分享(五)

//配置项var config {/*** Option merge strategies (used in core/util/options)//选项合并策略*/optionMergeStrategies: Object.create(null),/*** Whether to suppress warnings.//是否抑制警告*/silent: false,/*** Show production mode//生产模式 tip message on boot?…

TypeError: can‘t convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory

项目场景&#xff1a; 运行程序&#xff0c;出现报错信息 TypeError: cant convert CUDA tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.。 Traceback (most recent call last):File "tools/demo.py", line 97, in <module>vi…

Secure CRT 自动记录日志

配置自动log操作如下&#xff1a; 1.options ---> Global Options 2、General->Default Session->Edit Default Settings 3、Terminal->Log File 设置如图上所示 点击 日志 &#xff0c;在选项框中 Log file name中填入路径和命名参数&#xff1a; E:\Log\%Y_%M_…

java 异步调用方法_乐字节Java编程之方法、调用、重载、递归

一、概述方法是指人们在实践过程中为达到一定目的和效果所采取的办法、手段和解决方案。所谓方法&#xff0c;就是解决一类问题的代码的有序组合&#xff0c;是一个功能模块。编程语言中的方法是组合在一起来执行操作语句的集合。例如&#xff0c;System.out.println 方法&…