昨天涉及到操作 SQLCipher 在 Android 下的加解密操作,最初的需求是新建一个未加密的 Sqlite 数据库文件,然后分发到目标 Android 系统后,再根据实际情况加密(可能是根据特定目标平台的某具体参数设置加密密钥)。而根据昨天的调研结果,SQLCipher 中如果是加密的数据库文件,可以简单地更改密码,但如果是“加密数据库文件”与“平文数据库文件”之间的转换,则必须重新建一个文件,然后导数据。
于是,随之而来的问题便是 怎样在目标平台中新建文件。嗯,
因为穷,
买不起 Mac,所以没办法在苹果系设备中做开发以及测试,目前先只考虑安卓。
具体步骤:
1. 添加 Cordova 的文件系统操作插件
cordova plugin add cordova-plugin-file`
2. 具体代码
import { Component, OnInit } from '@angular/core';
import { NavController } from 'ionic-angular';
declare let cordova: any;
declare let window: any;
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage implements OnInit {
ngOnInit() {
document.addEventListener('deviceready', () => {
window.resolveLocalFileSystemURL(cordova.file.applicationStorageDirectory, root => {
alert(JSON.stringify(root));
root.getFile('demo.txt', { create: true }, fileEntry => {
alert(JSON.stringify(fileEntry));
}, error => {
alert(JSON.stringify(error))
});
}, error => {
alert(JSON.stringify(error))
});
});
}
}
这里网上有个坑,cordova.file.applicationStorageDirectory
,这个东西是不能加引号的。这个字段的具体表意如下:
Android File System Layout: (From https://www.npmjs.com/package/cordova-plugin-file#android-file-system-layout)
Device Path | cordova.file.* | AndroidExtraFileSystems | r/w? | persistent? | OS clears | private |
---|---|---|---|---|---|---|
file:///android_asset/ | applicationDirectory | assets | r | N/A | N/A | Yes |
/data/data/<app-id>/ | applicationStorageDirectory | - | r/w | N/A | N/A | Yes |
cache | cacheDirectory | cache | r/w | Yes | Yes* | Yes |
files | dataDirectory | files | r/w | Yes | No | Yes |
Documents | documents | r/w | Yes | No | Yes | |
<sdcard>/ | externalRootDirectory | sdcard | r/w | Yes | No | No |
Android/data/<app-id>/ | externalApplicationStorageDirectory | - | r/w | Yes | No | No |
cache | externalCacheDirectory | cache-external | r/w | Yes | No** | No |
files | externalDataDirectory | files-external | r/w | Yes | No | No |
* The OS may periodically clear this directory, but do not rely on this behavior. Clear the contents of this directory as appropriate for your application. Should a user purge the cache manually, the contents of this directory are removed.
** The OS does not clear this directory automatically; you are responsible for managing the contents yourself. Should the user purge the cache manually, the contents of the directory are removed.
Note: If external storage can't be mounted, the cordova.file.external* properties are null.
注意事项
-
至于文件系统权限问题,我在未申请权限的情况下,尝试了在 applicationStorageDirectory(/data/data/<app-id>/) 和 externalRootDirectory(<sdcard>/) 中创建文件,都成功了,所以,看起来并不如《 Cordova实现文件创建和读写操作(支持Android和IOS等)》中讲的那样需要显式定义权限。万一需要申请权限,写法如下:
In config.xml:<widget id="io.ionic.starter" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0"> ... <platform name="android"> ... <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ... ...
由于无知,并且没有去具体调研,有的 Android 的文件系统根本就没有 /data/data 路径,但是大多数 Android 系统都具有 Android/data 目录,所以建议还是写 externalApplicationStorageDirectory 这个参数比较保准吧。
-
另外还需要提及的一点是,在 ts 文件中如何使用诸如上述代码中的 window 和 cordova 这种的变量,就是需要在文件前声明,如下:
declare let cordova: any; declare let window: any;
以上,在《Typescript Error: Cannot find name 'cordova'》中有相当不怎么样的解释。