locked
FileSavePicker and share contract

    Question

  • Hello guys,

    quick question: can one use the FileSavePicker from within a method that handles the click event in an html page loaded when an app is activated through the share contract?


    Luis Abreu

    Tuesday, May 08, 2012 4:12 PM

Answers

  • Ah OK,

    It is not documented yet, but you cannot show the picker from the pane.  I am getting the right people to document this.

    -Jeff


    Jeff Sanders (MSFT)

    Monday, May 14, 2012 8:21 PM
    Moderator

All replies

  • I never tried!  Problems?

    -Jeff


    Jeff Sanders (MSFT)

    Wednesday, May 09, 2012 3:08 PM
    Moderator
  • Well, I'm finally able to show the dialog but when I try to change the current folder (going to the top menu, which allows me to navigate to a different drive, or trying to open an existing folder), the save  window gets closed and I'm brought back to the app which is sharing info.

    Saving in the default folder which is shown does end up saving the file there.

    Here's the code I'm using to save the file:

    function onShareSubmit() {      
            document.querySelector(".submitbutton").disabled = true;
            var picker = new Windows.Storage.Pickers.FileSavePicker();
            picker.fileTypeChoices.insert("JPEG files", [".jpg"]);
            picker.fileTypeChoices.insert("PNG files", [".png"]);
            picker.suggestedFileName = share.data.properties.title;
            picker.pickSaveFileAsync()
            .then(function (file) {
                share.data.getBitmapAsync()
                .done(function (bmp) {
                    bmp.openReadAsync()
                        .done(function (stream) {
                                file.openAsync(Windows.Storage.FileAccessMode.readWrite)
                                    .done(function (fileStream) {
                                        Windows.Storage.Streams.RandomAccessStream.copyAndCloseAsync(stream, fileStream)
                                            .done(function () {
                                                share.reportCompleted();
                                            });
                                    });
                            });
                        });
                },
                function (err) {
                    var t = "";
                });

    }

    Am I missing anything?


    Luis Abreu

    Wednesday, May 09, 2012 9:50 PM
  • Hi Luis,

    I took the share target sample.  If I even add this code to the button press handler, the pane disappears (without pressing the button):

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

    Can you send me a repro?

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, May 10, 2012 7:32 PM
    Moderator
  • Hello again Jeff.

    That was what was happening to me when I first tried it. debugging it would return an error saying that it had lost the window handle or something like that. WHen you replied, I tested the code again and it started showing the dialog, but this time, it won't let me navigate into another folder.

    TO where do you want me to send the sample? I can also paste the code here (it's really simple...)


    Luis Abreu

    Thursday, May 10, 2012 9:02 PM
  • I think the issue is related to the context of the SharePane.  Let me do some further digging.  If you had the same trouble when adding the code, I do not suspect your code will get me much further.

    Thanks!


    Jeff Sanders (MSFT)

    Friday, May 11, 2012 12:47 PM
    Moderator
  • True. but at least, you wouldn't need to write it :)

    Luis Abreu

    Friday, May 11, 2012 2:02 PM
  • :-)  Well thanks my friend!  Post away!

    Jeff Sanders (MSFT)

    Friday, May 11, 2012 2:11 PM
    Moderator
  • After adding the sharing contract, I've used the following HTML:

               

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="ms-design-extensionType" content="ShareTarget">
        <title>Share Target Contract</title>

        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.0.6/css/ui-light.css" rel="stylesheet">
        <script src="//Microsoft.WinJS.0.6/js/base.js"></script>
        <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>

        <link href="/css/default.css" rel="stylesheet">
        <link href="rececao.css" rel="stylesheet">
        <script src="rececao.js"></script>
    </head>
    <body>
        <!-- The content that will be loaded and displayed. -->
        <section aria-label="Main content" role="main">
            <header>
                <img class="shared-thumbnail" src="#" alt="share metadata image" />
                <div class="shared-metadata">
                    <h2 class="shared-title win-type-ellipsis"></h2>
                    <h4 class="shared-description"></h4>
                </div>
            </header>

            <div class="sharecontrols">
                <input class="submitbutton" type="submit" value="Gravar">
            </div>

        </section>
    </body>
    </html>

    and here's the JS code:

    // For an introduction to the Share Contract template, see the following documentation:
    // http://go.microsoft.com/fwlink/?LinkId=232513
    //
    // TODO: Edit the manifest to enable use as a share target.  The package 
    // manifest could not be automatically updated.  Open the package manifest file
    // and ensure that support for activation of sharing is enabled.

    (function () {
        "use strict";

        var share;

        // This function responds to all application activations.
        function activated(eventObject) {
            if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
                document.querySelector(".submitbutton").onclick = onShareSubmit;
                share = eventObject.detail.shareOperation;

                document.querySelector(".shared-title").textContent = share.data.properties.title;

                var thumbnail = share.data.properties.thumbnail;
                if (thumbnail) {
                    // If the share data includes a thumbnail, display it.               
                    thumbnail.openReadAsync().then(function (stream) {
                        var blob = MSApp.createBlobFromRandomAccessStream(stream.contentType, stream);
                        document.querySelector(".shared-thumbnail").src = URL.createObjectURL(blob, false);
                    });
                } else {
                    // If no thumbnail is present, expand the description  and
                    // title elements to fill the unused space.
                    document.querySelector("section[role=main] header").style.setProperty("-ms-grid-columns", "0px 0px 1fr");
                    document.querySelector(".shared-thumbnail").style.visibility = "hidden";
                }
               
            }
        }

        function onShareSubmit() {      
            document.querySelector(".submitbutton").disabled = true;
            var picker = new Windows.Storage.Pickers.FileSavePicker();
            picker.fileTypeChoices.insert("JPEG files", [".jpg"]);
            picker.fileTypeChoices.insert("PNG files", [".png"]);
            picker.suggestedFileName = share.data.properties.title;
            picker.pickSaveFileAsync()
            .then(function (file) {
                share.data.getBitmapAsync()
                .done(function (bmp) {
                    bmp.openReadAsync()
                        .done(function (stream) {
                                file.openAsync(Windows.Storage.FileAccessMode.readWrite)
                                    .done(function (fileStream) {
                                        Windows.Storage.Streams.RandomAccessStream.copyAndCloseAsync(stream, fileStream)
                                            .done(function () {
                                                share.reportCompleted();
                                            });
                                    });
                            });
                        });
                },
                function (err) {
                    var t = "";
                });
           
        }
        WinJS.Application.start();
        WinJS.Application.onactivated = activated;
    })();


    Luis Abreu

    Friday, May 11, 2012 2:37 PM
  • Hey Luis,

    So I get the same issue.  Just referencing the picker in the code prevents the UI from coming up.  I am engaging the product team with this repro.

    This made me wonder however, rather than a share target... If the intent is to use the file picker, you really ought to be creating a filepicker extension.  That way an app can choose to save a file and save it right through your application.

    Have you seen the way the SkyDrive application does this for you?

    -Jeff


    Jeff Sanders (MSFT)

    Monday, May 14, 2012 7:43 PM
    Moderator
  • Hello again Jeff.

    Well, this is only demo code. In fact, I'm currently documenting everything I can from WIndows 8 Metro (at least, trying hard to do that) and my examples are rather simplistic. In this case, I only intended to illustrate the sharing protocol and I decided to allow the received app to save the image. Not productive, I know, but since this is demo code, I really want it to be simple (btw, I've ended saving the file in the pictures folder )

    PS: I've already covered the file picker extension  and I'm currently stuck in the multimedia section :)


    Luis Abreu

    Monday, May 14, 2012 8:20 PM
  • Ah OK,

    It is not documented yet, but you cannot show the picker from the pane.  I am getting the right people to document this.

    -Jeff


    Jeff Sanders (MSFT)

    Monday, May 14, 2012 8:21 PM
    Moderator
  • Thanks Jeff!

    Luis Abreu

    Monday, May 14, 2012 8:36 PM
  • Hi Spanders,

    I have implemented the FileSavePicker Contract in my app,so when user selects an attachment from mail app and want to save to my app ,then OnTargetFileRequested(FileSavePickerUI^ sender, TargetFileRequestedEventArgs^ e) method gets triggered....

    OnTargetFileRequested(FileSavePickerUI^ sender, TargetFileRequestedEventArgs^ e) 
    {
        auto request = e->Request;
        auto deferral = request->GetDeferral();

        create_task(ApplicationData::Current->LocalFolder->CreateFileAsync(sender->FileName, CreationCollisionOption::GenerateUniqueName)).then([request, deferral](StorageFile^ file)
        {
            // Assign the resulting file to the targetFile property indicates success
            request->TargetFile = file;

            // Complete the deferral to let the Picker know the request is finished.
            deferral->Complete();

    return file;

       }.then([=](StorageFile^ file)

    {

    //here I wrote the code for upload

    }

    now whatever file i was created that i need to upload to my metro app....but i am facing an issue with deferral->complete...whether deferral->complete()  need to written after uploading the file to my app or above the deferral->complete statement is correct.??...

    but when i use deferral->complete after uploading the file always 0 bytes of file is getting uploaded...

    if i use deferral->complete in createFileAsync() as shown in above code then the file is not getting uploaded........please help me....

    Is there any callback or event to know that deferral->complete() has completed successfully,if so I can use that and upload file in that callback method or event..

    Monday, October 01, 2012 1:34 PM