如何导出android内部存储的文件(不用root)
这段时间公司项目,涉及到数据缓存,由于需要缓冲的数据太多、太大,通过网络请求,再缓存到本地sqlite数据库,太费时间,消耗流量。所以准备先在本地保存一个标准版sqlite数据库(包含数据),打包到apk文件里,以后需要的操作就是更新数据,这样一来,请求和操作的数据就很小了。
那么问题来了,如何把标准版的sqlite数据库文件(db格式)从内部存储空间里面导出,然后放到项目中assets文件夹下?
想从内部存储空间里拷贝东西,首先要root,手机要root,APP也要获得root权限。这篇博客不讲如何通过root拷贝内容,因为这种办法真的很蠢,root手机会给手机带来不可逆的改变,如果手机很贵的话,尽量不要root;即便手机root后,app也好获得root权限,很麻烦,而且国内手机厂商rom不同,很多手机即便按照步骤一步步root了,也不能查看和赋值内部存储空间里的文件。
那么怎么实现呢?一个简单到可笑的办法(获取这是android系统安全性上的漏洞),在代码中,我们可以访问、读取内部存储空间里的东西,也可以读写SD卡等外部存储空间(要添加相应权限),那么我们就可以通过IO的方法,将内部存储空间中的文件,拷贝到外部存储空间,然后再从外部存储空间里拷贝我们需要的东西就OK了。
实现方式:
1、添加系统权限:
在AndroidManifest.xml中添加读写SD卡等操作权限:
<!-- 写入扩展存储,向扩展卡写入数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2、从内部存储空间通过IO的方式拷贝到SD卡和外部存储空间:
这个时候,已经通过网络请求,将拿到的JSON数据写入到sqlite数据库中了。直接拷贝就好:
/**
* 拷贝内部存储空间的数据库到外部
*
* @throws FileNotFoundException
*/
public void copyDBFile() throws FileNotFoundException {
File toDir = new File(Field.DB_PATH_SD); //外部存储文件夹
if (!toDir.exists()) {
toDir.mkdirs();
} File toDb = new File(Field.DB_PATH_SD + App.BaseDB.dbName); //外部存储数据库
File fromDir = new File(Field.DB_PATH + App.BaseDB.dbName); //内部存储数据库 InputStream is;
OutputStream os;
is = new FileInputStream(fromDir);
os = new FileOutputStream(toDb);
byte[] buffer = new byte[1024];
int length;
try {
/**
* 拷贝过程
*/
while ((length = is.read(buffer, 0, buffer.length)) > 0) {
os.write(buffer, 0, length);
} os.flush();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
相关常量:
/**
* 内部数据库路径
*/
public static final String DB_PATH = File.separator + "data"
+ Environment.getDataDirectory().getAbsolutePath() + File.separator
+ MyApplication.getInstance().getPackageName() + File.separator + "databases" + File.separator; /**
* 外部数据库路径
*/
public static final String DB_PATH_SD = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "tdr" + File.separator; public static class BaseDB{
public static final int version=1;
public static final String dbName="base.db";
}
3、在需要的地方,调用copyDBFile()
try {
//拷贝工具类通过单例获取
BaseDBHelper.getInstance().copyDBFile();
} catch (FileNotFoundException e) {
Log.e(TAG, "fileNotFount");
Log.e(TAG, e.getMessage());
Log.e(TAG, e.toString());
e.printStackTrace();
}
执行完成以后,就可以直接在手机文件夹里看到需要的db文件了:

如此,就可以在非root的前提下,拷贝出内部存储空间里的文件了。不得不说,这也许是android无意的一个安全漏洞吧!因为这个真的很蠢,就好比:一家人有一个保险柜,里面放着家里的财产,贼要是想从保险柜里直接拿走财物是不可以的,但是如果贼先把钱从保险柜里拿到客厅,再从客厅拿走,就完全可以,这样拿走,不仅没有约束,家里主人还会主动把保险柜密码告诉你,把家里的大门为你敞开。。。。。。
4、后记
我之前介绍公司项目的时候,提到:我会把db文件通过离线的方式拷贝到项目的assets文件夹下,然后需要操作数据库的时候,就操作assets文件夹里的数据库。但是这样做会有一个很大的性能上的问题:
sqlite数据库的读写,只能读写/data/...中的数据库文件,如此一来,每次读写或修改assets中的数据库的时候,就要先把assets的数据库拷贝到data对应文件夹下,然后再进行读取,这样一来,效率极低,并且对数据库做完改动后,改动也没有办法同步到源数据库中(也就是数据库会自动还原)。那么这个问题该输入解决呢?以后有时间,再整理一篇博客,说一些这个问题。
如何导出android内部存储的文件(不用root)的更多相关文章
- Android用路径api在内部存储读写文件
复制并修改原有项目 复制之前创建的项目CC+CV操作 需要改动的地方: * 项目名字 * 应用包名 * R文件重新导包 接着修改件/AndroidManifest.xml中的包名:package=&q ...
- Android 在内部存储读写文件
文件读写操作* Ram内存:运行内存,相当于电脑的内存* Rom内存:内部存储空间,相当于电脑的硬盘* sd卡:外部存储空间,相当于电脑的移动硬盘在内部存储空间中读写文件>小案例:用户输入账号密 ...
- Android 数据存储之 文件存储
-------------------------------------------文件存储----------------------------------------------- 文件存储是 ...
- Android 内部存储相关的函数(getCacheDir,getDir, getFileStreamPath,getFilesDir,openFileInput, ...)
为了保证应用程序存储数据的安全性,开发人员在开发应用程序的过程中须要注意使用Android 应用程序的内部存储空间. 依据不同的要求.将相应的数据文件.缓存文件.暂时文件等分别存储在相应的位置. 注意 ...
- android 内部存储 安装apk
在做应用自动更新模块下载apk时遇到了内部存储和sd卡存储两种情况,存在sk卡中存储apk可以正常安装,可是在内部存储中安装apk时出现了parse error的问题. 在网上搜了搜,大致分为两种方案 ...
- Android 内部存储读写介绍
内部存储读写 内容介绍 Android系统允许应用程序创建仅能够自身访问的私有文件,文件保存在设备的内部存储器上,在Linux系统下的/data/data//files目录中 Android系统不仅支 ...
- Android 内部存储和外部存储
应用程序的一些配置文件需要存储在手机上.一般分为内部存储和SD卡存储. 一. 内部存储 ,以 FileOutputStream File file = new File(getFilesDir(),& ...
- Android 内部存储安装apk文件实现
目前国内市场的山寨机横行,安卓手机升级也是一天一个样,对于原来老手机可能没有SDCARD,导致我们的APP不能下载资源,无法更新APP,针对这种情况有以下解决方案.通过以下函数判断是否有SD卡再判断下 ...
- android 内部存储相关知识点: getfilestreampath getDir 子文件夹
文件系统的API的命名方式和常规的不一样: 都是get命名,但是功能就是能创建文件夹... 这种方式的API 命名习惯和常规的不一样... createXXX ----方便查找 http://i ...
随机推荐
- C++ Primer Plus读书笔记(六)分支语句和逻辑运算符
1. 以上均包含在cctype中 1 #include<cctype> 2 //#include<ctype.h> 2.文件操作 (1)头文件 1 #include<fs ...
- Smarty 3.1.34 反序列化POP链(任意文件删除)
Smarty <= 3.1.34,存在任意文件删除的POP链. Exp: <?php class Smarty_Internal_Template { public $smarty = n ...
- DEDECMS:修改网站底部出现的POWER BY DEDECMS
在include/dedesql.classs.php文件中找到第588行: $arrs1 = array(0x63,0x66,0x67,0x5f,0x70,0x6f,0x77,0x65,0x72,0 ...
- C++ 标准模板库(STL):map
目录 4. map 4.1 map的定义 4.2 map容器内元素的访问 4.3 map常用函数实例解析 4.4 map的常见用途 4. map map翻译为映射,也是常用的STL容器. 在定义数组时 ...
- Flink-v1.12官方网站翻译-P029-User-Defined Functions
用户自定义函数 大多数操作都需要用户定义的函数.本节列出了如何指定这些函数的不同方法.我们还涵盖了累加器,它可以用来深入了解您的Flink应用. Lambda函数 在前面的例子中已经看到,所有的操作都 ...
- 1153 Decode Registration Card of PAT
A registration card number of PAT consists of 4 parts: the 1st letter represents the test level, nam ...
- 树链剖分(附带LCA和换根)——基于dfs序的树上优化
.... 有点懒: 需要先理解几个概念: 1. LCA 2. 线段树(熟练,要不代码能调一天) 3. 图论的基本知识(dfs序的性质) 这大概就好了: 定义: 1.重儿子:一个点所连点树size最大的 ...
- Codeforces Global Round 11 C. The Hard Work of Paparazzi (DP)
题意:有\(r\)X\(r\)的网格图,有\(n\)位名人,会在\(t_i\)时出现在\((x_i,y_i)\),如果过了\(t_i\)名人就会消失,从某一点走到另外一点需要花费的时间是它们之间的曼哈 ...
- typedef struct xxx xxx与struct xxx区别 && “->”和“.”访问结构体变量
1. struct //是C中的结构体的关键词.如: stuct node{ int a;.....} a; node 相当于结构体的类型,关键是其实在C中stuct node 才相当于一个数据类型, ...
- Codeforces Round #656 (Div. 3) D. a-Good String (DFS)
题意:有一个长度为\(n=2^k\)的字符串,对于某个字符\(c\),我们定义他是一个\(c-good\),如果: 1.\(len=1\),并且\(s[1]=c\). 2.\(len>1 ...