Windows Mobile Widget 101 – Persistence

Prior posts in this series:

Out of the box the Windows Mobile widget API provides only basic support for saving and retrieving data. The documentation on MSDN shows how you can read and write basic key-value pairs for values up to 4000 bytes but what happens if you want to store more than that? And, what do you do if you want your widget to run as a gadget or on a desktop browser? The following code, which we’ll add to widget.js handles all these scenarios.

—————–
widget.js
—————–

//———————————————————————–
// Storage
//———————————————————————–

        // saves key-value pair (length restricted, use persistData for long string values)
        saveKeyValue: function (key, value) {
            if (window.widget) {
                window.widget.setPreferenceForKey(value, key);
            }
            else if (isGadget && isGadget == true){
                return System.Gadget.Settings.writeString(key,value);
            }
            else {
                return Cookie.set(key,value,365);
            }
        },

        // retrieves key-value pair
        retrieveKeyValue: function (key) {
            if (window.widget) {
                return window.widget.preferenceForKey(key);
            }
            else if (isGadget && isGadget == true){
                return System.Gadget.Settings.readString(key);
            }
            else {
                return Cookie.get(key);
            }
        },
        // Persists Data (any length)
        persistData: function (key, value) {
            if (!value || value == null) {
                WidgetAPI.saveKeyValue(key, 0);
                return;
            }

            var str = value;
            var i = 0;
            var j = 0;

            while (j < str.length) {
                var inc = 2000;
                if (j + inc > str.length) {
                    inc = str.length – j;
                }
                var tmp = str.substring(j, j + inc);
                j += inc;
                WidgetAPI.saveKeyValue(key + i, tmp);
                i += 1;
            }
            WidgetAPI.saveKeyValue(key, i);
        },
        // Checks to see if data exists
        dataExists: function (key) {
            var count = WidgetAPI.retrieveKeyValue(key);
            if (typeof(count)=="undefined" || count == null || count <= 0) {
                return false;
            }
            else {
                return true;
            }
        },

        // Retrive data (any length)
        retrieveData: function (key) {
            var count = WidgetAPI.retrieveKeyValue(key);
            if (!count || count == null || count <= 0) {
                return null;
            }
            var str = "";
            for (var i = 0; i < count; i++) {
                str += WidgetAPI.retrieveKeyValue(key + i);
            }
            return str;
        }

And of course we need some sample code added to main.js and main.htm to demonstrate this in action:

—————– 
main.htm
—————–

        <div id="welcome">Welcome….</div>
        <div id="persistenceDemo">Name:
            <input id="nameTextbox" type="text" />
            <input id="submitButton" type="button" value="Save" onclick="saveName()"/>
        </div>

—————– 
main.js
—————–

function onLoad() {
    // Code omitted as same as previous posts

    sayWelcome();
}

function sayWelcome() {
    var welcome = $get("welcome");
    var name = WidgetAPI.retrieveData("Name");
    if (!name || name == null) {
        name = "…";
    }
    welcome.innerHTML = "Welcome " + name;
}

function saveName() {
    var txt = $get("nameTextbox");
    WidgetAPI.persistData("Name", txt.value);
    sayWelcome();
}

When you run the widget you can enter a name, which will be persisted across runs of your widget. The following screenshots are from the widget running as a widget, gadget and in the desktop browser. Note that the gadget is unique in that if you close the gadget and open another instance it will not remember your settings.  This is because each instance of the gadget has its own unique storage (so you can run multiple instance of the gadget at once). However, if you restart your computer with your gadget running you will notice that it remembers the values. This is because it is the same gadget instance!

imageimage image

Leave a comment