wtorek, 27 grudnia 2011

Notatki o Windows 8 - odc. 15

Aplikacje Metro - JS: pliki multimedialne - konwertowanie do innego formatu, przycinanie; urządzenia - listowanie, informacje, notyfikacje o dodaniu, usunięciu, zmianie, kontenery urządzeń, urządzenia na przenośnym komputerze, wyświetlanie ikony, sensory ruchu i położenia (akcelerometr, żyroskop, kompas, inklinometr, sensor orientacji, sensor prostej orientacji - położenie urządzenia), sensor natężenia światła, położenie geograficzne (natywne API i specyfikacja HTML5), urządzenia pamięci przenośnej (listowanie, pobieranie i zapisywanie plików, AutoPlay - odczyt plików)

Transcoding

var source;

var destination;

 

var openPicker = new Windows.Storage.Pickers.FileOpenPicker();

openPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.videosLibrary;

openPicker.fileTypeFilter.replaceAll([".wmv", ".mp4"]);

openPicker.pickSingleFileAsync().then(

    function(file){

        source = file;

 

        var savePicker = new Windows.Storage.Pickers.FileSavePicker();

        savePicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.videosLibrary;

        savePicker.defaultFileExtension = ".mp4";

        savePicker.suggestedFileName = "New Video";

        savePicker.fileTypeChoices.insert("MPEG4", [".mp4"]);

        return savePicker.pickSaveFileAsync();

    }).then(

    function(file){   

        destination = file;

 

        var profile = Windows.Media.Capture.MediaEncodingProfile.createMp4(

            Windows.Media.Capture.VideoEncodingQuality.hd720p);

 

        var transcoder = new Windows.Media.Transcoding.MediaTranscoder();

        return transcoder.transcodeFileAsync(source, destination, profile);

    }).then(

    function(){

        // Update the UI for completion.

    },

    function(error){

        // Handle Errors.

    },

    function(percent)

    {

        // Update the UI for progress.

    });

<video controls id="myvideo"/>

var video = document.getElementById('myvideo');

video.src = URL.createObjectURL(destination);

video.play();

Trimming

For trimming, you don't have to specify an encoding profile in the TranscodeFileAsync method. If the profile is omitted, the destination file has the same format as the input file.

        var transcoder = new Windows.Media.Transcoding.MediaTranscoder();

        transcoder.trimStartTime = 1000;

        transcoder.trimStopTime = 9000;

        return transcoder.transcodeFileAsync(source, destination, profile);

When you transcode a file, there are two phases:

  1. Set up: The MediaTranscoder finds the right codecs, configures them, and returns a deferral object.
  2. Processing: The MediaTranscoder sends the audio and video streams through the decoders and encoders and writes the output.

The MediaTranscoder.TranscodeFileAsync method performs both of these phases as single action. The application is notified when phase 2 completes.

Most of the time will be spent in phase 2, the processing step. But if an error occurs, it is most likely to occur during phase 1- especially if you use a custom encoding profile or a third-party codec.

var transcoder = new Windows.Media.Transcoding.MediaTranscoder();

        return transcoder.getFileTranscodeDeferralAsync(source, destination, profile);

    }).then(

 

    // Begin phase 2.

 

    function(deferral){

        return deferral.transcodeAsync();

    }).then(

    function(){

        // Update the UI for completion.

    },

    function(error){

        // Handle errors.

    },

    function(percent)

    {

        // Update the UI for progress.

    });

Call the MediaTranscoder.GetFileTranscodeDeferralAsync method. The method is asynchronous and returns a MediaTranscodeDeferralOperation object when it completes.

At this point you can store the deferral object to use later. When you are ready to start phase 2 you can call MediaTranscodeDeferral.CanTranscode to determine if the transcode operation can be performed.

Call the MediaTranscodeDeferral.TranscodeAsync method to start the processing.

Support for devices

You can support a number of devices in your Metro style app:

  • Motion and orientation sensors (like accelerometers, gyrometers, inclinometers, and orientation sensors) let your app respond to user movement.
  • Light sensors let your app respond to changes in ambient light.
  • Geolocation lets your app detect and respond to user location.

The Windows.Devices.Enumeration and Windows.Device.Enumeration.Pnp namespaces enable you to enumerate devices.

The Windows Runtime Enumeration API lets you enumerate a device by the functionality it provides, or by identifying the physical device, which may provide more than one function. Device interfaces represent specific functionality that a device provides, and device containers group together the info associated with the different functions that a single physical device provides.

The container for this device groups the separate device interfaces as belonging to a single device, since each device interface in the physical device shares the same container ID. The enumeration methods in the Windows.Devices.Enumeration namespace generate results by device interface. The methods in the Windows.Devices.Enumeration.Pnp namespace additionally allow you to enumerate by device containers.

The Windows.Devices.Enumeration namespace provides two methods for enumerating devices: FindAllAsync, and CreateWatcher. FindAllAsync does a one-time search for available devices and is best for apps that don't need updates if devices arrive, depart, or change. CreateWatcher enumerates devices and also raises notification events when devices arrive, depart, or change after the initial enumeration completes.

function onEnumerateDeviceInterfaces() {

    document.getElementById("Output").innerHTML = ""; // clear output

    try {

        var selection = document.getElementById("SelectInterfaceClass");

        var selectedDeviceClass =

            selection.options[selection.selectedIndex].value;

        var deviceClass;

        var Enumeration = Windows.Devices.Enumeration;

        var selectorString = "";

 

        var mtpServiceDevice = Windows.Devices.Portable.ServiceDevice;

        var smsDevice = Windows.Devices.Sms.SmsDevice;

        var proximityDevice = Windows.Networking.Proximity.ProximityDevice;

        switch (selectedDeviceClass) {

            case "audioCapture":

                // same as:

                // var mediaDevice = Windows.Media.Devices.MediaDevice;

                // selectorString =  mediaDevice.getAudioCaptureSelector();

                deviceClass = Enumeration.DeviceClass.audioCapture;

                break;

            case "audioRender":

                // same as:

                // var mediaDevice = Windows.Media.Devices.MediaDevice;

                // selectorString =  mediaDevice.getAudioRenderSelector();

                deviceClass = Enumeration.DeviceClass.audioRender;

                break;

            case "portableStorageDevice":

                // same as:

                // var storageDevice = Windows.Devices.Portable.StorageDevice;

                // selectorString = storageDevice.getDeviceSelector();

                deviceClass = Enumeration.DeviceClass.portableStorageDevice;

                break;

            case "videoCapture":

                // same as:

                // var mediaDevice = Windows.Media.Devices.MediaDevice;

                // selectorString =  mediaDevice.getVideoCaptureSelector();

                deviceClass = Enumeration.DeviceClass.videoCapture;

                break;

            case "mtpService":

            // Windows.Devices.Portable.ServiceDevice.GetDeviceSelector

                selectorString = mtpServiceDevice.GetDeviceSelector();

                break;

            case "sms":

            // Windows.Devices.Sms.SmsDevice.GetDeviceSelector

                selectorString = smsDevice.GetDeviceSelector();

                break;

            case "proximity":

            // Windows.Networking.Proximity.ProximityDevice.GetDeviceSelector

                selectorString = proximityDevice.GetDeviceSelector();

                break;

            default: deviceClass = Enumeration.DeviceClass.all;

        }

 

        var DeviceInformation = Enumeration.DeviceInformation;

        if (selectorString == "") {

            DeviceInformation.findAllAsync(deviceClass).then(

                successCallback,

                errorCallback

            );

        } else {

            DeviceInformation.findAllAsync(selectorString).then(

                successCallback,

                errorCallback

            );

        }

    } catch (e) {

        document.getElementById("statusMessage").innerHTML =

            "Failed to enumerate devices, error: " + e.message;

    }

}

 

// Handles successful completion of the findAllAsync method.

function successCallback(deviceInformationCollection) {

    var numDevices = deviceInformationCollection.length;

    document.getElementById("statusMessage").innerHTML =

        numDevices + " device interface(s) found";

    if (numDevices) {

        for (var i = 0; i < numDevices; i++) {

            printFriendlyNameAndID(deviceInformationCollection[i],

                document.getElementById("Output"));

        }

    } else {

        document.getElementById("statusMessage").innerHTML = "No devices found";

    }

}

 

// Handles an error completion of the findAllAsync method.

function errorCallback(e) {

    document.getElementById("statusMessage").innerHTML =

        "Failed to find devices, error: " + e.message;

}

 

// Prints the friendly name of the device interface and its ID

// The ID is the device interface path.

function printFriendlyNameAndID(deviceInterface, log) {

 

    // The name property is equivalent to System.ItemNameDisplay property

    log.innerHTML += "<h3>" +

            deviceInterface.name + "<h3/>";

    log.innerHTML += "<p>Interface ID: " + deviceInterface.id;   

    log.innerHTML += "<p>Enabled: " + deviceInterface.isEnabled;

   

    log.innerHTML += "<br />";

}

The code for using the selector string instead of the DeviceClass enumeration is commented out within the relevant cases in the switch statement.

For the last 3 choices, there is no DeviceClass enumeration value so only the API call for getting the appropriate selector string is shown.

To start accessing device functionality rather than just listing devices, pass the DeviceInformation.id property of a device that you've enumerated to the Windows Runtime API for using the device. For instance, you can use the ID of an enumerated webcam to set the Windows.Media.Capture.MediaCaptureInitializationSettings.VideoDeviceId property, to specify the webcam to use for video capture.

These are some methods that take a device ID to initialize an object for using a device.

For WPD Devices that use an MTP device service (enumerated using Windows.Devices.Portable.ServiceDevice.GetDeviceSelector or Windows.Devices.Portable.ServiceDevice.GetDeviceSelectorFromServiceId), you can create a COM Automation object to work with the device like this:

deviceFactory = new ActiveXObject("PortableDeviceAutomation.Factory");

    var device = deviceFactory.getDeviceFromId(deviceId);

If the device interface class you want isn't in the Windows.Device.Enumeration.DeviceClass enumeration, and there is no Windows Runtime API to get a selector for you, you'll have to build an Advanced Query Syntax (AQS) string yourself and pass it to findAllAsync.

      if (textinput.value != ""){

            var textDeviceInterfaceClassGUID = textinput.value;

            var selectorString = "System.Devices.InterfaceClassGuid:=" +

                textDeviceInterfaceClassGUID +

                " AND System.Devices.InterfaceEnabled:=true";

            var Enum = Windows.Devices.Enumeration;

            Enum.DeviceInformation.findAllAsync(selectorString, null).then(

                    successCallback,

                    errorCallback

                );

This sample did a one-time enumeration, but this won't be enough for an app that needs to update its user interface when a new device is added, removed, or changed.

Get notifications on device add, remove or change

You use the DeviceWatcher class to start a device enumeration. For each device that's found, DeviceWatcher raises an Add event, until all devices are found and the enumeration is complete. After the initial enumeration is complete, DeviceWatcher continues to raise events if a device is added, updated, or removed.

    var watcher;

    var isEnumerationComplete = false;

    var deviceArray = new Array(); // Saves the enumeration results

 

    function WatchDevices() {

        try {

            output.innerHTML = ""; // clear output field

 

            watcher =

                Windows.Devices.Enumeration.DeviceInformation.createWatcher();

            // Add event handlers

            watcher.addEventListener("added", onAdded);

            watcher.addEventListener("removed", onRemoved);

            watcher.addEventListener("updated", onUpdated);

            watcher.addEventListener("enumerationcompleted",

                onEnumerationCompleted);

            watcher.addEventListener("stopped", onStopped);

            // Start enumerating and listening for events

            watcher.start();

        } catch (e) {

            document.getElementById("statusMessage").innerHTML =

                "Failed to create watcher, error: " + e.message;

        }

    }

 

    function stopWatcher() {

        try {

            watcher.stop();

        }

        catch (e) {

            document.getElementById("statusMessage").innerHTML =

                "Failed to stop watcher: " + e.message;

        }

    }

 

    function onAdded(devinfo) {

        document.getElementById("output").innerHTML += "<p>Device added: " +

            devinfo.name + "</p>";

        deviceArray.push(devinfo);

        if (isEnumerationComplete) {

            output.innerHTML = ""; // clear output field

            printDeviceArray(document.getElementById("output"));

        }

    }

 

    function onUpdated(devUpdate) {

        document.getElementById("output").innerHTML += "<p>Device updated.</p>";

        for (var i = 0; i < deviceArray.length; i++) {

            if (deviceArray[i].id == devUpdate.id) {

                deviceArray[i].update(devUpdate);

            }

        }

        output.innerHTML = ""; // clear output field

        printDeviceArray(document.getElementById("output"));

    }

 

    function onRemoved(devupdate) {

        document.getElementById("output").innerHTML += "<p>Device removed.</p>";

        for (var i = 0; i < deviceArray.length; i++) {

            if (deviceArray[i].id == devupdate.id) {

                deviceArray[i].slice(devupdate);

            }

        }

        output.innerHTML = ""; // clear output field

        printDeviceArray(document.getElementById("output"));

    }

 

    function onEnumerationCompleted(obj) {

        isEnumerationComplete = true;

        document.getElementById("output").innerHTML +=

            "<p>Enumeration Completed.</p>";

        printDeviceArray(document.getElementById("output"));

    }

 

    function onStopped(obj) {

        document.getElementById("output").innerHTML += "<p>Stopped.</p>";

        if (watcher.status == aborted) {

           document.getElementById("output").innerHTML +=

            "<p>Enumeration stopped unexpectedly. </p>";

           document.getElementById("output").innerHTML +=

            "<p>Click the Watch button to restart enumeration.</p>";

        } else if (watcher.status == stopped) {

           document.getElementById("output").innerHTML +=

            "<p>You requested to stop enumeration. </p>";

           document.getElementById("output").innerHTML +=

            "<p>Click the Watch button to restart enumeration.</p>";

        } 

    }

Save the last used device to reuse later

The first time you run an app that needs to use devices, it enumerates available devices, selects a DeviceInformation object from the enumeration results, and passes the DeviceInformation.Id property to a Windows Runtime API for accessing the device. It can be good practice for an app to save this device Id, so that the next time the app runs, it can start up more quickly by checking if the last-used device is available, before starting another enumeration.

function getLastUsedDeviceInfo(savedDeviceID) { 

    // Create a DeviceInformation object from the ID

    var Enum = Windows.Devices.Enumeration;

    var DevInf = Enum.DeviceInformation;

    DevInf.createFromIdAsync(savedDeviceId).then(

        function(devinfo) {            

            printMessage("Found last-used device. Name: " + devinfo.name);

            if (devinfo.isEnabled) {

                // Add code to pass devinfo.id to an appropriate API

                // For instance, if devinfo is a camera, use the id property

                // to select the camera as the one the Camera Capture API

                // should use, by setting the VideoDeviceId property of

                // Windows.Media.Capture.MediaCaptureInitializationSettings

            } else {

                // Handle the case of the device not being enabled

            }

        },

        function (e) {

            displayError("Failed to create DeviceInformation: " + e.message);

            // since the last-used device wasn't found, add code here

            // to call FindAllAsync or CreateWatcher to find other devices.

        });

}

Retrieve device containers and additional properties

The device container that represents the physical device as seen by the user. The device container lets you access information that pertains to the whole device hardware product, rather than one of its functional interfaces. Examples of device container properties are manufacturer or model name.

By default, the results of asyncFindAll and createDeviceWatcher only include the following properties:

  • System.ItemNameDisplay
  • System.Devices.Icon
  • System.Devices.InterfaceEnabled
  • System.Devices.IsDefault

You can specify additional properties to include in the results by using the additionalProperties parameter, as follows:

// Create a set of two additional properties

   var propertiesToRetrieve = new Array();

   propertiesToRetrieve.push("System.Devices.InterfaceClassGuid");

   propertiesToRetrieve.push("System.Devices.ContainerId");

 

   Windows.Devices.Enumeration.findAllAsync(selectorString,

             propertiesToRetrieve).then(successCallback, errorCallback);)

 

// Handles successful completion of the findAllAsync method.

function successCallback(deviceInformationCollection) {

    var numDevices = deviceInformationCollection.length;

    if (numDevices) {

        for (var i = 0; i < numDevices; i++) {

            printProperties(document.getElementById("log"),

                 deviceInformationCollection[i].properties);

        }

    }

}

 

function printProperties(log, prop) {

    log.innerHTML += "property store count is: " + prop.size;

    var pt = prop.first();

    while (pt.hasCurrent) {

        log.innerHTML += "<br />" + pt.current.key + " := " + pt.current.value;

        pt.moveNext();

    }

    log.innerHTML += "<br />";

}

You may need to get properties of the container a device interface belongs to. For instance, if you have the device ID of a selected device, but need to get the model name, you need to create a container object because System.Devices.ModelName is a container property, not a device interface property.

string GetModelNameFromDeviceID (devID) {

// First create a DeviceInformation object from the ID.

// Create the argument that specifies that additional properties

// returned should include the System.Devices.ContainerId property

   var propertiesToGet = new Array();

   propertiesToGet.push("System.Devices.ContainerId");

 

 

// Create a DeviceInformation object from the ID

   var Enum = Windows.Devices.Enumeration;

   var DevInfo = Enum.DeviceInformation;

   var contID;   // The container ID

   DevInfo.createFromIdAsync(devID, propertiesToGet).then(

       function(devInf) {            

            var prop = devInf.properties;

            if (prop) {

                contID = prop.lookup("System.Devices.ContainerID");              

            }

       },

       function (e) {

           displayError("Failed to create DeviceInformation: " + e.message);

       });

 

// Use the container ID to create a PnPObject representing the container,

// and specify that the created object should have a

// System.Devices.ModelId property.

 

 

// Create the argument that specifies that the additional properties to

// return should include the System.Devices.ContainerId property

   var containerPropertiesToGet = new Array();

   containerPropertiesToGet.push("System.Devices.ModelId");

 

   var modelID;

 

 

// NOTE: We need to add extra braces "{}" back to the container ID before

// passing it to createIdAsync (a pair of braces is lost in the implicit

// conversion from GUID to string).

   contID = "{" + contID + "}";

 

// Create the container from its ID.

   Enum.Pnp.createFromIdAsync(contID, containerPropertiesToGet).then(

       function(contInf) {

           var prop = contInf.properties;

           if (prop) {

               modelID = prop.lookup("System.Devices.ModelID");

           });

   return modelID;

}

 

Enumerating device containers and other PnP object types

The Plug and Play (PnP) object types in the PnpObjectType enumeration represent device information associated with a particular device interface, the device that the interface is part of, a class of device interfaces, or the device container which represents the entire hardware product. The device container describes the visible aspects of a device hardware product, such as manufacturer or model name. Windows.Devices.Enumeration.DeviceInformation represents the same type as PnpObjectType.DeviceInterface.

The Windows.Devices.Enumeration.PnP namespace allows you to enumerate devices and device containers, as well as devices and device interfaces.

function onEnumerateDeviceContainers() {

    try {

 

        document.getElementById("output").innerHTML = "";

 

        var propertiesToRetrieve = new Array();

        propertiesToRetrieve.push("System.ItemNameDisplay");

        propertiesToRetrieve.push("System.Devices.ModelName");

        propertiesToRetrieve.push("System.Devices.Manufacturer");

 

        var DevEnum = Windows.Devices.Enumeration;

        var Pnp = DevEnum.Pnp;

        var pnpObjType = Pnp.PnpObjectType;

        var deviceContainerType = pnpObjType.deviceContainer;

 

        Pnp.PnpObject.findAllAsync(

            deviceContainerType,

            propertiesToRetrieve).then(

                function (devinfoCollection) {

                    var numDevices = devinfoCollection.length;

                    document.getElementById("statusMessage").innerHTML =

                        numDevices + " device containers(s) found";

                    if (numDevices) {

                        for (var i = 0; i < numDevices; i++) {

                            printDeviceContainer(devinfoCollection[i],

                            document.getElementById("output"));

                        }

                    } else {

                    document.getElementById("statusMessage").innerHTML =

                        ("No devices found");

                    }

                },

                function (e) {

                    document.getElementById("statusMessage").innerHTML =

                        ("Failed to find devices, error: " + e.message);

                });

    } catch (e) {

        document.getElementById("statusMessage").innerHTML =

            ("Failed to enumerate devices, error: " + e.message);

    }

}

 

Check where a device is located on a portable computer

How to find out if an embedded camera or other embedded device is in the front, back, lid, or panel of a portable computer.

The EnclosureLocation property used in this example is only valid for devices that expose this location information in ACPI tables. EnclosureLocation will be null if the device does not declare this data in its ACPI table.

function locationMessage(deviceInformation) {

   var locationMessage = "";

   var location = deviceInformation.enclosureLocation;

   if (location == null) {

       return "The device does not specify its enclosure location.";

   }

   if (location.inDock) {

       message = "In docking station.";

   } else if (location.inLid) {

       message = "In lid.";

   } else switch (location.panel) {

       var Panel = Windows.Devices.Enumeration.Panel

       case Panel.unknown:

           locationMessage = "In unknown panel.";

           break;

       case Panel.front:

           locationMessage = "In front panel.";

           break;

       case Panel.back:

           locationMessage = "In back panel.";

           break;

       case Panel.top:

           locationMessage = "In top panel.";

           break;

       case Panel.bottom:

           locationMessage = "In bottom panel.";

           break;

       case Panel.left:

           locationMessage = "In left panel.";

           break;

       case Panel.right:

           locationMessage = "In right panel.";

           break;

       default:

           locationMessage = "Location unknown.";

           break;

   }

   return locationMessage;

}

 

Display a device icon

 

// Takes a parameter of type DeviceInformation

// and retrieves a DeviceThumbnail to pass to displayImage()

function getImage (device) {  

 

    var thumbnail = null;

    if (device){

        device.getThumbnailAsync().then(

            function (thumbnail) {

            // A valid thumbnail is always returned.

                displayImage(thumbnail);

            });

    }                                                                                    

}

 

(function() {

    var Enum = Windows.Devices.Enumeration;

    Enum.DeviceInformation.findAllAsync(

        Enum.DeviceClass.videoCapture).then(

                    successCallback

            );

})();

 

function successCallback(deviceInformationCollection) {

    var numDevices = deviceInformationCollection.length;

    if (numDevices) {

        getImage(deviceInformationCollection[0]);

    } else {

        document.getElementById("statusMessage").innerHTML =

            "No devices found.";

    }

}

The size of the returned icon is 256 x 256. However, in Windows Developer Preview, the size may vary.

Accelerometer

An app based on an accelerometer typically uses only one or two axes for input. However, it may also use the shake event as another input source.

(function () {

    'use strict';

    var accelerometer;

 

    // This function is invoked within onDataChanged to

    // retrieve the given identifier from the HTML document.

    function id(elementId) {

        return document.getElementById(elementId);

    }

 

    // This function is called each time an accelerometer event

    // is fired by the driver.

    function onDataChanged(e) {

        var accelX = e.reading.accelerationX.toFixed(2);

        var accelY = e.reading.accelerationY.toFixed(2);

        var accelZ = e.reading.accelerationZ.toFixed(2);

 

        id('eventOutputX').innerHTML = accelX;

        id('eventOutputY').innerHTML = accelY;

        id('eventOutputZ').innerHTML = accelZ;

    }

 

    WinJS.Application.onmainwindowactivated = function (e) {

        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

            // Retrieve the default accelerometer and

            // establish the event handler.

            if (accelerometer == null) {

                    accelerometer = Windows.Devices.Sensors.Accelerometer.getDefault();

                    accelerometer.addEventListener("readingchanged", onDataChanged);

            }

        }

    }

 

    WinJS.Application.start();

})();

 

Gyrometer

An appl uses a gyrometer to determine the rate of rotation around three axes (X, Y, and Z).

Gyrometers and accelerometers work together as game controllers. While the accelerometer measures device orientation, the gyrometer gives nearly instantaneous information about changes in orientation.

(function () {

    'use strict';

    var gyrometer;

 

    function id(elementId) {

        return document.getElementById(elementId);

    }

 

    function onDataChanged(e) {

        id('txtXVelocity').innerHTML = e.reading.angularVelocityX.toFixed(2);

        id('txtYVelocity').innerHTML = e.reading.angularVelocityY.toFixed(2);

        id('txtZVelocity').innerHTML = e.reading.angularVelocityZ.toFixed(2);

    }

 

    WinJS.Application.onmainwindowactivated = function (e) {

        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

            gyrometer = Windows.Devices.Sensors.Gyrometer.getDefault();

            gyrometer.addEventListener("readingchanged", onDataChanged);

        }

    }

 

    WinJS.Application.start();

})();

Compass

(function () {

    'use strict';

    var compass;

 

    // This function is invoked within onDataChanged to

    // retrieve the given identifier from the HTML document.

    function id(elementId) {

        return document.getElementById(elementId);

    }

 

    // This function is called each time a compass event

    // is fired by the driver.

    function onDataChanged(e) {

        id('txtMagNorth').innerHTML = e.reading.headingMagneticNorth.toFixed(2);

        if (e.reading.headingTrueNorth != null) {

            id('txtTrueNorth').innerHTML = e.reading.headingTrueNorth.toFixed(2);

        }

    }

 

    WinJS.Application.onmainwindowactivated = function (e) {

        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

            // Retrieve the default compass and

            // establish the event handler.

            compass = Windows.Devices.Sensors.Compass.getDefault();

            compass.addEventListener("readingchanged", onDataChanged);

        }

    }

 

    WinJS.Application.start();

})();

 

Inclinometer

 

(function () {

    'use strict';

    var inclinometer;

 

    function id(elementId) {

        return document.getElementById(elementId);

    }

 

    function onDataChanged(e) {

        var pitch = e.reading.pitchDegrees.toFixed(2);

        var roll = e.reading.rollDegrees.toFixed(2);

        var yaw = e.reading.yawDegrees.toFixed(2);

 

        id('txtXAngle').innerHTML = pitch;

        id('txtYAngle').innerHTML = roll;

        id('txtZAngle').innerHTML = yaw;

    }

 

    WinJS.Application.onmainwindowactivated = function (e) {

        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

            inclinometer = Windows.Devices.Sensors.Inclinometer.getDefault();

            inclinometer.addEventListener("readingchanged", onDataChanged);

        }

    }

 

    WinJS.Application.start();

})();

 

Orientation sensor

A complex 3-D app can use the Orientation sensor to adjust the user's perspective. This sensor combines input from the accelerometer, gyrometer, and compass.

The Orientation sensor returns two forms of data: a quaternion and a rotation matrix. A quaternion can be most easily understood as a rotation of a point [x,y,z] about a single arbitrary axis. This is different from a rotation matrix, which represents rotations around 3 axes.

(function () {

    'use strict';

    var orientationSensor;

 

    function id(elementId) {

        return document.getElementById(elementId);

    }

 

    function onDataChanged(e) {

        id('txtQuaternion').innerHTML = "W: " + e.reading.quaternion.w.toFixed(6)

                                              + "X: " + e.reading.quaternion.x.toFixed(6)

                                              + "Y: " + e.reading.quaternion.y.toFixed(6)

                                              + "Z: " + e.reading.quaternion.z.toFixed(6);

 

        id('txtRotationMatrix').innerHTML = "M11: " + e.reading.rotationMatrix.m11.toFixed(6)

                                                  + "M12: " + e.reading.rotationMatrix.m12.toFixed(6)

                                                  + "M13: " + e.reading.rotationMatrix.m13.toFixed(6)

                                                  + "M21: " + e.reading.rotationMatrix.m21.toFixed(6)

                                                  + "M22: " + e.reading.rotationMatrix.m22.toFixed(6)

                                                  + "M23: " + e.reading.rotationMatrix.m23.toFixed(6)

                                                  + "M31: " + e.reading.rotationMatrix.m31.toFixed(6)

                                                  + "M32: " + e.reading.rotationMatrix.m32.toFixed(6)

                                                  + "M33: " + e.reading.rotationMatrix.m33.toFixed(6);

    }

 

    WinJS.Application.onmainwindowactivated = function (e) {

        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

            orientationSensor = Windows.Devices.Sensors.OrientationSensor.getDefault();

            orientationSensor.addEventListener("readingchanged", onDataChanged);

         }

    }

 

    WinJS.Application.start();

})();

Determining device orientation

Apps use the SimpleOrientation sensor to determine the current device orientation (portrait up, portrait down, landscape left, landscape right), as well as the device's face-up or face-down status.

Rather than returning properties like "portrait-up" or "landscape left", this sensor returns a rotation value: "Not rotated", "Rotated90DegreesCounterclockwise", and so on.

Portrait Up: NotRotated, Landscape Left: Rotated90DegreesCounterclockwise, Portrait Down: Rotated180DegreesCounterclockwise, Landscape Right: Rotated270DegreesCounterclockwise.

(function () {

    'use strict';

    var orientationSensor;

 

    function id(elementId) {

        return document.getElementById(elementId);

    }

 

    function onDataChanged(e) {

        switch (e.orientation) {

            case Windows.Devices.Sensors.SimpleOrientation.notRotated:

                id('txtOrientation').innerHTML = "Not Rotated";

                break;

            case Windows.Devices.Sensors.SimpleOrientation.rotated90DegreesCounterclockwise:

                id('txtOrientation').innerHTML = "Rotated 90";

                break;

            case Windows.Devices.Sensors.SimpleOrientation.rotated180DegreesCounterclockwise:

                id('txtOrientation').innerHTML = "Rotated 180";

                break;

            case Windows.Devices.Sensors.SimpleOrientation.rotated270DegreesCounterclockwise:

                id('txtOrientation').innerHTML = "Rotated 270";

                break;

            case Windows.Devices.Sensors.SimpleOrientation.faceup:

                id('txtOrientation').innerHTML = "Face Up";

                break;

            case Windows.Devices.Sensors.SimpleOrientation.facedown:

                id('txtOrientation').innerHTML = "Face Down";

                break;

            default:

                id('txtOrientation').innerHTML = "Undefined orientation " + e.orientation;

                break;

        }

    }

 

    WinJS.Application.onmainwindowactivated = function (e) {

        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

            orientationSensor = Windows.Devices.Sensors.SimpleOrientationSensor.getDefault();

            orientationSensor.addEventListener("orientationchanged", onDataChanged);

        }

    }

 

    WinJS.Application.start();

})();

You might use the Faceup and Facedown values to determine when to save state information and shut down your app.

Responding to changes in lighting

The Windows.Devices.Sensors namespace includes support for a LightSensor object that apps can use to retrieve the current illuminance as a LUX value.

(function () {

    'use strict';

    var lightSensor;

 

    // This function is invoked within onDataChanged to

    // retrieve the given identifier from the HTML document.

    function id(elementId) {

        return document.getElementById(elementId);

    }

 

    // This function is called each time an accelerometer event

    // is fired by the driver.

    function onDataChanged(e) {

        id('eventOutputIlluminance').innerHTML = e.reading.illuminanceInLux.toFixed(2);

    }

 

    WinJS.Application.onmainwindowactivated = function (e) {

        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

            // Retrieve the default accelerometer and

            // establish the event handler.

            if (lightSensor == null) {

                lightSensor = Windows.Devices.Sensors.LightSensor.getDefault();

                lightSensor.addEventListener("readingchanged", onDataChanged);

            }

        }

    }

 

    WinJS.Application.start();

})();

Detecting geolocation

var loc = null;

 

function getloc() {

    if (loc == null) {

        loc = new Windows.Devices.Geolocation.Geolocator();

    }

    if (loc != null) {

        loc.getGeopositionAsync().then(getPositionHandler, errorHandler);

    }

}

 

function getPositionHandler(pos) {

    document.getElementById('latitude').innerHTML = pos.coordinate.latitude;

    document.getElementById('longitude').innerHTML = pos.coordinate.longitude;

    document.getElementById('accuracy').innerHTML = pos.coordinate.accuracy;

    document.getElementById('geolocatorStatus').innerHTML =

            getStatusString(loc.locationStatus);

}

 

function errorHandler(e) {       

    document.getElementById('errormsg').innerHTML = e.message;

    // Display an appropriate error message based on the location status.

    document.getElementById('geolocatorStatus').innerHTML =

        getStatusString(loc.locationStatus);   

}

 

function getStatusString(locStatus) {

    switch (locStatus) {

        case Windows.Devices.Geolocation.PositionStatus.ready:

            // Location data is available

            return "Location is available.";       

            break;

        case Windows.Devices.Geolocation.PositionStatus.initializing:

            // This status indicates that a GPS is still acquiring a fix

            return "A GPS device is still initializing.";

            break;

        case Windows.Devices.Geolocation.PositionStatus.noData:

            // No location data is currently available

            return "Data from location services is currently unavailable.";      

            break;

        case Windows.Devices.Geolocation.PositionStatus.disabled:

            // The app doesn't have permission to access location,

            // either because location has been turned off.

            return "Your location is currently turned off. " +

                "Change your settings through the Settings charm " +

                " to turn it back on.";

            break;

        case Windows.Devices.Geolocation.PositionStatus.notInitialized:

            // This status indicates that the app has not yet requested

            // location data by calling GetGeolocationAsync() or

            // registering an event handler for the positionChanged event.

            return "Location status is not initialized because " +

                "the app has not requested location data.";

            break;

        case Windows.Devices.Geolocation.PositionStatus.notAvailable:

            // Location is not available on this version of Windows

            return "You do not have the required location services " +

                "present on your system.";

            break;

        default:

            break;

    }

}

Make sure you've enabled access to location by opening package.appxmanifest in Solution Explorer and checking Location in the Capabilities tab.

If an administrator has disabled location services, your app won't be able to access the user's location. In the desktop Control Panel, open Change Location Settings and check if Turn on the Windows Location platform is checked.

Detecting location using HTML5 (W3C Geolocation API)

    var nav = null; 

    function requestPosition() {

        if (nav == null) {

            nav = window.navigator;

        }

 

        var geoloc = nav.geolocation;

        if (geoloc != null) {

            geoloc.getCurrentPosition(successCallback, errorCallback);

        } 

    }

 

    function successCallback(position) {

        document.getElementById("latitude").innerHTML =

            position.coords.latitude;

        document.getElementById("longitude").innerHTML =

            position.coords.longitude;     

    }

 

    function errorCallback(error) {

        var strMessage = "";

 

        // Check for known errors

        switch (error.code) {

            case error.PERMISSION_DENIED:

                strMessage = "Access to your location is turned off. "  +

                    "Change your settings to turn it back on.";

                break;

            case error.POSITION_UNAVAILABLE:

                strMessage = "Data from location services is " +

                    "currently unavailable.";

                break;

            case error.TIMEOUT:

                strMessage = "Location could not be determined " +

                    "within a specified timeout period.";

                break;

            default:

                break;

        }

 

        document.getElementById("status").innerHTML = strMessage;

    }

Respond to location updates

        var loc = null; 

        function trackloc() {

            if (loc == null) {

                loc = new Windows.Devices.Geolocation.Geolocator();

            }

            if (loc != null) {

                loc.addEventListener("positionchanged", onPositionChanged);

                loc.addEventListener("statuschanged", onStatusChanged);

                // display initial status, in case location is turned off.

                document.getElementById('geolocatorStatus').innerHTML =

                    getStatusString(loc.locationStatus);

            }

        }

 

        function stoptracking() {

            if (loc != null) {

                loc.removeEventListener("positionchanged", onPositionChanged);

            }

        }

 

        function onPositionChanged(args) {

            var pos = args.position;

            document.getElementById('latitude').innerHTML =

                pos.coordinate.latitude;

            document.getElementById('longitude').innerHTML =

                pos.coordinate.longitude;

            document.getElementById('accuracy').innerHTML =

                pos.coordinate.accuracy;

            document.getElementById('geolocatorStatus').innerHTML =

                    getStatusString(loc.locationStatus);

        }

 

        // Handle change in status to display an appropriate message.       

        function onStatusChanged(args) {

            var newStatus = args.status;

            document.getElementById('geolocatorStatus').innerHTML =

                getStatusString(newStatus);

        }

You should test for location updates by using a Wi-Fi enabled computer, because the Windows Location Provider uses Wi-Fi triangulation to resolve the location. If you use a computer that doesn't have Wi-Fi enabled, location will be based on IP address, and you might not get location update events, since IP Address data is not updated frequently.

Responding to location updates using HTML5

 

    var loc = null;

    var watchId;

 

    function watchloc() {

        if (loc == null) {

            loc = window.navigator.geolocation;

        }

        if (loc != null){

            watchId = loc.watchPosition(successCallback);

        }

    }

   

    function stopwatching() {

        loc.removeEventListener(watchId);

    }

   

    function successCallback(pos) {

        document.getElementById('latitude').innerHTML = pos.coords.latitude;

        document.getElementById('longitude').innerHTML = pos.coords.longitude;

        document.getElementById('accuracy').innerHTML = pos.coords.accuracy;

    }

 

Adjust the distance between location updates

 

loc.movementThreshold = threshold;

If the user re-enables location access after disabling it, there is no notification. The status property does not change, and there is no StatusChanged event. Your app should reattempt access by creating a new Geolocator object and calling GetGeopositionAsync to get updated location data.

If location is not essential for your app, display the message as inline text. Social networking or gaming apps fall into this category.

If location is essential for your app's functionality, display the message as a flyout or a dialog. Mapping and navigation apps fall into this category.

Setting the MovementThreshold property doesn't change the frequency at which the source of the location data (such as the Windows Location Provider or an attached GPS device) calculates location.

If your application doesn't require the most accurate possible stream of data, or requires updates infrequently, set the ReportInterval property to indicate the minimum frequency of location updates that your app needs. so that the location source can conserve power by calculating location only when needed.

Apps that do require real-time data should set ReportInterval to 0, to indicate that no minimum interval is specified, and the app may receive events at the frequency that the most accurate location source sends events.

Devices that provide location data may track the report interval requested by different apps, and provide data reports at the smallest requested interval, so that the app with the greatest need for accuracy receives the data it needs. So it's possible that the location provider will generate updates at a higher frequency than your app requested, if another app has requested more frequent updates. It isn't guaranteed that the location source will honor the request for the given report interval. Not all location provider devices track the report interval, but you should still provide it for those that do.

For applications that require GPS support, you can use methods in the Windows.Devices.Enumeration namespace to find whether GPS devices are available on the computer.

// An AQS selector string is to query for instances

// of the specified device interface class

// The GUID for GPS devices is {ED4CA589-327A-4FF9-A560-91DA4B48275E}

 

// InterfaceEnabled means the device is installed

// It does not mean that the device is ready to provide location data.

var deviceInterfaceClass = {ED4CA589-327A-4FF9-A560-91DA4B48275E}; 

var selector = "System.Devices.InterfaceClassGuid:=" + deviceInterfaceClass

    + " AND System.Devices.InterfaceEnabled:=true"; 

 

var DevInfo = Windows.Devices.Enumeration.DeviceInformation;

DevInfo.findAllAsync(selector, null).then(successCallback, errorCallback);

 

// Handles successful completion of the findAllAsync method.

function successCallback(devinfoCollection) {

    var numDevicesFound = devinfoCollection.length;

    if (numDevicesFound > 0) {

        // A GPS device was found.

    }

 }

The first time an app requests location data, there might be a short delay of one to two seconds while the location provider starts up. Your app's user interface should consider this. For instance, you may want to avoid blocking other tasks on the completion of the call to getGeopostionAsync.

If a Metro style app for Windows Developer Preview doesn't have focus, it won't receive location update events while it's suspended in the background. If your application tracks location updates by logging them, be aware of this. When the app regains focus, it will receive only new events.

Removable storage devices

Windows Developer Preview provides support for accessing content on media and storage devices that use Windows Portable Devices (WPD), including Media Transport Protocol (MTP) devices and Mass Storage Class (MSC) devices. The Windows.Devices.PortableDevices namespace provides the StorageDevice class for enumerating removable storage devices and accessing them as a StorageFolder.

Double click on package.appxmanifest in solution explorer. Select the Capabilities tab. Check Removable Storage in the Capabilities list.

// Use the Removable Devices KnownFolder to get a snapshot of the currently

// connected devices as StorageFolders.

 function listStorages() {

        document.getElementById("output").innerHTML = "";

        Windows.Storage.KnownFolders.removableDevices.getFoldersAsync().

        then(

            function (removableStorages) {

            // Display each storage device.

            var numRemovableStorages = removableStorages.length;

            if (numRemovableStorages > 0) {

                removableStorages.forEach(function (removableStorage, i) {

                    document.getElementById("output").innerHTML +=

                             removableStorage.name + "<br/>";

                });

            } else {

                document.getElementById("output").innerHTML =

                        "No storages found. Attach a removable storage " +

                        "such as a camera or USB drive.)";

            }

        },

            function (e) {

            document.getElementById("output").innerHTML =

                    "Failed to find all storage devices. Error: " +

                     e.message;

        });

}

 

Sending a file to a storage device

 

    Enum = Windows.Devices.Enumeration;

 

    // Enumerate removable storage devices.

    // The success callback selects the removable storage to use.

    function pickStorage(){

        Enum.DeviceInformation.findAllAsync(

            Windows.Devices.Portable.StorageDevice.getDeviceSelector(),

            null).then(

                successCallback,

                errorCallback);

    }

 

    // Handler that's called when removable storages are found.

    // The storageDevices parameter is of type

    // Windows.Devices.Enumeration.DeviceInformationCollection

    function successCallback(storageDevices){

        var removableStorage;

        if (storageDevices.length) {

            try {

                // Create an IStorageItem from the first removable storage device

                removableStorage = Windows.Devices.Portable.StorageDevice.fromId(

                    storageDevices.getAt(0).id); 

            } catch (e) {

                document.getElementById("output").innerHTML =

                    "Error creating storage item: " + e.message;

            }

            if (removableStorage != null) {

                PickAndSend(removableStorage, removableStorage.name);

            }

        }

    }                               

 

    function errorCallback(e) {

        document.getElementById("output").innerHTML = "Error: " + e.message;

    }

 

    // Pick a file, and send it to the removable storage device

    // removableStorage: The IStorageItem representing the storage device

    // removableStorageName: The name of the storage device

    function PickAndSend(removableStorage, removableStorageName) {

        // Create the picker for selecting an image file

        var picker = new Windows.Storage.Pickers.FileOpenPicker();

        // Set the collection of types that the file open picker displays.

        picker.fileTypeFilter.replaceAll([".jpg", ".png", ".gif"]);

        // Set the initial location where the file picker looks

        picker.suggestedStartLocation =

            Windows.Storage.Pickers.PickerLocationId.picturesLibrary;

        picker.pickSingleFileAsync().then(

        function (sourceFile) {

            // sourceFile is null if the user

        // clicked cancel from the picker

            if (sourceFile == null) {

                document.getElementById("output").innerHTML =

                "No file was picked.";

            }

            else {

                // Copy the file to the storage device

                // using StorageFile.copyAsync

                sourceFile.copyAsync(removableStorage).then(

                    function (newFile) {

                        document.getElementById("output").innerHTML =

                        "Created file: " + newFile.name + " on " +

                        removableStorageName + "<br/>";

                },

                    function (e) {

                    // A failure here could mean that the removable storage

                    // does not allow file creation on its root.

                    // We try to find a folder to copy the file to.

                    copyToFirstAvailableFolder(

                            removableStorage, sourceFile);

                });   // end sourceFile.copyAsync

            }             // end if (sourceFile)

        });               // end pickSingleFileAsync.then

    }

 

function copyToFirstAvailableFolder(removableStorage, sourceFile) {

    // Construct a recursive folder search

    var queryOptions = new Windows.Storage.Search.QueryOptions(

            Windows.Storage.Search.CommonFolderQuery.defaultQuery);

    queryOptions.folderDepth = Windows.Storage.Search.FolderDepth.deep;

    var deepFolderQuery =

            removableStorage.createFolderQueryWithOptions(queryOptions);

 

    deepFolderQuery.getFoldersAsync().then(

        function (folders) {

            copyToFolder(folders, 0, sourceFile);

        },

        function (e) {

            document.getElementById("output").innerHTML =

                "Failed to find any folders to copy to: " + e.message;

        });

    }

 

function copyToFolder(folderList, currentIndex, sourceFile) {

    if (currentIndex === folderList.length) {

        document.getElementById("output").innerHTML =

            "Failed to find a writable folder to copy to";

        return;

    }

 

    var destinationFolder = folderList[currentIndex];

    document.getElementById("output").innerHTML =

            "Trying folder: " + destinationFolder.name + "...";

    performCopyToDevice(

            destinationFolder,

            sourceFile,

            function (newFile) {

        document.getElementById("output").innerHTML += "Created file: " +

        newFile.name + " in folder: " + destinationFolder.name + "<br/>";

    },

        function (e) {

        copyToFolder(folderList, currentIndex + 1, sourceFile);

    });

}

 

    function performCopyToDevice(

        destinationFolder, sourceFile, completedHandler, errorHandler) {

        if (itemInFileSystemStorage(destinationFolder)) {

            sourceFile.copyAsync(destinationFolder).then(

                completedHandler, errorHandler);

        } else {

            // Use createFile/stream copy for non-file-system-based storages

            var destOutputStream = null;

            var newFile = null;

            return destinationFolder.createFileAsync(sourceFile.fileName).

                then(

                    function (file) {

                newFile = file;

                return newFile.openAsync(

                    Windows.Storage.FileAccessMode.readWrite);

            },

                    errorHandler).

                then(

                    function (destStream) {

                destOutputStream = destStream.getOutputStreamAt(0);

                return sourceFile.openForReadAsync();

            },

                    errorHandler).

                then(

                    function (sourceInputStream) {

                Windows.Storage.Streams.RandomAccessStream.copy(

                    sourceInputStream, destOutputStream);

                return destOutputStream.flushAsync();

            },

                    errorHandler).

                then(

                    function () {

                completedHandler(newFile);

            },

                    errorHandler);

        }

    }

 

    function itemInFileSystemStorage(item) {

        // Items in file-system-backed storages have a non-zero-length path

        return (item.path.length > 0);

    }

Get an image file from a storage device

Double click on package.appxmanifest in solution explorer. Select the Capabilities tab. Check Removable Storage in the Capabilities list.

Declare file types

  • In the Declarations tab, choose File Type Declarations from Available Declarations.
  • Under Properties, set the Name property to image.
  • In the Supported File Types box, click Add New, to add .gif as a supported file type by entering .gif in the FileType field.
  • Add two more supported file types for .jpg and .png by clicking Add New and filling in the FileType.

    Enum = Windows.Devices.Enumeration;

 

    // Enumerate removable storage devices.

    // The success callback selects the removable storage to use.

    function pickStorageToGetImageFrom() {

        Enum.DeviceInformation.findAllAsync(

        Windows.Devices.Portable.StorageDevice.getDeviceSelector(),

        null).then(

            successCallback,

            errorCallback);

    }

 

    // Handler that's called when removable storages are found.

    // storageDevices: A collection of type

    // Windows.Devices.Enumeration.DeviceInformationCollection.

    // This example just takes the first storage found in the list.

    function successCallback(storageDevices) {

        var removableStorage = null;

        if (storageDevices.length) {

            try {

                // Create an IStorageItem from the first removable storage device

                removableStorage = Windows.Devices.Portable.StorageDevice.fromId(

                storageDevices.getAt(0).id);

                // document.getElementById("output").innerHTML = storageDevices.getAt(0).name;

            } catch (e) {

                document.getElementById("output").innerHTML =

                "Error: " + e.message;

            }

            if (removableStorage != null) {

                getImageFiles(removableStorage);

            }

        } else {

            document.getElementById("output").innerHTML =

                "No removable storage devices were found.";

        }

    }

 

    // Error callback that's called if unable to enumerate all

    // removable storages

    function errorCallback(e) {

        document.getElementById("output").innerHTML =

            "Error enumerating storages: " + e.message;

    }

 

    // Find the images on the removable storage and display the first one

    // in the <img> element.

    // storageItem: the item representing the removable storage

    function getImageFiles(removableStorage)

    {

        // Construct the query for image files

        var queryOptions = new Windows.Storage.Search.QueryOptions(

                    Windows.Storage.Search.CommonFileQuery.orderByName,

                    [".jpg", ".png", ".gif"]);

        var imageFileQuery = removableStorage.createFileQueryWithOptions(

            queryOptions);

 

        // Run the query for image files

        imageFileQuery.getFilesAsync().

                    then(

                        function (items) {

            displayFirstImage(items);

        },

                        function (e) {

            document.getElementById("output").innerHTML =

                "Error when looking for images on the removable storage: "

                + e.message;

        });

    } 

 

    function displayFirstImage(items) {

        var found = false;

        for (var i = 0, l = items.length; i < l && !found; i++) {

            if (items[i].size > 0) { // display the first non-empty file

                displayImage(items[i]);

                found = true;

            }

        }

 

        if (!found) {

            // No files found matching our criteria

            document.getElementById("output").innerHTML =

                "No image files found on the removable storage.";

        }

    }

Get an image from a camera using AutoPlay

How to access removable storage when the storage device is plugged in (a camera that has storage, or memory for a camera), by handling AutoPlay events.

Declare the Removable Storage capability + Declare the file types

Declare the AutoPlay Content contract

  1. In the Declarations tab, choose AutoPlay Content from Available Declarations and click Add.
  2. Under Properties, set the ContentEvent property to CameraMemoryOnArrival, set the Verb property to storageDevice, and set the ActionDisplayName property to the friendly name to display for your app when it's launched on autoplay activation.

Declare the AutoPlay Device contract

  1. In the Declarations tab, choose AutoPlay Device from Available Declarations and click Add.
  2. Under Properties, set the DeviceEvent property to WPD\ImageSource, set the Verb property to wpdImage, and set the ActionDisplayName property to the friendly name to display for your app when it's launched on autoplay activation.

document.addEventListener("DOMContentLoaded", initialize, false);

 

    // Add a handler for the activated event so it can

    // do something when activated via AutoPlay.

    Windows.UI.WebUI.WebUIApplication.addEventListener(

        "activated", activatedHandler);

 

function activatedHandler(eventArgs) {

    if (eventArgs.kind ===

            Windows.ApplicationModel.Activation.ActivationKind.file) {

        // clear any device id so we always use

        //  the latest connected device

        g_autoPlayDeviceId = null;

        g_autoPlayDrive = eventArgs.files[0];

        document.getElementById("btn").click();

        getFirstImageOnAutoPlayStorage();

    } else if (eventArgs.kind ===

            Windows.ApplicationModel.Activation.ActivationKind.device) {

        // clear any saved drive so we always use

        // the latest connected device

        g_autoPlayDrive = null;

        g_autoPlayDeviceId = eventArgs.deviceInformationId;

        document.getElementById("btn").click();

        getFirstImageOnAutoPlayStorage();

    } else {

        document.getElementById("status").innerHTML =

            "Not activated using Autoplay";

        document.getElementById("btn").disabled = true;

    }

}

 

    function initialize() {

        document.getElementById("btn").addEventListener(

           "click", getFirstImageOnAutoPlayStorage, false);

    }

 

function getFirstImageOnAutoPlayStorage() {

 

    document.getElementById("output").innerHTML = "";

    if (g_autoPlayDrive) {

 

        document.getElementById("status").innerHTML =

            "Activated using Drive Autoplay";

 

        // Drive Autoplay returns a Windows.Storage.StorageFolder

        // representing the storage drive

        // Construct the query for image files on the device

        var queryOptions = new Windows.Storage.Search.QueryOptions(

            Windows.Storage.Search.CommonFileQuery.orderByName,

            [".jpg", ".png", ".gif"]);

        var imageFileQuery =

            g_autoPlayDrive.createFileQueryWithOptions(queryOptions);

         // Run the query for image files

        imageFileQuery.getFilesAsync().

            then(

                function (items) {

                displayFirstImage(items);

            },

                function (e) {

            document.getElementById("output").innerHTML =

                "Error when looking for images in '" +

                g_autoPlayDrive.name + "': " + e.message;

            });

 

        } else if (g_autoPlayDeviceId) {

 

        document.getElementById("output").innerHTML =

            "Activated using Device Autoplay";

 

        // Device Autoplay returns a device ID. We take an extra step to

        // convert that identifier into a Windows.Storage.StorageFolder.

        var autoplayStorageDevice;

        try {

            autoplayStorageDevice =

            Windows.Devices.Portable.StorageDevice.fromId(g_autoPlayDeviceId);

        } catch (e) {

            document.getElementById("output").innerHTML =

            e.message;

        }

         // Construct the query for image files on the device

        var queryOptions = new Windows.Storage.Search.QueryOptions(

            Windows.Storage.Search.CommonFileQuery.orderByName,

            [".jpg", ".png", ".gif"]);

        var imageFileQuery =

            autoplayStorageDevice.createFileQueryWithOptions(queryOptions);

        imageFileQuery.getFilesAsync().

            then(

                function (items) {

            displayFirstImage(items);

        },

                function (e) {

            document.getElementById("output").innerHTML =

                    "Error when looking for images in '" +

                    autoplayStorageDevice.name + "': " + e.message;

        });

    } else {

        document.getElementById("output").innerHTML =

            "Not activated via AutoPlay.";

    }

} 

    

function displayFirstImage(items) {

    var found = false;

    for (var i = 0, l = items.length; i < l && !found; i++) {

        if (items[i].size > 0) { // display the first non-empty file

            displayImage(items[i]);

            found = true;

        }

    }

 

    if (!found) {

        // No files found matching our criteria

        document.getElementById("output").innerHTML =

            "No image files found on the removable storage";

    }

}

c.d.n

Brak komentarzy: