项目需要通过jni调用c代码实现的加解密逻辑代码,需要用到一个加解密的矩阵文件,于是我就把文件放在了项目中的assest目录下,但是再通过接口调用的时候,接口函数的参数是文件的路径,而android无法获取到assest中具体文件的路径。原因时因为assest目录下的文件在安装app的时候会被打包成一个apk文件存放在手机中,无法得到具体文件的具体路径。这个时候就需要先从apk中读取到文件,把文件拷贝到手机内部存储空间中,然后再获取这个文件的路径,把路径作为jni函数的参数,从而实现文件的调用。
//把assest文件夹下的文件拷贝到指定的存储目录
/**
*
* @param context 上下文对象
* @param assetsPath assest文件夹需要拷贝的文件所在的目录
* @param destPath 拷贝的目的文件夹的路径
*/
protected void copyFilesFromAssets(Context context, String assetsPath, String destPath) {
try {
//获取到assest文件夹下指定目录下的所有文件
//比如需要拷贝的是assest下面的files文件夹下的所有文件,那么assestPath就参数就应该 是:files
String fileNames[] = context.getAssets().list(assetsPath);
File file = new File(destPath);
//循环执行,知道把assestpath目录下所有文件都拷贝完成
if (fileNames.length > 0) {
file.mkdirs();
for (String fileName : fileNames) {
copyFilesFromAssets(context, assetsPath + "/" + fileName,
destPath + "/" + fileName);
}
} else {
if (file.exists()) return;
//获取需要拷贝的文件的流
InputStream instream = context.getAssets().open(assetsPath);
FileOutputStream outstream = new FileOutputStream(new File(destPath));
byte[] buffer = new byte[1024];
int byteCount = 0;
while ((byteCount = instream.read(buffer)) != -1) {
outstream.write(buffer, 0, byteCount);
}
outstream.flush();
instream.close();
outstream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 测试函数,具体的使用方式
* app每次开始运行的时候做一次检测,查看目标文件夹下有没有需要拷贝的文件,如果有,就不用进行
* 操作了,如果没有,调用拷贝函数进行拷贝
*/
public void test(){
String[] files = getApplicationContext().fileList();
if (!Arrays.asList(files).contains("testfile")) {
//这里是将文件拷贝到内部存储中,具体的目录为:/data/data/包名/files
copyFilesFromAssets(this, "testfile", this.getFilesDir().getAbsolutePath());
}
}