[Cordova] 取得行動裝置的內部及外部剩餘儲存空間

Cordova本身有提供了一些功能可以取得儲存剩餘空間的方式
不過使用上並不完整,需要再搭配一些程式碼作處理

現在的行動裝置儲存空間大多分為兩個,一個是裝置本身的儲存空間,另一個則是外部儲存空間(如SD等)

透過Cordova取得外部儲存空間的方式很簡單,一行就可以搞定了

cordova.exec(funSuccess, funFail, "File", "getFreeDiskSpace", []);

但是若是要取得內部儲存空間就很麻煩,必須透過 window.requestFileSystem 的方法去執行才能取得本機儲存剩餘的空間
簡單的程式碼大概如下

function funGetLocalFreeSpace(callback, start, end) {
    callback = callback == null ? function () { } : callback
    start = start == null ? 0 : start
    end = end == null ? 1 * 1024 * 1024 * 1024 * 1024 : end //starting with 1 TB
    limit = 1024 // precision of 1kb

    start_temp = start
    end_temp = end
    callback_temp = callback
    if (end - start < limit)
        callback(start)
    else {
        window.requestFileSystem(LocalFileSystem.PERSISTENT, parseInt(end_temp - ((end_temp - start_temp) / 2)), function (fileSystem) {
            setTimeout(function () {
                funGetLocalFreeSpace(callback_temp, parseInt(parseInt(end_temp - ((end_temp - start_temp) / 2))), end_temp)
            }, 0)
        }, function () {
            setTimeout(function () {
                funGetLocalFreeSpace(callback_temp, start_temp, parseInt(end_temp - ((end_temp - start_temp) / 2)))
            }, 0)
        })
    }
}

看起來很難懂,下面我就將這兩種取得儲存空間的程式碼整裡一下,讓大家比較好理解

首先先在html上放兩個button,分別是取得內部儲存空間以及外部儲存空間的按鈕

<input type="button" value="取得裝置的內部可用儲存空間" onclick="javascript: funShowLocalFreeSpace();" />
<input type="button" value="取得裝置的外部可用儲存空間" onclick="javascript: funShowExtFreeSpace();" />

接著把取得內部以及外部空間的程式碼作成可呼叫使用的副程式放在Javascript的區塊中

// 取得本機裝置的內存空間
function funGetLocalFreeSpace(callback, start, end) {
    callback = callback == null ? function () { } : callback
    start = start == null ? 0 : start
    end = end == null ? 1 * 1024 * 1024 * 1024 * 1024 : end //starting with 1 TB
    limit = 1024 // precision of 1kb

    start_temp = start
    end_temp = end
    callback_temp = callback
    if (end - start < limit)
        callback(start)
    else {
        window.requestFileSystem(LocalFileSystem.PERSISTENT, parseInt(end_temp - ((end_temp - start_temp) / 2)), function (fileSystem) {
            setTimeout(function () {
                funGetLocalFreeSpace(callback_temp, parseInt(parseInt(end_temp - ((end_temp - start_temp) / 2))), end_temp)
            }, 0)
        }, function () {
            setTimeout(function () {
                funGetLocalFreeSpace(callback_temp, start_temp, parseInt(end_temp - ((end_temp - start_temp) / 2)))
            }, 0)
        })
    }
}

// 取得外部儲存體的空間
function funGetExtendFreeSpace(funSuccess, funFail)
{
    cordova.exec(funSuccess, funFail, "File", "getFreeDiskSpace", []);
}

最後,把按鈕呼叫的兩個副程式放上去,將按鈕按下的動作與呼叫執行的動作串接起來

// 取得內存空間的內容
function funShowLocalFreeSpace()
{
    funGetLocalFreeSpace
    (
        function (intLocalFreeSpace) { alert("內部儲存空間還有:" + funGetFreeSpaceString(intLocalFreeSpace)); }
    );
}

// 取得外部儲存空間的內容
function funShowExtFreeSpace()
{
    funGetExtendFreeSpace
    (
        function (intExtFreeSpace) { alert("外部儲存空間還有:" + funGetFreeSpaceString(intExtFreeSpace)); },
        fail
    );
}

在這裡,我在呼叫完計算剩餘空間的副程式後,多執行了一個funGetFreeSpaceString的程序,這個程序主要目的是在將回傳的空間數字轉換成熟悉的字串,如KB、MB或是GB等等的,程式內容如下所示

// 回傳空間字字串
function funGetFreeSpaceString(intFreeSpace)
{
    var strFreeSpace;

    if (intFreeSpace > 0) {
        if (intFreeSpace > 1024)
            strFreeSpace = (intFreeSpace / 1024).toFixed(2) + " KB";

        if (intFreeSpace > (1024 * 1024))
            strFreeSpace = (intFreeSpace / (1024 * 1024)).toFixed(2) + " MB";

        if (intFreeSpace > (1024 * 1024 * 1024))
            strFreeSpace = (intFreeSpace / (1024 * 1024 * 1024)).toFixed(2) + " GB";
    }

    return strFreeSpace;
}

這樣,就可以把計算空間的功能完全串起來了,直接引用程式碼很簡單,但是在計算本機儲存空間上卻必須要繞一大圈才能達成,我想這也是Cordova團隊需要加強的一個部份

參考資料:
PhoneGap - Display available free space?

本次的範例程式大家可以從GitHub上取得
https://github.com/madukapai/CordovaProject