offline images

friends list / select
friend distance
This commit is contained in:
2011-04-05 00:40:21 +03:00
parent f79ee0adc2
commit bf599907dc
23 changed files with 1099 additions and 348 deletions
@@ -9,7 +9,7 @@
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8192/GpsEmulator" binding="basicHttpBinding"
<endpoint address="http://localhost:9192/GpsEmulator" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IGpsEmulatorService"
contract="ServiceReference1.IGpsEmulatorService" name="BasicHttpBinding_IGpsEmulatorService" />
</client>
+95
View File
@@ -0,0 +1,95 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
using System.IO;
using System.IO.IsolatedStorage;
using System.Runtime.Serialization;
namespace WPImageCaching
{
internal static class ImageCache
{
private const string IMAGECACHEFILE = "imagecachefile.nfo";
internal static Dictionary<string, ImageCacheItem> imageCache;
public static BitmapImage GetImage(BitmapImage image)
{
string url = image.UriSource.ToString();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
//Wenn im Designmodus von Blend oder Visual Studio
image.UriSource = new Uri(url);
return image;
}
if (imageCache==null)
{
LoadCachedImageInfo();
}
//Prüfen auf ein vorhandenes gespeichertes Bild
if (imageCache.ContainsKey(url))
{
//Prüfen auf Gültigkeit des Bildes
if (DateTime.Compare(DateTime.Now, imageCache[url].Expiration) >= 0)
{
ImageDownloadHelper.DownloadImage(url,image,imageCache[url]);
}
else
{
//Bild ist noch gültig
image.SetSource(IsolatedStorageFile.GetUserStoreForApplication().OpenFile(imageCache[url].LocalFilename, FileMode.Open));
return image;
}
}
else
{
//Bild noch nicht gespeichert
ImageCacheItem item = new ImageCacheItem();
ImageDownloadHelper.DownloadImage(url, image, item);
}
return image;
}
//Laden der Bildinformationen
private static void LoadCachedImageInfo()
{
if (IsolatedStorageFile.GetUserStoreForApplication().FileExists(IMAGECACHEFILE))
{
IsolatedStorageFileStream fs =
IsolatedStorageFile.GetUserStoreForApplication().OpenFile(IMAGECACHEFILE,FileMode.Open);
DataContractSerializer dcs = new DataContractSerializer(typeof(Dictionary<string, ImageCacheItem>));
imageCache = (Dictionary<string, ImageCacheItem>)dcs.ReadObject(fs);
fs.Close();
}
else
{
imageCache = new Dictionary<string, ImageCacheItem>();
}
}
//Speichern der Bildinformationen
internal static void SaveCachedImageInfo()
{
IsolatedStorageFileStream fs =
IsolatedStorageFile.GetUserStoreForApplication().CreateFile(IMAGECACHEFILE);
DataContractSerializer dcs = new DataContractSerializer(typeof(Dictionary<string, ImageCacheItem>));
dcs.WriteObject(fs, imageCache);
fs.Flush();
fs.Close();
}
}
}
@@ -0,0 +1,38 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Data;
using System.Globalization;
using System.Windows.Media.Imaging;
namespace WPImageCaching
{
public class ImageCacheConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is BitmapImage)
{
return ImageCache.GetImage((BitmapImage)value);
}
else
{
return value;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,21 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace WPImageCaching
{
//Beinhaltet die Informationen eines Bildes
internal class ImageCacheItem
{
public string LocalFilename { get; set; }
public string ImageID { get; set; }
public DateTime Expiration { get; set; }
}
}
@@ -0,0 +1,132 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Text;
using System.Security.Cryptography;
using System.Threading;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.IO;
using System.Windows.Media.Imaging;
namespace WPImageCaching
{
internal static class ImageDownloadHelper
{
private const double EXPIRATIONDAYS = 1.0;
//Hilfsmethode zum Laden des Bildes
public static void DownloadImage(string url, BitmapImage image, ImageCacheItem item)
{
string filename = CreateUniqueFilename(url);
item.LocalFilename = filename;
//Erstellen des Hilfsobjektes zur Übergabe an den asynchronen Aufruf
AsyncDataTransfer transfer = new AsyncDataTransfer();
transfer.Item = item;
transfer.Image = image;
//Erstellen der Abfrage
var wc = (HttpWebRequest)HttpWebRequest.Create(url);
if (item.ImageID!=null)
{
//Prüfen, ob das Bild im Web immer noch aktuell ist
wc.Headers["If-None-Match"] = item.ImageID;
}
transfer.WebRequest = wc;
wc.BeginGetResponse(RequestCallback, transfer);
}
private static void RequestCallback(IAsyncResult result)
{
//War die Abfrage erfolgreich
if (!result.IsCompleted)
{
return;
}
//Herstellen des Hilfsobjektes
AsyncDataTransfer transfer = (AsyncDataTransfer)result.AsyncState;
try
{
var response = (HttpWebResponse)transfer.WebRequest.EndGetResponse(result);
//Bild wurde nicht geändert seit dem letzten Aufruf
if (response.StatusCode == HttpStatusCode.NotModified)
{
Deployment.Current.Dispatcher.BeginInvoke(() => transfer.Image.SetSource(IsolatedStorageFile.GetUserStoreForApplication().OpenFile(transfer.Item.LocalFilename, FileMode.Open)));
return;
}
//Hat das Bild eine neue ID?
if (response.Headers["ETag"] != null)
{
transfer.Item.ImageID = response.Headers["ETag"];
}
else
{
transfer.Item.ImageID = null;
}
//Gibt es ein Ablaufdatum?
if (response.Headers["Expires"] != null)
{
transfer.Item.Expiration = DateTime.Parse(response.Headers["Expires"]);
}
else
{
transfer.Item.Expiration = DateTime.Now.AddDays(EXPIRATIONDAYS);
}
var responseStream = response.GetResponseStream();
//Schreiben der Bilddatei
using (var bw = new BinaryWriter(IsolatedStorageFile.GetUserStoreForApplication().CreateFile(transfer.Item.LocalFilename)))
{
byte[] b = new byte[4096];
int read = 0;
while ((read = responseStream.Read(b, 0, b.Length)) > 0)
{
bw.Write(b, 0, read);
}
bw.Flush();
bw.Close();
}
//Setzen des Bildes
Deployment.Current.Dispatcher.BeginInvoke(() => transfer.Image.SetSource(IsolatedStorageFile.GetUserStoreForApplication().OpenFile(transfer.Item.LocalFilename, FileMode.Open)));
//Hinzufügen der Bildinformationen
ImageCache.imageCache.Add(transfer.WebRequest.RequestUri.ToString(), transfer.Item);
//Speichern der Bildinformationen
ImageCache.SaveCachedImageInfo();
}
catch
{
//Nichts machen, da Bild nicht heruntergeladen werden konnte
}
}
//Erstellt einen eindeutigen Namen für das zu ladende Bild
private static string CreateUniqueFilename(string url)
{
string extension = System.IO.Path.GetExtension(url);
byte[] textToHash = Encoding.UTF8.GetBytes(url);
SHA1Managed sa = new SHA1Managed();
byte[] hash = sa.ComputeHash(textToHash);
return BitConverter.ToString(hash)+extension;
}
}
//Hilfsklasse für den asynchronen Aufruf
internal class AsyncDataTransfer
{
public ManualResetEvent ResetEvent { get; set; }
public HttpWebRequest WebRequest { get; set; }
public BitmapImage Image { get; set; }
public ImageCacheItem Item { get; set; }
}
}
@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WPImageCaching")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("WPImageCaching")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a6a5ab19-1d8d-4a28-a25f-f1529b26d5b8")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.20506</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{17158FD9-80FD-49C1-9E3F-C5633602A4D9}</ProjectGuid>
<ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WPImageCaching</RootNamespace>
<AssemblyName>WPImageCaching</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
<TargetFrameworkProfile>WindowsPhone</TargetFrameworkProfile>
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
<SilverlightApplication>false</SilverlightApplication>
<ValidateXaml>true</ValidateXaml>
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>Bin\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>Bin\Release</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Windows" />
<Reference Include="system" />
<Reference Include="System.Core" />
<Reference Include="System.Xml" />
<Reference Include="System.Net" />
</ItemGroup>
<ItemGroup>
<Compile Include="ImageCache.cs" />
<Compile Include="ImageCacheConverter.cs" />
<Compile Include="ImageCacheItem.cs" />
<Compile Include="ImageDownloadHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
<ProjectExtensions />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>