Windows Phone 8.1 AppBarButton with custom BitmapIcon - windows-phone-8

I want to create a custom image for the AppbarButton.
I'm using code from
Windows Phone 8.1 AppBarButton icon with 2 rows of text
RenderTargetBitmap rtb = new RenderTargetBitmap();
await rtb.RenderAsync(TodayTextBorder);
IBuffer pixels = await rtb.GetPixelsAsync();
string filename = "TodayIcon.png";
var outputFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.ReplaceExisting);
using (var outputStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, outputStream);
var dpi = DisplayInformation.GetForCurrentView().LogicalDpi;
enc.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)rtb.PixelWidth, (uint)rtb.PixelHeight, dpi, dpi, pixels.ToArray());
await enc.FlushAsync();
}
BitmapIcon icon = new BitmapIcon();
icon.UriSource = new Uri("ms-appdata:///local/" + filename);
TodayAppbarButton.Icon = icon;
But it doesn't work. Well, it works on the Emulator and on the phone in case the app was deployed directly from Visual Studio. But when I'm publishing app and installing it from the Store I'm getting erroneous appbar button image (like this http://i.imgur.com/de73cTo.png)

Related

ZXing.Net.Mobile in Windows Phone 8.1

I am using ZXing.Net.Mobile in my windows phone 8.1 app. It is using below reference:
ZXing.Net.Mobile.Core
zxing.portable
ZXingNetMobile
My Code :
var scanner = new MobileBarcodeScanner();
MobileBarcodeScanningOptions options = new MobileBarcodeScanningOptions();
options.TryHarder = true;
options.PossibleFormats.Add(ZXing.BarcodeFormat.CODE_128);
options.PossibleFormats.Add(ZXing.BarcodeFormat.CODE_39);
var result = await scanner.Scan(options);
if (result != null)
{
MessageDialog a = new MessageDialog(result.Text);
a.Content = result.Text;
a.ShowAsync();
}
Issue:
Am getting below issue whenever scan method executes.
Use the platform specific implementations instead at ZXing.Mobile.MobileBarcodeScanner.Scan(....
Is there any real time QR code scanner available for windows phone 8.1 ?

Download Azure Blob image to memorystream in Windows Phone 8.1

The code below will copy an image file from Azure blob storage, and create a new image file locally. This local image will then be added to a List for further databinding to the XAML UI.
string accountName = "testacc";
string accountKey = "123abc";
string container = "textcontainer";
List<Mydata> items = new List<Mydata>();
BitmapImage bitmapToShow = new BitmapImage();
StorageCredentials creds = new StorageCredentials(accountName, accountKey);
CloudStorageAccount acc = new CloudStorageAccount(creds, useHttps: true);
CloudBlobClient cli = acc.CreateCloudBlobClient();
CloudBlobContainer sampleContainer = cli.GetContainerReference(container);
CloudBlockBlob blob = sampleContainer.GetBlockBlobReference("xbox.jpg");
// Here I need to copy the data stream directely to the BitmapImage instead of creating a file first
StorageFile photoFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("temp_image.jpg", CreationCollisionOption.ReplaceExisting);
await blob.DownloadToFileAsync(photoFile);
bitmapToShow = new BitmapImage(new Uri(photoFile.Path));
items.Add(new Mydata() { image = bitmapToShow });
DataBinding.ItemsSource = items;
The code below will copy an image file from Azure blob storage, and create a new image file locally. This local image will then be added to a List for further databinding to the XAML UI.
Hovewer - in order to get more efficient, I am looking for a way to avoid creating the image file locally first. I am looking for a way where the image file in the Azure blob storage are copied to a MemoryStream and then passed directely into a BitmapImage.
I have not fiugred out to code that myself, and the code snippets I have not found, do not work for Windows Phone 8.1. I am programming in C# for Windows Phone 8.1 Universal App (not Silverlight).
Can someone help me with the code needed to get that functionality?
Would this work?
Stream photoStream = await blob.DownloadToStreamAsync(photoFile)
bitmapToShow = new BitmapImage(photoStream);
Hope it helps,
Drew
I found that this Works. It might not be perfect, but it Works. Comments or corrections are welcome.
string accountName = "testacc";
string accountKey = "123abc";
string container = "textcontainer";
List<Mydata> items = new List<Mydata>();
BitmapImage bitmapToShow = new BitmapImage();
InMemoryRandomAccessStream memstream = new InMemoryRandomAccessStream();
StorageCredentials creds = new StorageCredentials(accountName, accountKey);
CloudStorageAccount acc = new CloudStorageAccount(creds, useHttps: true);
CloudBlobClient cli = acc.CreateCloudBlobClient();
CloudBlobContainer sampleContainer = cli.GetContainerReference(container);
CloudBlockBlob blob = sampleContainer.GetBlockBlobReference("xbox.jpg");
await blob.DownloadToStreamAsync(memstream.CloneStream());
bitmapToShow.SetSource(memstream);
items.Add(new Mydata() { image = bitmapToShow });
DataBinding.ItemsSource = items;

How to encode IImageProvider as a PNG image?

Assuming I have a LumiaImagingSDK rendering chain setup, with a final IImageProvider object that I want to render, how do I encode that into a PNG image?
Lumia Imaging SDK supports PNG images as input, however there isn't a "PNG Renderer" avaliable in the SDK.
Luckily if you are developing for Windows 8.1 (StoreApplication / universal application / Windows phone 8.1 project) there is a Windows encoder (Windows.Graphics.Imaging.BitmapEncoder) you can use.
Assuming the IImageProvider you want to render is called "source" this is a code snippet you can use to encode the resulting image as PNG:
using Lumia.Imaging;
using Windows.Graphics.Imaging;
using System.IO;
...
using (var renderer = new BitmapRenderer(source, ColorMode.Bgra8888))
{
var bitmap = await renderer.RenderAsync();
byte[] pixelBuffer = bitmap.Buffers[0].Buffer.ToArray();
using (var stream = new InMemoryRandomAccessStream())
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream).AsTask().ConfigureAwait(false);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)bitmap.Dimensions.Width, (uint)bitmap.Dimensions.Height, 96, 96, pixelBuffer);
await encoder.FlushAsync().AsTask().ConfigureAwait(false);
//If InMemoryRandomAccessStream (IRandomAccessStream) works for you, end here.
//If you need an IBuffer, here is how you get one:
using (var memoryStream = new MemoryStream())
{
memoryStream.Capacity = (int)stream.Size;
var ibuffer = memoryStream.GetWindowsRuntimeBuffer();
await stream.ReadAsync(ibuffer, (uint)stream.Size, InputStreamOptions.None).AsTask().ConfigureAwait(false);
}
}
}
This will give you bytes in memory as either InMemoryRandomAccessStream (IRandomAccessStream) or an IBuffer depending on what you need. You can then save the buffer to disk or pass it to other parts of your application.

How can I play mp3 files stored in my Windows Phone 8.1 solution?

I have a number of mp3 files stored in my solution at the location
/Resources/mp3Files/
In Windows Phone 8 I was able to play these with the following:
var name = track.Item1;
var uri = new Uri("/Resources/mp3Files/sound.mp3", UriKind.Relative);
var song = Song.FromUri(name, uri);
FrameworkDispatcher.Update();
MediaPlayer.Play(song);
However, in Windows Phone 8.1 this doesn't work.
What do I need to do to play mp3 files I have stored in my solution?
You need to use MediaElement in Windows 8.1: http://blogs.msdn.com/b/johnkenn/archive/2013/12/31/supporting-background-audio-in-your-windows-8-1-app.aspx
Playing Audio from a file stored in the Music folder
var audioFile = await KnownFolders.MusicLibrary.GetFileAsync("/Resources/mp3Files/sound.mp3");
var stream = await audioFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
mediaplayer.SetSource(stream, audioFile.ContentType);
Take a look for a whole example: http://msdn.microsoft.com/library/windows/apps/xaml/jj841209.aspx
This is what worked:
// get folder app is installed to
var installFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
// get folders mp3 files are installed to.
var resourcesFolder = await installFolder.GetFolderAsync("Resources");
var mp3FilesFolder = await resourcesFolder.GetFolderAsync("mp3Files");
// open the mp3 file async
var audioFile = await mp3FilesFolder.GetFileAsync("sound.mp3");
var stream = await audioFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
// play dat funky music
MediaElement mediaplayer = new MediaElement();
mediaplayer.SetSource(stream, audioFile.ContentType);
mediaplayer.Play();
Here is how one used to open a file in WP8.0 embedded in solution with 'Build Action' 'Content':
Dim fs As IO.FileStream = IO.File.OpenRead("MyFolder/MyFile.txt")
And here is how it is done in WP8.1 Win-RT:
Dim fs As System.IO.Stream = Await Windows.ApplicationModel.Package.Current.InstalledLocation.OpenStreamForReadAsync("MyFolder\MyFile.txt")
Notice how "/" has changed to "\".

How to update a custom image Live Tile every minute in Windows Phone 8.1?

There are quite a few Windows Phone 8.1 apps (e.g. Clock hub, Analog Clock Tile, etc.) which allow you to pin an analog clock on the main screen.
I am trying to do the same by following this sample which shows me how to update an XML document every minute.
But if I am going to create an analog clock tile then it needs to be an image.
I have tried to use XamlRenderingBackgroundTask with RenderTargetBitmap to generate the image, this bit works. What I am not sure is how can I update this image every minute.
Any help wold be greatly appreciated!
I took the sample you provided and modified it to generate a custom image live tile every minute.
I've tested it on my phone and it seems to be working OK. You might need to do more testing such as memory usage testing to make sure it doesn't go over the cap (maybe can reduce planTill to 30 minutes to generate less tiles in the loop?).
The UserControl xml file SquareFrontTile1.xml
<Border Height="360" Width="360" Background="#00b2f0" xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006'>
<TextBlock Text="{0}" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="White" FontSize="50.667" />
</Border>
The code
public static async void UpdateAsync(BackgroundTaskDeferral deferral)
{
TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
IReadOnlyList<ScheduledTileNotification> plannedUpdated = tileUpdater.GetScheduledTileNotifications();
string language = GlobalizationPreferences.Languages.First();
CultureInfo cultureInfo = new CultureInfo(language);
DateTime now = DateTime.Now;
DateTime planTill = now.AddHours(1);
DateTime updateTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0).AddMinutes(1);
if (plannedUpdated.Count > 0)
updateTime = plannedUpdated.Select(x => x.DeliveryTime.DateTime).Union(new[] { updateTime }).Max();
StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
StorageFile file = await folder.GetFileAsync("SquareFrontTile1.xml");
string xml = await Windows.Storage.FileIO.ReadTextAsync(file);
string startXml = string.Format(xml, now.ToString(cultureInfo.DateTimeFormat.ShortTimePattern));
XmlDocument tileDocumentNow = await GetTileXmlDocument(startXml);
TileNotification notification = new TileNotification(tileDocumentNow) { ExpirationTime = now.AddMinutes(1) };
tileUpdater.Update(notification);
for (var startPlanning = updateTime; startPlanning < planTill; startPlanning = startPlanning.AddMinutes(1))
{
Debug.WriteLine(startPlanning);
Debug.WriteLine(planTill);
try
{
string updateXml = string.Format(xml, startPlanning.ToString(cultureInfo.DateTimeFormat.ShortTimePattern));
XmlDocument updatedTileDocument = await GetTileXmlDocument(updateXml);
ScheduledTileNotification scheduledNotification = new ScheduledTileNotification(updatedTileDocument, new DateTimeOffset(startPlanning)) { ExpirationTime = startPlanning.AddMinutes(1) };
tileUpdater.AddToSchedule(scheduledNotification);
Debug.WriteLine("schedule for: " + startPlanning);
}
catch (Exception e)
{
Debug.WriteLine("exception: " + e.Message);
}
}
deferral.Complete();
}
private static async Task<XmlDocument> GetTileXmlDocument(string xml)
{
Border tileUIElement = XamlReader.Load(xml) as Border;
string liveTileImageName = string.Format("UpdatedLiveTile_{0}.png", DateTime.Now.Ticks.ToString());
if (tileUIElement != null)
{
RenderTargetBitmap rtb = new RenderTargetBitmap();
await rtb.RenderAsync(tileUIElement, 150, 150);
IBuffer pixels = await rtb.GetPixelsAsync();
DataReader dReader = Windows.Storage.Streams.DataReader.FromBuffer(pixels);
byte[] data = new byte[pixels.Length];
dReader.ReadBytes(data);
var outputFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.CreateFileAsync(liveTileImageName, Windows.Storage.CreationCollisionOption.ReplaceExisting);
var outputStream = await outputFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, outputStream);
enc.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, 150, 150, 96, 96, data);
await enc.FlushAsync();
}
var tileDocument = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Image);
var tileImageAttributes = tileDocument.GetElementsByTagName("image");
XmlElement tmp = tileImageAttributes[0] as XmlElement;
tmp.SetAttribute("src", liveTileImageName);
return tileDocument;
}
I am not going to fully answer the question since I am myself trying to get this working at present. However I will set you in right direction. I have done this in past with windows 8.
What you need to do is create Tile Updater and schedule tiles updates every so often.. in this case one every minute. The tile schema chosen can have be image or text or a combination of both.
you can find the TileSchema catalogue here
http://msdn.microsoft.com/en-us/library/windows/apps/hh761491.aspx
and details of Tile Schema here
http://msdn.microsoft.com/en-us/library/windows/apps/br212859.aspx
Here is a Windows 8 sample
http://code.msdn.microsoft.com/windowsapps/scheduled-notifications-da477093
Here is a snippet from my code which isn't working correctly so far.. tile is blank
TileUpdater updater = TileUpdateManager.CreateTileUpdaterForApplication();
XmlDocument document = new XmlDocument();
document.LoadXml(str2);
ScheduledTileNotification notification2 = new ScheduledTileNotification(document, new DateTimeOffset(time4));
notification2.ExpirationTime = (new DateTimeOffset?((DateTimeOffset)time4.AddMinutes(1.0)));
ScheduledTileNotification notification = notification2;
updater.AddToSchedule(notification);
Once I finish this, I will write up a blog post and add a link here
I have created a repro project that tries to do this from within sample app (not background task).
http://1drv.ms/1nai8nn
The sample work for me, I add to Windows Phone Silverlight 8.1. You must change Notification Services from MPN to WNS in WMAppManifest.xml and add Background task, tick System event, Timer in Package.appxmanifest (Declarations tab).
#Justin XL: your code not work for me, error in line
Border tileUIElement = XamlReader.Load(xml) as Border;
Error: The application called an interface that was marshalled for a different thread.