Cordova在Android系統下的檔案操作要點

weixin_34146805發表於2018-02-24

昨天涉及到操作 SQLCipherAndroid 下的加解密操作,最初的需求是新建一個未加密的 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 檔案中如何使用諸如上述程式碼中的 windowcordova 這種的變數,就是需要在檔案前宣告,如下:

    declare let cordova: any;
    declare let window: any;
    

    以上,在《Typescript Error: Cannot find name 'cordova'》中有相當不怎麼樣的解釋。

參考資料:

相關文章