2013-08-24 80 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))

再次感謝!