1

我正在尝试使用 C# 在 Windows Phone 8 上实现锁屏背景应用程序。这个想法是,当用户单击按钮时,会启动 PhotoChooserTask。当他从他的媒体库中挑选一张照片时,它会被复制到独立存储中,然后设置为锁屏背景。

问题是 Windows Phone 要求每个新的锁屏图片都有一个唯一的名称,因此解决方案必须如下:

  1. 用户从库中选择一张照片 2.1 如果当前锁屏图片EndsWith("_A.jpg")选择的照片被复制到隔离存储中作为photobackground_B.jpg并设置为锁屏背景 2.2。否则,如果当前锁屏图片不满足EndsWith("_A.jpg")条件,则将所选照片作为photobackground_A.jpg复制到隔离存储中,并设置为锁屏背景。

因此,实现了 A/B 切换逻辑,以便每个新的锁屏背景都有一个唯一的名称。

但是,我的代码不起作用。特别是以下行引发异常:

Windows.Phone.System.UserProfile.LockScreen.SetImageUri(new Uri("ms-appdata:///Local/photobackground_A.jpg", UriKind.Absolute));

似乎是什么问题?

PS我对编程完全陌生,所以我也非常感谢解释和适当的代码示例。谢谢!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;
using Day2Demo.Resources;
using System.Windows.Media;
using System.IO;
using System.IO.IsolatedStorage;
using Microsoft.Xna.Framework.Media;


namespace Day2Demo
{
    public partial class MainPage : PhoneApplicationPage
    {
        PhotoChooserTask photoChooserTask;
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Sample code to localize the ApplicationBar
            //BuildLocalizedApplicationBar();
        }





        private async void button1_Click(object sender, RoutedEventArgs e)
        {


            //check if current app provided the lock screen image
            if (!Windows.Phone.System.UserProfile.LockScreenManager.IsProvidedByCurrentApplication)
            {
                //current image not set by current app ask permission
                var permission = await Windows.Phone.System.UserProfile.LockScreenManager.RequestAccessAsync();

                if (permission == Windows.Phone.System.UserProfile.LockScreenRequestResult.Denied)
                {
                    //no permission granted so return without setting the lock screen image
                    return;
                }

            }
            photoChooserTask = new PhotoChooserTask();
            photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
            photoChooserTask.Show();
        }

        void photoChooserTask_Completed(object sender, PhotoResult e)
        {
            if (e.TaskResult == TaskResult.OK)
            {
                var currentImage = Windows.Phone.System.UserProfile.LockScreen.GetImageUri();
                if (currentImage.ToString().EndsWith("_A.jpg"))
                {

                    var contents = new byte[1024];
                    using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        using (var local = new IsolatedStorageFileStream("photobackground_B.jpg", FileMode.Create, store))
                        {
                            int bytes;
                            while ((bytes = e.ChosenPhoto.Read(contents, 0, contents.Length)) > 0)
                            {
                                local.Write(contents, 0, bytes);
                            }

                        }
                        Windows.Phone.System.UserProfile.LockScreen.SetImageUri(new Uri("ms-appdata:///Local/photobackground_B.jpg", UriKind.Absolute));
                    }
                }

                else
                {
                    var contents = new byte[1024];
                    using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        using (var local = new IsolatedStorageFileStream("photobackground_A.jpg", FileMode.Create, store))
                        {
                            int bytes;
                            while ((bytes = e.ChosenPhoto.Read(contents, 0, contents.Length)) > 0)
                            {
                                local.Write(contents, 0, bytes);
                            }

                        }
                        Windows.Phone.System.UserProfile.LockScreen.SetImageUri(new Uri("ms-appdata:///Local/photobackground_A.jpg", UriKind.Absolute));
                    }
                }


            }
        }
    }
}
4

2 回答 2

1

感谢 lthibodeaux 的好主意)除了 SetImageUri 线外,一切正常。

这似乎是做生意:Windows.Phone.System.UserProfile.LockScreen.SetImageUri(new Uri("ms-appdata:///Local/" + nextImageName, UriKind.Absolute))

再次感谢!

于 2013-08-28T11:07:26.590 回答
1

这里有一些建议给你:

  1. 您可能使命名文件的问题过于复杂。首先,我会说如果该应用程序是当前的锁屏管理器,请删除现有的锁屏图像,然后使用Guid.NewGuid创建一个新的图像名称。Guid 保证在生成时是唯一的,因此您永远不会在这里遇到命名冲突。

  2. 您正在使用可能会锁定您的 UI 并导致其无响应的过时存储 API。Windows Phone 8 中提供了新的异步文件存储 API,它可能有助于您将来熟悉它们。提供的代码示例将为您提供一个开始。

  3. 您最终要提供的 URI 可能最容易通过为操作系统提供系统相关文件路径(即 C:\)来生成,并且可以从StorageFile.Path 属性轻松访问。

将您的事件处理程序修改为以下代码行中的内容,看看您的表现如何。您需要添加 using 指令来导入 System.IO 命名空间以使用OpenStreamForWriteAsync 扩展

private async void photoChooserTask_Completed(object sender, PhotoResult e)
{
    if (e.TaskResult == TaskResult.OK)
    {
        // Load the image source into a writeable bitmap
        BitmapImage bi = new BitmapImage();
        bi.SetSource(e.ChosenPhoto);
        WriteableBitmap wb = new WriteableBitmap(bi);

        // Buffer the photo content in memory (90% quality; adjust parameter as needed)
        byte[] buffer = null;

        using (var ms = new System.IO.MemoryStream())
        {
            int quality = 90;
            e.ChosenPhoto.Seek(0, SeekOrigin.Begin);

            // TODO: Crop or rotate here if needed
            // Resize the photo by changing parameters to SaveJpeg() below if desired

            wb.SaveJpeg(ms, wb.PixelWidth, wb.PixelHeight, 0, quality);
            buffer = ms.ToArray();
        }

        // Save the image to isolated storage with new Win 8 APIs
        var isoFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
        var nextImageName = Guid.NewGuid() + ".jpg";
        var newImageFile = await isoFolder.CreateFileAsync(nextImageName, Windows.Storage.CreationCollisionOption.FailIfExists);
        using (var wfs = await newImageFile.OpenStreamForWriteAsync())
        {
            wfs.Write(buffer, 0, buffer.Length);
        }

        // Use the path property of the StorageFile to set the lock screen URI
        Windows.Phone.System.UserProfile.LockScreen.SetImageUri(new Uri(newImageFile.Path, UriKind.Absolute));
    }
}
于 2013-08-24T10:24:47.157 回答