Cross fade page transitions Windows phone 8 toolkit - windows-phone-8

I'm implementing the NavigationTransition with the TransitionService provided by the Windows Phone 8 toolkit and Microsoft.Phone.Controls. I was expecting the pages to cross fade during the transition but they don't crossfade by default.
For instance if I'm going back to a previous page using a fade out transition, the origin page fades to full opacity before the target page appears, producing a "popping" effect.
I hoping that someone could provide guidance on getting that effect to happen.

Please check the type of your RootFrame in App.xaml.cs, it must be TransitionFrame if want to use NavigationTransition.

I ended up using some slight-of-hand with screen shots and the far background plane to make the phone pages appear to "cross-fade" - here with edited out biz-details:
public class FormPage : PhoneApplicationPage {
public FormPage() {
InitializeComponent();
PrepareAnimationIn(FormApp.frameTransition);
}
void PrepareAnimationIn(string pageAnimation) {
AnimatedPageFactory.SetNavigationInTransition(pageAnimation, this);
}
public void PrepareAnimationOut(string pageAnimation) {
AnimatedPageFactory.SetNavigationOutTransition(pageAnimation, this);
}
void StoreScreenShot(string name, WriteableBitmap bitmap) {
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
string path = Path.Combine(screenshotDir, name + screenFileType);
store.CreateDirectory(screenshotDir);
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(path, FileMode.Create, store)) {
using (BinaryWriter writer = new BinaryWriter(stream)) {
int count = bitmap.Pixels.Length * sizeof(int);
byte[] pixels = new byte[count];
Buffer.BlockCopy(bitmap.Pixels, 0, pixels, 0, count);
writer.Write(pixels, 0, pixels.Length);
}
}
}
}
WriteableBitmap FetchScreenShot(string name) {
WriteableBitmap bitmap = new WriteableBitmap((int)this.ActualWidth, (int)this.ActualHeight);
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
string path = Path.Combine(screenshotDir, name + screenFileType);
if (store.FileExists(path)) {
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(path, FileMode.Open, store)) {
using (BinaryReader reader = new BinaryReader(stream)) {
int count = bitmap.Pixels.Length * sizeof(int);
byte[] pixels = new byte[count];
reader.Read(pixels, 0, count);
Buffer.BlockCopy(pixels, 0, bitmap.Pixels, 0, count);
}
}
store.DeleteFile(path);
}
}
return bitmap;
}
WriteableBitmap ScreenShot() {
WriteableBitmap bmpCurrentScreenImage = new WriteableBitmap((int)this.ActualWidth, (int)this.ActualHeight);
bmpCurrentScreenImage.Render(_canvas, new MatrixTransform());
bmpCurrentScreenImage.Invalidate();
return bmpCurrentScreenImage;
}
ImageBrush ImageBrushFromBitmap(WriteableBitmap bitmap) {
return new ImageBrush { ImageSource = bitmap };
}
static Stack<string> formImages = new Stack<string>();
static string screenFileType = ".frmscn";
static string screenshotDir = "frmscrn";
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) {
var app = Application.Current as App;
if (e.NavigationMode == NavigationMode.New &&
e.Uri.ToString().Contains("FormPage.xaml")) {
WriteableBitmap screenShot = ScreenShot();
app.RootFrame.Background = ImageBrushFromBitmap(screenShot);
formImages.Push(Name);
StoreScreenShot(Name, screenShot);
} else if (e.NavigationMode == NavigationMode.Back) {
if (formImages.Count > 0)
app.RootFrame.Background = ImageBrushFromBitmap(FetchScreenShot(formImages.Pop()));
else {
//we're backing out of the last form so reset the background
app.RootFrame.Background = null;
RemoveCachedScreenshots();
}
}
}
public static void RemoveCachedScreenshots() {
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
string path = Path.Combine(screenshotDir, "*" + screenFileType);
try {
string[] fileList = store.GetFileNames(path);
foreach (string f in fileList) {
store.DeleteFile(Path.Combine(screenshotDir, f));
}
} catch {
}
}
}
}

Related

Clear image cache created by <Image>

If I have an element like this in a Windows Store or Windows Phone application:
<Image Source="{Binding UrlToWebServer}" />
the image is cached locally. This is great. But how do I remove all cached images on disc from code?
You just have to set the imagesource to NULL
Something like this:
BitmapImage bitmapImage = myimage.Source as BitmapImage;
bitmapImage.UriSource = null;
myimage.Source = null;
This works for me. Here you can find mor infos handling images (section Image Caching for example).
Hi it´s a little bit late to answer this question but you can use this class to delete the cache of a specific files or all if you want
this is the class helper
class CacheCleanup : IDisposable
{
private DispatcherTimer cleanCacheTimer;
public CacheCleanup(TimeSpan? cleanInterval = null)
{
if (!cleanInterval.HasValue)
cleanInterval = TimeSpan.FromMinutes(0.2);
cleanCacheTimer = new DispatcherTimer();
cleanCacheTimer.Interval = cleanInterval.Value;
cleanCacheTimer.Tick += CleanCacheTimer_Tick;
cleanCacheTimer.Start();
}
private void CleanCacheTimer_Tick(object sender, object e)
{
try
{
StorageFolder localDirectory = ApplicationData.Current.LocalFolder;
string[] tmpCacheDirectories = Directory.GetDirectories(localDirectory.Path + "\\..\\ac\\inetcache");
foreach (string dir in tmpCacheDirectories)
{
string[] tmpCacheFilesPng = Directory.GetFiles(dir, "*.png");
foreach (string file in tmpCacheFilesPng)
{
try
{
File.Delete(file);
Debug.WriteLine("Deleted png: " + file);
}
catch (Exception) { }
}
string[] tmpCacheFilesJpg = Directory.GetFiles(dir, "*.jpg");
foreach (string file in tmpCacheFilesJpg)
{
try
{
File.Delete(file);
Debug.WriteLine("Deleted jpg: " + file);
}
catch (Exception) { }
}
}
}
catch (Exception ex) { Debug.WriteLine("ERROR CLEANING CACHE: " + ex.Message); }
}
public void Dispose()
{
if (cleanCacheTimer != null)
{
cleanCacheTimer.Stop();
cleanCacheTimer = null;
}
}
}
and this is the way how you can call this class in some part of your c# code
CacheCleanup cacheCleanup = new CacheCleanup();

Accurate Windows phone 8.1 geolocation?

Im working with windows phone 8.1 geolocation. The problem that I currently have is that my code only shows the first numbers of my coordinate. Example: If the coordinate is "41.233" the app only shows "41.00" . I need it to be as accurate as possible. In case it matters, im using windows phone 8.1 emulator to try the app, not an actual phone.
My code:
public sealed partial class MainPage : Page
{
bool shouldSend = false;
DispatcherTimer timer = new DispatcherTimer();
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
private async Task GetLocation()
{
Geolocator geolocator = new Geolocator();
geolocator.DesiredAccuracy = Windows.Devices.Geolocation.PositionAccuracy.High;
try
{
Geoposition geoposition = await geolocator.GetGeopositionAsync(
maximumAge: TimeSpan.FromSeconds(1),
timeout: TimeSpan.FromSeconds(10)
);
LatitudeTxt.Text = geoposition.Coordinate.Latitude.ToString("0.00");
LongitudeTxt.Text = geoposition.Coordinate.Longitude.ToString("0.00");
LatLonTxt.Text = LatitudeTxt.Text + ", " + LongitudeTxt.Text;
var speed = geoposition.Coordinate.Speed.ToString();
ProcessingTxt.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
string result = "";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
"http://proyecto-busways.rhcloud.com/colectivos?p=lta123&l=80&d=moyano&lat=" + LatitudeTxt.Text + "&lon=" + LongitudeTxt.Text + "&v=" + speed + "&Accion=Agregar");
request.ContinueTimeout = 4000;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
{
if (response.StatusCode == HttpStatusCode.OK)
{
//To obtain response body
using (Stream streamResponse = response.GetResponseStream())
{
using (StreamReader streamRead = new StreamReader(streamResponse, Encoding.UTF8))
{
result = streamRead.ReadToEnd();
}
}
}
}
}
catch (Exception ex)
{
ProcessingTxt.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
if ((uint)ex.HResult == 0x80004004)
{
// the application does not have the right capability or the location master switch is off
}
//else
{
// something else happened acquring the location
}
}
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}
private async void StartSending_Click(object sender, RoutedEventArgs e)
{
await GetLocation();
timer.Tick += timer_Tick;
timer.Interval = new TimeSpan(0, 0, 5);
timer.Start();
StartSending.IsEnabled = false;
}
async void timer_Tick(object sender, object e)
{
ProcessingTxt.Visibility = Windows.UI.Xaml.Visibility.Visible;
await GetLocation();
}
private void EndSending_Click(object sender, RoutedEventArgs e)
{
timer.Tick -= timer_Tick;
timer.Stop();
StartSending.IsEnabled = true;
EndSending.IsEnabled = false;
}
private void GPS_Tapped(object sender, TappedRoutedEventArgs e)
{
Frame.Navigate(typeof(ContactPage));
}
}
Thanks for your help!
Did you try out the Geolocator.DesiredAccuracyInMeters property?
geolocator.DesiredAccuracyInMeters = 3;
Reference & Sample
In this point LatitudeTxt.Text = geoposition.Coordinate.Latitude.ToString("0.00");
LongitudeTxt.Text = geoposition.Coordinate.Longitude.ToString("0.00");
You indicated that you have 0.00 decimals, for more accuracy you should put 0.000000

How cancel Async Call in Windows Phone?

I have a list wich is loaded with elements each time the user make a research...These elements contain an Icon which is dowloaded with an async method GetByteArrayAsync of the HttpClient object. I have an issue when the user make a second research while the icon of the first list are still downloading.Because the list of elements is changing while Icon downloads are processing on each element of the first list. So my guess is that I need to cancel these requests each time the user proceed to a new research...Ive readen some stuuf on Task.run and CancellationTokenSource but I can't find really helpful example for my case so here is my code...Hope you can help me with that ...Thank you
public static async Task<byte[]> DownloadElementFile(BdeskElement bdeskElement)
{
//create and send the request
DataRequest requesteur = new DataRequest();
byte[] encryptedByte = await requesteur.GetBytesAsync(dataRequestParam);
return encryptedByte;
}
public async Task<Byte[]> GetBytesAsync(DataRequestParam datarequesparam)
{
var handler = new HttpClientHandler { Credentials = new NetworkCredential(datarequesparam.AuthentificationLogin, datarequesparam.AuthentificationPassword, "bt0d0000") };
HttpClient httpClient = new HttpClient(handler);
try
{
byte[] BytesReceived = await httpClient.GetByteArrayAsync(datarequesparam.TargetUri);
if (BytesReceived.Length > 0)
{
return BytesReceived;
}
else
{
return null;
}
}
catch (WebException)
{
throw new MyException(MyExceptionsMessages.Webexception);
}
}
EDIT
public async Task<Byte[]> GetBytesAsync(DataRequestParam datarequesparam)
{
var handler = new HttpClientHandler { Credentials = new NetworkCredential(datarequesparam.AuthentificationLogin, datarequesparam.AuthentificationPassword, "bt0d0000") };
HttpClient httpClient = new HttpClient(handler);
try
{
cts = new CancellationTokenSource();
HttpResponseMessage reponse = await httpClient.GetAsync(datarequesparam.TargetUri,cts.Token);
if (reponse.StatusCode == HttpStatusCode.OK)
{
byte[] BytesReceived = reponse.Content.ReadAsByteArrayAsync().Result;
if (BytesReceived.Length > 0)
{
return BytesReceived;
}
else
{
return null;
}
}
else
{
return null;
}
}
catch (WebException)
{
throw new MyException(MyExceptionsMessages.Webexception);
}
catch(OperationCanceledException)
{
throw new OperationCanceledException();
}
EDIT2
I need to cancel this funntion when the user make a new research and the list "listBoxGetDocsLibs" changed.
private async void LoadIconDocLibs()
{
foreach (var doclib in listBoxGetDocsLibs)//ERROR HERE COLLECTION HAS CHANGED
{
doclib.Icon = new BitmapImage();
try
{
byte[] Icon = await ServerFunctions.GetDocLibsIcon(doclib);
if (Icon != null)
{
{
var ms = new MemoryStream(Icon);
BitmapImage photo = new BitmapImage();
photo.DecodePixelHeight = 64;
photo.DecodePixelWidth = 92;
photo.SetSource(ms);
doclib.Icon = photo;
}
}
}
catch(OperationCanceledException)
{
}
}
}
First you need to define CancellationTokenSource:
private System.Threading.CancellationTokenSource cts;
place above code somewhere, where you can access it with your Button or other method.
Unfortunately GetByteArrayAsync lacks Cancelling - so it cannot be used with cts.Token, but maybe you can accomplish your task using GetAsync - which supports Cancelling:
ctsDownload = new System.Threading.CancellationTokenSource();
HttpResponseMessage response = await httpClient.GetAsync(requestUri, cts.Token);
Then you can get your content from response.
And when you want to Cancel your Task it can look like this:
private void cancelBtn_Click(object sender, RoutedEventArgs e)
{
if (this.cts != null)
this.cts.Cancel();
}
When you Cancel task an Exception will be thrown.
If you want to cancel your own async Task, a good example you can find at Stephen Cleary blog.
EDIT - you can also build your own method (for example with HttpWebRequest) which will support Cancelling:
For this purpose you will have to extend HttpWebRequest (under WP it lacks GetResponseAsync):
// create a static class in your namespace
public static class Extensions
{
public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest webRequest)
{
TaskCompletionSource<HttpWebResponse> taskComplete = new TaskCompletionSource<HttpWebResponse>();
webRequest.BeginGetResponse(
asyncResponse =>
{
try
{
HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
taskComplete.TrySetResult(someResponse);
}
catch (WebException webExc)
{
HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
taskComplete.TrySetResult(failedResponse);
}
catch (Exception exc) { taskComplete.SetException(exc); }
}, webRequest);
return taskComplete.Task;
}
}
Then your method can look like this:
public async Task<Byte[]> GetBytesAsync(DataRequestParam datarequesparam, CancellationToken ct)
{
HttpWebRequest request = HttpWebRequest.CreateHttp(datarequesparam.TargetUri);
request.Method = "GET";
request.Credentials = new NetworkCredential(datarequesparam.AuthentificationLogin, datarequesparam.AuthentificationPassword, "bt0d0000");
request.AllowReadStreamBuffering = false;
try
{
if (request != null)
{
using (HttpWebResponse response = await request.GetResponseAsync())
using (Stream mystr = response.GetResponseStream())
using (MemoryStream output = new MemoryStream())
{
const int BUFFER_SIZE = 10 * 1024;
byte[] buf = new byte[BUFFER_SIZE];
int bytesread = 0;
while ((bytesread = await mystr.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
{
output.Write(buf, 0, bytesread);
ct.ThrowIfCancellationRequested();
}
return output.ToArray();
}
}
else return null;
}
catch (WebException)
{
throw new MyException(MyExceptionsMessages.Webexception);
}
}
You can freely change Buffer Size which will affect how often Cancellation will be checked.
I haven't tried this but I think it should work.

Downloading multiple images from the net

I am developing a app in which i download the images from the net and store them into the Isolated Storage. Here is my Code.
private void LoadImage(List<ProductImageList> item)
{
BitmapImage bi = new BitmapImage();
foreach (var product in item)
{
string a = product.ImageUrl;
string b = a.Substring(1, a.Length - 2);
Uri uri = new Uri(b, UriKind.RelativeOrAbsolute);
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
//load image from Isolated Storage if it already exist
name = System.IO.Path.GetFileName(b);
if (myIsolatedStorage.FileExists(name))
{
}
else
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(DownloadCompleted);
wc.OpenReadAsync(uri, wc);
}
}
}
}
private void DownloadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(name);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(e.Result);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Encode WriteableBitmap object to a JPEG stream.
System.Windows.Media.Imaging.Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
}
}
catch (Exception ex)
{
//Exception handle appropriately for your app
}
}
The item contains the ImageId,ImageUrl.The code only download last image of my list all time.Please suggest me how can i download All images..
You should use HttpRequest instead of WebClient here is the example
private void LoadImage(List<ProductImageList> item)
{
BitmapImage bi = new BitmapImage();
foreach (var product in item)
{
string a = product.ImageUrl;
string b = a.Substring(1, a.Length - 2);
Uri uri = new Uri(b, UriKind.RelativeOrAbsolute);
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
//load image from Isolated Storage if it already exist
name = System.IO.Path.GetFileName(b);
if (myIsolatedStorage.FileExists(name))
{
}
else
{
HttpWebRequest imageRequest = HttpWebRequest.CreateHttp();
imageRequest.Headers["ImageName"] = name;
imageRequest.BeginGetResponse(Imageresponse, imageRequest);
}
}
}
}
private void Imageresponse(IAsyncResult asyncResult)
{
try
{
string name = string.Empty;
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
using (Stream data = response.GetResponseStream())
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
name = request.Headers["ImageName"];
if (!string.IsNullorEmpty(name))
{
using (IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(name))
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(data);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Encode WriteableBitmap object to a JPEG stream.
System.Windows.Media.Imaging.Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
}
}
}
}
}
catch (Exception ex)
{
}
}

How can I save a JSON response to a file in unity3D for ios and android

I'm working on a 2D mobile game for ios and android using Unity3D.
The game requires to save a JSON response to a file.
I use NGUI and MiniJSON for that.
I want to know how to implement that starting from www function to get JSOn response and save it to a file(including path) and load it from other script.
if it is too much, just give me a example for that.
Thank you
I haven't tested the code yet, but it might give you an idea :-)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
public class WWWJsonTest : MonoBehaviour
{
private const float SECONDS_BEFORE_TIMEOUT = 10;
private const string URL = "INSERT URL HERE";
private const string FILE_PATH = "INSERT FILE PATH";
public void DownloadAndSave()
{
StartCoroutine(DownloadCoroutine());
}
public Dictionary<object, object> GetSavedData()
{
// Use ReadContents() and do your MiniJSON magic here
return null;
}
private IEnumerator DownloadCoroutine()
{
var requestHeaders = new Hashtable()
{
{ "Connection", "close"},
{ "Accept", "application/json"}
};
using(var request = new WWW(URL, null, requestHeaders))
{
float timeStarted = Time.realtimeSinceStartup;
while(!request.isDone)
{
// Check if the download times out
if(Time.realtimeSinceStartup - timeStarted > SECONDS_BEFORE_TIMEOUT)
{
Debug.Log("Download timed out");
yield break;
}
yield return null;
}
// Check for other errors
if(request.error != null)
{
Debug.Log(request.error);
yield break;
}
SaveContents(request.text);
}
}
private string ReadContents()
{
string ret;
using(FileStream fs = new FileStream(FILE_PATH, FileMode.Open))
{
BinaryReader fileReader = new BinaryReader(fs);
ret = fileReader.ReadString();
fs.Close();
}
return ret;
}
private void SaveContents(string text)
{
using(FileStream fs = new FileStream(FILE_PATH, FileMode.Create))
{
BinaryWriter fileWriter = new BinaryWriter(fs);
fileWriter.Write(text);
fs.Close();
}
}
}