Windows Phone 8.1 live tile not updating daily - windows-phone-8.1

I'm having problems to get my Windows Phone 8.1 live tile update by itself daily (around 7am)
My project has 2 parts :
a Web API project hosted on Azure that provides the tile template in XML (that part works fine)
a Windows Phone 8.1 project with a single MainPage.xaml where I build 2 square/wide tiles
When I pin my app to the start screen from the app list, my tile (whether I choose the square or wide format) flips back and forth between my 2 brands of the day just fine.
The next morning at 7:15 am, the tile won't update with the 2 new brands :(
I noticed that if I tap the tile to launch the app and come back to the start screen, the tile has updated.
It also works if I unpin and repin the tile but in both cases, that's "cheating" :-/
I call my Azure website like this to get the tile templates of both brands :
http://example.azurewebsites.net/api/tiles/0 (BRAND1)
http://example.azurewebsites.net/api/tiles/1 (BRAND2)
The XML tile template looks like this (example):
<tile>
<visual>
<binding template="TileWide310x150ImageAndText01">
<image id="1" src="http://www.example.com/sales/BRAND1/visualWide.png"/>
<text id="1">Brand 1</text>
</binding>
<binding template="TileSquare150x150PeekImageAndText04">
<image id="1" src="http://www.example.com/sales/BRAND1/visualSquare.png"/>
<text id="1">Brand 1</text>
</binding>
</visual>
</tile>
The WP8.1 page contains this :
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
TileUpdateManager.CreateTileUpdaterForApplication().EnableNotificationQueue(true);
PeriodicUpdateRecurrence recurrence = PeriodicUpdateRecurrence.Daily;
Task<string> responseBody;
for (int i = 0; i < 2; i++)
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("http://xxxxx.azurewebsites.net/api/tiles/" + i); //I hid the address here for discretion
HttpResponseMessage response = httpClient.GetAsync(httpClient.BaseAddress).Result;
string statusCode = response.StatusCode.ToString();
response.EnsureSuccessStatusCode();
responseBody = response.Content.ReadAsStringAsync();
}
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(responseBody.Result);
string srcWide, srcSquare, textWide, textSquare, templateWide, templateSquare;
XElement root = XElement.Parse(responseBody.Result);
IEnumerable<XElement> wideElement = root.Descendants("binding").Where(a => a.Attribute("template").Value.ToLower().Contains("wide"));
IEnumerable<XElement> squareElement = root.Descendants("binding").Where(a => a.Attribute("template").Value.ToLower().Contains("square"));
templateWide = wideElement.Attributes("template").SingleOrDefault().Value;
srcWide = wideElement.Descendants("image").Attributes("src").SingleOrDefault().Value;
textWide = wideElement.Descendants("text").SingleOrDefault().Value;
templateSquare = squareElement.Attributes("template").SingleOrDefault().Value;
srcSquare = wideElement.Descendants("image").Attributes("src").SingleOrDefault().Value;
textSquare = wideElement.Descendants("text").SingleOrDefault().Value;
XmlDocument wideTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150ImageAndText01);
XmlNodeList wideTileTextAttributes = wideTileXml.GetElementsByTagName("text");
wideTileTextAttributes[0].InnerText = textWide;
XmlNodeList wideTileImageAttributes = wideTileXml.GetElementsByTagName("image");
((XmlElement)wideTileImageAttributes[0]).SetAttribute("src", srcWide);
((XmlElement)wideTileImageAttributes[0]).SetAttribute("alt", textWide);
XmlDocument squareTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150PeekImageAndText01);
XmlNodeList squareTileTextAttributes = squareTileXml.GetElementsByTagName("text");
squareTileTextAttributes[0].AppendChild(squareTileXml.CreateTextNode(textSquare));
XmlNodeList squareTileImageAttributes = squareTileXml.GetElementsByTagName("image");
((XmlElement)squareTileImageAttributes[0]).SetAttribute("src", srcSquare);
((XmlElement)squareTileImageAttributes[0]).SetAttribute("alt", textSquare);
IXmlNode node = wideTileXml.ImportNode(squareTileXml.GetElementsByTagName("binding").Item(0), true);
wideTileXml.GetElementsByTagName("visual").Item(0).AppendChild(node);
TileNotification tileNotification = new TileNotification(wideTileXml);
tileNotification.ExpirationTime = DateTimeOffset.UtcNow.AddDays(1).AddHours(7).AddMinutes(0);
TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);
}
List<Uri> urisToPoll = new List<Uri>(5);
urisToPoll.Add(new Uri("http://example.azurewebsites.net/api/tiles/0")); //fake url
urisToPoll.Add(new Uri("http://example.azurewebsites.net/api/tiles/1")); //fake url
//I want the tile to update its content every day at 7:15am
//(the Azure website supposedly returns new brands of the day at 7am)
DateTime dtTomorrow7 = DateTime.SpecifyKind(DateTime.Today.AddDays(1).AddHours(7).AddMinutes(15), DateTimeKind.Local);
DateTimeOffset dtoTomorrow7 = dtTomorrow7;
TileUpdateManager.CreateTileUpdaterForApplication().StartPeriodicUpdateBatch(urisToPoll, dtoTomorrow7, recurrence);
}
I'm not sure I'm using the StartPeriodicUpdateBatch method correctly.
In debug mode,I can see the DateTimeOffset value is Day+1 7:15am +2:00 which looks correct but the tile does not update.
I live in France that is UTC+2
Thanks for your suggestions.

Your dtTomorrow7 is incorrect. It should just be 7:15 AM. Then it will first do an update at 7:15 AM and subsequent updates occurring at the periodic interval thereafter(you set it to daily).
Example of start time where the last TimeSpan is offset from UTC:
DateTime tomorrow = DateTime.Today.AddDays(1);
var startTime = new DateTimeOffset(tomorrow.Year, tomorrow.Month, tomorrow.Day, 7, 15, 0, TimeSpan.FromHours(2));

Related

Get SIM MSISDN & IMSI number in Windows Phone Application

Is it possible to get the SIM MSISDN & IMSI number in windows Phone app development?
I have gone through some of the Q/A but they all are asked a long time ago.
You could get SIM MSISDN & IMSI number in Windows Phone Application. Please notice that you should manually edit your application Package.appxmanifest as follows:
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
......
<Capabilities>
<rescap:Capability Name="cellularDeviceIdentity" />
</Capabilities>
The cellularDeviceIdentity capability allows apps to access cellular identification data.
Anyone may request access to these capabilities for store submission.
You could use MobileBroadbandModem class to get all CurrentDeviceInformation, and the following is core codes.
using Windows.Networking.NetworkOperators;
......
public IReadOnlyList<SimCard> GetSimCards()
{
var results = new List<SimCard>();
var modem = MobileBroadbandModem.GetDefault();
if (modem == null)
{
return results.AsReadOnly();
}
var account = modem.CurrentAccount;
if (account == null)
{
return results.AsReadOnly();
}
var simCard = new SimCard();
simCard.ICCID = account.CurrentDeviceInformation.SimIccId;
simCard.IMSI = account.CurrentDeviceInformation.SubscriberId;
simCard.MSISDN = modem.DeviceInformation.TelephoneNumbers;
simCard.MCC = ExtractMCC(simCard.IMSI);
simCard.MNC = ExtractMNC(simCard.IMSI);
simCard.MSID = ExtractMSID(simCard.IMSI);
results.Add(simCard);
return results.AsReadOnly();
}
I have uploaded code sample to git hub. Please check!

Embedding SSRS 2016 reports into another webpage without iFrame?

Reporting-services 2016 (currently only available as a technical preview) comes with big-upgrades including HTML5 rendering and compliance. See: https://msdn.microsoft.com/en-us/library/ms170438.aspx
My desire is to embed SSRS 2016 reports into another webpage using native mode (no Sharepoint or aspx, just pure HTML5).
The traditional fashion to do this is to use an iFrame.
This is an half-way okay method as it's possible to remove the toolbar, hide parameters etc but still you end up losing a lot of control over the document. This is a cross-site implementation from a different domain so I can't manipulate the contained iFrame document as I please.
Does there exist an official way to embed the report element 'natively'?
I could envision a URL parameter option like rs:Format=REPORTDIV which serves me a html element.
I also tried fetching the report as an image (rs:Format=IMAGE&rc:OutputFormat=PNG) but the resulting PNG has a huge white frame (even when setting background to transparent in Report Builder) around the report element which is a no-go.
This should work. It should work outside of the environment as well as it embeds the images from memory instead of fetching them from the database
// Create service instance
ReportExecutionServiceSoapClient rsExec = new ReportExecutionServiceSoapClient(binding, endpoint);
rsExec.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
rsExec.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
ReportingServices.Extension[] extentions = null;
ReportingServices.TrustedUserHeader trustedUserHeader = new ReportingServices.TrustedUserHeader();
rsExec.ListRenderingExtensions(trustedUserHeader, out extentions);
string reportPath = "/Untitled";
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
ReportingServices.ServerInfoHeader serverInfo = new ReportingServices.ServerInfoHeader();
string historyID = null;
rsExec.LoadReport(trustedUserHeader, reportPath, historyID, out serverInfo, out execInfo);
//Get execution ID
execHeader.ExecutionID = execInfo.ExecutionID;
string deviceInfo = null;
string extension;
string encoding;
string mimeType;
ReportingServices.Warning[] warnings = new ReportingServices.Warning[1];
warnings[0] = new ReportingServices.Warning();
string[] streamIDs = null;
string format = "HTML5";
Byte[] result;
rsExec.Render(execHeader, trustedUserHeader, format, deviceInfo, out result, out extension, out mimeType, out encoding, out warnings, out streamIDs);
var report = Encoding.UTF8.GetString(result);
int streamIdCount = streamIDs.Length;
Byte[][] imageArray = new Byte[streamIdCount][];
String[] base64Images = new String[streamIdCount];
for (int i = 0; i <= streamIdCount - 1; i++)
{
Byte[] result2;
string streamId = streamIDs[i];
rsExec.RenderStream(execHeader, trustedUserHeader, format, streamId, deviceInfo, out result2, out encoding, out mimeType);
imageArray[i] = result2;
base64Images[i] = Convert.ToBase64String(result2);
string replace = string.Format("https://<reportserver>/ReportServer?%2FUntitled&rs%3ASessionID={0}&rs%3AFormat={1}&rs%3AImageID={2}", execInfo.ExecutionID, format, streamId);
string src = string.Format("data:{0};charset=utf-8;base64, {1}", mimeType, base64Images[i]);
report = report.Replace(replace, src);
}

Save ringtones in wp8

Well I was wondering why i can't save ringtones on windows phone
SaveRingtone ringtone = new SaveRingtone();
ringtone.Source = new Uri("appdata:/"+path);
ringtone.DisplayName = b.Content.ToString();
ringtone.Completed += Ringtone_Save_completed;
ringtone.Show();
this is my code
Well you was so close.
The class SaveRingtone it is SaveRingtoneTask
SaveRingtoneTask ringtone = new SaveRingtoneTask();
ringtone.Source = new Uri("appdata:/"+path);
ringtone.DisplayName = b.Content.ToString();
ringtone.Completed += Ringtone_Save_completed;
ringtone.Show();
and you will need to add
using Microsoft.Phone.Tasks;

Why does MusicProperties->Year always return the current year?

I'm trying to get the music properties for each file in the music library by using the StorageFolder APIs.
After calling GetFilesAsync(CommonFileQuery::OrderByName) on my music library I'm iterating over the resulting IVectorView^ and calling StorageFile->Properties->GetMusicPropertiesAsync() for each file, which is inherently slow but I have to do it this way, since QueryOptions are not supported on Windows Phone for some reason.
Anyway, after completing that task every property is correct except for MusicProperties->Year, which is 2014 for every single one of well over 900 music files on my phone. Here's a short code snippet:
create_task(lib->GetFilesAsync(Search::CommonFileQuery::OrderByName))
.then([](IVectorView<StorageFile^>^ songFiles)
{
auto taskPtr = std::make_shared<std::vector<task<Song>>>(songFiles->Size);
for (size_t i = 0, len = songFiles->Size; i < len; ++i)
{
StorageFile^ song = songFiles->GetAt(i);
(*taskPtr)[i] = create_task(song->Properties->GetMusicPropertiesAsync()).then([]
(MusicProperties^ props)
{
Song s;
s.album = std::wstring(std::move(props->Album->Data()));
s.artist = std::wstring(std::move(props->Artist->Data()));
s.title = std::wstring(std::move(props->Title->Data()));
s.track = props->TrackNumber;
s.year = props->Year;
return s;
});
}
//further processing is done in a when_all function after the song tasks have completed
}
Song is just a plain struct to save my result temporarily and convert it to JSON later on, but that Year property is freaking me out. Has anybody else encountered that issue already and is there any other way to retrieve the proper release year from a music file?

Windows phone crash when loading rss feed

I got some code to load rss feeds to my WindowsPhone app:
var result = e.Result;
result = result.Replace("\t", string.Empty);
result = result.Replace("\n", string.Empty);
var rssItems = XDocument.Parse(result.Replace("dc:creator", "creator")).Descendants("item").Select(
x => new RssItem()
{
Title = (string)x.Element("title"),
Description = (string)x.Element("description"),
Link = (string)x.Element("link"),
Author = (string)x.Element("creator"),
Comments = (string)x.Element("comments"),
PubDate = ParseNewsDateToStringFormatExtended(Convert.ToDateTime((string)x.Element("pubDate"))),
ThumbnailPart = stripImagePathFromDescription((string)x.Element("description").Value.ToString()),
StrippedHtml = strippedHtmlConversion((string)x.Element("title"), (string)x.Element("creator"), ParseNewsDateToStringFormatExtended(Convert.ToDateTime((string)x.Element("pubDate"))), (string)x.Element("description").Value.ToString())
}
).ToList();
success(rssItems);
When it loads feeds containing this symbol « or » it crashes. How can i make my app able to read these symbols?
EDIT: here is one element from my rss feed:
<item>
<title>Norges «skjulte perle» utvider</title>
As you can see there a «» in the title of the item. And i know that's why it crashes. But why? And how to handle these symbols?