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. 古いストレージ API を使用しているため、UI がロックされて応答しなくなる可能性があります。Windows Phone 8 では新しい非同期ファイル ストレージ API が提供されており、今後それらを理解するのに役立つ可能性があります。提供されているコード サンプルを参考にしてください。

  3. 最終的に提供する URI は、OS にシステム相対ファイル パス (つまり C:\) を与えることで最も簡単に生成され、StorageFile.Path プロパティから簡単にアクセスできます。

次のコードの行に沿ってイベント ハンドラーを変更し、どのように動作するかを確認します。OpenStreamForWriteAsync Extensionを使用するには、using ディレクティブを追加して System.IO 名前空間をインポートする必要があります

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 に答える