2013-08-24 84 views
1

我想在Windows Phone 8上使用C#实现锁屏背景应用程序。这个想法是,当用户点击一个按钮时,启动PhotoChooserTask。当他从媒体库中选取一张照片时,它将被复制到独立存储器中,然后设置为锁定屏幕背景。Windows Phone 8. C#。从孤立的存储锁屏背景。异常

的问题是,Windows Phone的要求每个新的锁屏画面的唯一名称,因此该解决方案必须是以下几点:

  1. 用户选择从库中的照片 2.1如果当前锁屏图片EndsWith(“_ A.jpg”)将选中的照片复制到隔离存储为photobackground_B.jpg并设置为锁屏背景 2.2。否则,如果当前的图片锁屏不满足的endsWith(“_ A.JPG”)条件,则所选择的照片复制到独立存储为photobackground_A.jpg和被设定为锁屏背景。

因此,A/B开关逻辑被实施为使得每个新的锁屏背景具有唯一的名称。

但是,我的代码不work.In特别是以下行抛出异常:

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

出了什么问题?

P.S.我对编程完全陌生,所以我也会很欣赏解释和适当的代码示例。谢谢!

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)); 
        } 
       } 


      } 
     } 
    } 
} 

回答

1

这里有一些建议供您参考:

  1. 你可能会过于复杂命名的文件的问题。首先,我想说,如果应用程序是当前锁屏经理,删除现有的锁屏图像,然后创建一个使用Guid.NewGuid新形象的名字。 Guides保证在生成时是唯一的,所以你将永远不会碰到这里的命名冲突。

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

  3. 你最终要提供的URI可能是最容易给OS的系统相对文件路径生成(即C:\),这就是从StorageFile.Path Property方便。

将您的事件处理函数修改为以下代码的行,并查看您的票价。 你将需要添加一个using指令导入System.IO命名空间使用OpenStreamForWriteAsync Extension

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)); 
    } 
} 
+0

谢谢!就将图像保存到独立存储而言,新的API似乎很完美。但是,'Windows.Phone.System.UserProfile.LockScreen.SetImageUri(new Uri(newImageFile.Path,UriKind.Absolute));'抛出异常( –

1

感谢lthibodeaux为真棒想法)除了SetImageUri行一切工作。

这一个似乎做的业务有:Windows.Phone.System.UserProfile.LockScreen.SetImageUri(新的URI( “MS-应用程序数据:///本地/” + nextImageName,UriKind.Absolute))

再次感谢!