Search code examples
c#windows-runtimewindows-phone-8.1sharing

Sharing screenshot on Windows Phone 8.1 WinRT does not attach image on sharing apps


I want to share the screenshot of my app. The screenshot is saved into the phone's picture library then it's shared as StorageFile

The problem is, the image is not attached to the sharing apps. I've verified that the screenshot was saved successfully in the phone's picture library.

Here's my code. What am I missing?

    private async void askFacebook()
    {
        // Render some UI to a RenderTargetBitmap
        var renderTargetBitmap = new RenderTargetBitmap();
        await renderTargetBitmap.RenderAsync(this.gridRoot, (int)this.gridRoot.ActualWidth, (int)this.gridRoot.ActualHeight);

        // Get the pixel buffer and copy it into a WriteableBitmap
        var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
        var width = renderTargetBitmap.PixelWidth;
        var height = renderTargetBitmap.PixelHeight;
        var wbmp = await new WriteableBitmap(1, 1).FromPixelBuffer(pixelBuffer, width, height);

        imageToShare = await saveWriteableBitmapAsJpeg(wbmp, string.Format("{0}.jpg", getAppTitle()));
        DataTransferManager.ShowShareUI();
    }

    private string getAppTitle()
    {
        // Get the assembly with Reflection:
        Assembly assembly = typeof(App).GetTypeInfo().Assembly;

        // Get the custom attribute informations:
        var titleAttribute = assembly.CustomAttributes.Where(ca => ca.AttributeType == typeof(AssemblyTitleAttribute)).FirstOrDefault();

        // Now get the string value contained in the constructor:
        return titleAttribute.ConstructorArguments[0].Value.ToString();
    }

    private async Task<StorageFile> saveWriteableBitmapAsJpeg(WriteableBitmap bmp, string fileName)
    {
        // Create file in Pictures library and write jpeg to it
        var outputFile = await KnownFolders.PicturesLibrary.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
        using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            await encodeWriteableBitmap(bmp, writeStream, BitmapEncoder.JpegEncoderId);
        }
        return outputFile;
    }

    private async Task encodeWriteableBitmap(WriteableBitmap bmp, IRandomAccessStream writeStream, Guid encoderId)
    {
        // Copy buffer to pixels
        byte[] pixels;
        using (var stream = bmp.PixelBuffer.AsStream())
        {
            pixels = new byte[(uint)stream.Length];
            await stream.ReadAsync(pixels, 0, pixels.Length);
        }

        // Encode pixels into stream
        var encoder = await BitmapEncoder.CreateAsync(encoderId, writeStream);
        var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;

        encoder.SetPixelData(BitmapPixelFormat.Bgra8, 
            BitmapAlphaMode.Premultiplied,
           (uint)bmp.PixelWidth, 
           (uint)bmp.PixelHeight,
           logicalDpi, 
           logicalDpi, 
           pixels);

        await encoder.FlushAsync();
    }


    private void ShareImageHandler(DataTransferManager sender,  DataRequestedEventArgs e)
    {
        DataRequest request = e.Request;
        request.Data.Properties.Title = "Ask Social Media";
        request.Data.Properties.Description = "Do you know the answer to this question?";

        // Because we are making async calls in the DataRequested event handler,
        //  we need to get the deferral first.
        DataRequestDeferral deferral = request.GetDeferral();

        // Make sure we always call Complete on the deferral.
        try
        {
            request.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(imageToShare));
        }
        finally
        {
            deferral.Complete();
        }
    }

Solution

  • Apparently for Windows Phone, the image needs to be a StorageItem as the SetBitmap methods only works with Windows 8.x

    So for Windows phone, instead of

    request.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(imageToShare));
    

    I created a storage item and use SetStorageItems to share it. It works with native Windows Phone apps such as emails, OneNote but I haven't tested it for sharing on Facebook, Twitter etc.

     var imageItems = new List<IStorageItem>();
     imageItems.Add(imageToShare);
     request.Data.SetStorageItems(imageItems);