Живые плитки не загружают изображение из изолированного хранилища

В моем приложении WP7 я создаю изображение для живой плитки и сохраняю его в изолированном хранилище. Затем для моей периодической задачи доступно обновление живой плитки, и в этом отношении для периодической задачи все работает нормально.

Проблема, с которой я сталкиваюсь, заключается в том, что в моем приложении WP7 переднего плана, когда я создаю изображение живой плитки, я также обновляю живую плитку (поскольку я знаю, что что-то изменилось, так зачем ждать периодическую задачу). Но когда здесь происходит обновление живой плитки, кажется, что он не может найти вновь созданный файл и поэтому представляет живую плитку без растрового изображения.

С точки зрения соответствующего кода

Создание файла

var source = new BitmapImage(new Uri("Images/Tiles/Class Timetable with T.png", UriKind.Relative));
source.CreateOptions = BitmapCreateOptions.None;
source.ImageOpened += (sender, e) => // This is important. The image can't be rendered before it's loaded.
{
    // Create our image as a control, so it can be rendered to the WriteableBitmap.
    var newImage = new Image();
    newImage.Source = source;
    newImage.Width = 173;
    newImage.Height = 173;

    // Define the filename for our tile. Take note that a tile image *must* be saved in /Shared/ShellContent
    // or otherwise it won't display.
    var tileImage = string.Format("/Shared/ShellContent/{0}.jpg", Event.UniqueId);

    // Define the path to the isolatedstorage, so we can load our generated tile from there.
    var isoStoreTileImage = string.Format("isostore:{0}", tileImage);

и фактическое сохранение себя

// Create a stream to store our file in.
var stream = store.CreateFile(tileImage);

// Invalidate the bitmap to make it actually render.
bitmap.Invalidate();

// Save it to our stream.
bitmap.SaveJpeg(stream, 173, 173, 0, 100);

// Close the stream, and by that saving the file to the ISF.
stream.Close();

и код, который фактически извлекает изображение и обновляет живую плитку (и работает в периодической задаче, но не из самого приложения).

string imageString = "isostore:/Shared/ShellContent/" + nextEvent.UniqueId + ".jpg";
ShellTile defaultTile2 = ShellTile.ActiveTiles.First();
defaultTile2.Update(new StandardTileData
{
    Title = nextTime,
    BackgroundImage = (new Uri(imageString, UriKind.Absolute)),

});

Просто не уверен, что я делаю что-то принципиально неправильное здесь? Я рассматриваю возможность хранения сгенерированного изображения в базе данных с его объектом. И у меня есть управляемое количество файлов, задействованных здесь. Я не генерирую сотни вещей.

У меня есть обходной путь, который заключается в обновлении livetile из приложения WP7 без использования файла изображения.


person Peter    schedule 27.09.2011    source источник
comment
Вы говорите, что он не отображает BackgroundImage, но Title обновляется правильно?   -  person Claus Jørgensen    schedule 27.09.2011
comment
Да, верно, заголовок есть, а фонового изображения нет.   -  person Peter    schedule 27.09.2011


Ответы (2)


Эй, этот код выглядит знакомым ;-) Кроме того, в опубликованном вами коде нет ничего, что действительно могло бы определить проблему.

Я предполагаю, что вы вызываете NotifyComplete() в начале своей периодической задачи. Для этого я рекомендую вам использовать библиотеку параллельных задач для обхода проблемы.

Сегодня утром я написал об этом статью: Как: жить Плитка с запланированным агентом

Важно использовать Task.ContinueWith, чтобы убедиться, что NotifyComplete() является первым вызывается после завершения рендеринга фонового изображения и его сохранения в изолированном хранилище.

person Claus Jørgensen    schedule 27.09.2011
comment
Да, это хороший код - спасибо! Рассмотрю вашу статью и посмотрим, поможет ли это. - person Peter; 27.09.2011
comment
Если вам нужен быстрый способ проверить это, просто закомментируйте NotifyComplete() и посмотрите, правильно ли обновилось изображение. - person Claus Jørgensen; 27.09.2011
comment
Я изучал этот подход и начал включать код в соответствии с приведенным здесь примером. Если позволите, всего пара вопросов: во-первых, требуется ли REST только из-за примера, в котором используется твиттер? Или это присуще передаче во время потока пользовательского интерфейса. И, во-вторых, при таком подходе я все еще могу использовать функцию отладки, чтобы задача периода выполнялась более регулярно, что невероятно удобно. - person Peter; 28.09.2011
comment
1) Да, я использую RestSharp для получения данных из Twitter. Вы можете заменить его любым типом потока данных, который вам нравится. 2) Да, этому не должно ничего мешать. - person Claus Jørgensen; 28.09.2011
comment
Я изо всех сил пытаюсь адаптировать ваш пример Windcap для работы в моей ситуации. Потому что при этом вы создаете начальную задачу как часть процесса получения клиента твиттера. ExecuteTask‹List‹Tweet››(запрос)… но в моем случае я просто заполняю небольшую коллекцию из базы данных и делаю не вижу, как я могу создать начальную задачу и как она может включать мою коллекцию. Я думаю, что как только я это сделаю, я смогу обрабатывать в соответствии с вашим методом RunOnUIThread. Но этот метод полагается на задачу, которая будет создана при его первом вызове. - person Peter; 28.09.2011
comment
Я предлагаю вам потратить некоторое время на изучение того, как TPL работает в обычном C#. Вам необходимо понять, как работает асинхронный код для работы с платформой Windows Phone. - person Claus Jørgensen; 28.09.2011

Вам не нужен префикс isostore: в пути при его создании в основном приложении. Попробуйте просто создать относительный URI для файла.

person Matt Lacey    schedule 27.09.2011
comment
Когда я создаю его с префиксом isostore:, периодическая задача может найти файл, но основное приложение не может. Если я сделаю так, как вы предлагаете, сможет ли периодическая задача увидеть файл? - person Peter; 27.09.2011
comment
Префикс isostore: очень нужен. Это на самом деле причина, по которой вообще возможно создать локальную плитку. (И он взял код из одного из моих сообщений в блоге, так что я должен знать) И независимо от того, если файл не создан, он не будет работать. - person Claus Jørgensen; 27.09.2011
comment
Потому что я думаю, что это могло быть проблемой, когда я пробовал без префикса isostore:. - person Peter; 27.09.2011
comment
Итак, если я создаю файл с префиксом isostore:, почему основное приложение не может его увидеть, если это приложение только что создало файл. - person Peter; 27.09.2011
comment
У меня есть файлы, сохраненные в основном приложении и видимые как приложению, так и агенту, которые не используют префикс, но используют относительные префиксы, и все работает нормально. - person Matt Lacey; 27.09.2011
comment
Да, файлы, которые уже есть во время компиляции. Он генерирует новое изображение во время выполнения, которое затем должно сохраняться в изолированном хранилище. Таким образом, BackgroundImage для плитки должен иметь префикс isostore:. - person Claus Jørgensen; 27.09.2011
comment
В любом случае, поскольку я написал исходный код, я могу поручиться, что он вообще не связан с isostore. - person Claus Jørgensen; 27.09.2011
comment
Да, основное приложение загружено из Интернета и сохранено в изолированном хранилище. Файлы изображений должны находиться в изолированном хранилище, чтобы их можно было использовать в плитке и сохранять после перезагрузки устройства. Я позволю вам разобраться, в чем проблема. :) - person Matt Lacey; 27.09.2011