зеркало из https://github.com/microsoft/places.git
Updated to use latest Lumia SensorCore SDK 1.1 Preview
This commit is contained in:
Родитель
034deb40f0
Коммит
5adca97155
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -59,7 +60,7 @@ namespace Places
|
|||
this.Loaded += (sender, args) =>
|
||||
{
|
||||
var ver = Windows.ApplicationModel.Package.Current.Id.Version;
|
||||
VersionNumber.Text = string.Format("{0}.{1}.{2}", ver.Major, ver.Minor, ver.Revision);
|
||||
VersionNumber.Text = string.Format("{0}.{1}.{2}.{3}", ver.Major, ver.Minor,ver.Build, ver.Revision);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -30,26 +31,16 @@ using Windows.UI.Xaml.Navigation;
|
|||
namespace Places.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the method that will handle the <see cref="NavigationHelper.LoadState"/> event.
|
||||
/// </summary>
|
||||
public delegate void LoadStateEventHandler(object sender, LoadStateEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the method that will handle the <see cref="NavigationHelper.SaveState"/> event.
|
||||
/// </summary>
|
||||
public delegate void SaveStateEventHandler(object sender, SaveStateEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// NavigationHelper aids in navigation between pages. It provides commands used to
|
||||
/// navigate back and forward as well as registers for standard mouse and keyboard
|
||||
/// shortcuts used to go back and forward. In addition it integrates SuspensionManger
|
||||
/// to handle process lifetime management and state management when navigating between
|
||||
/// pages.
|
||||
/// NavigationHelper aids in navigation between pages. It provides commands used to
|
||||
/// navigate back and forward as well as registers for standard mouse and keyboard
|
||||
/// shortcuts used to go back and forward in Windows and the hardware back button in
|
||||
/// Windows Phone. In addition it integrates SuspensionManger to handle process lifetime
|
||||
/// management and state management when navigating between pages.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// To make use of NavigationHelper, follow these two steps or start with a BasicPage
|
||||
/// or any other Page item template other than BlankPage.
|
||||
/// <para>
|
||||
/// To make use of NavigationHelper, follow these two steps or
|
||||
/// start with a BasicPage or any other Page item template other than BlankPage.
|
||||
///
|
||||
/// 1) Create an instance of the NavigationHelper somewhere such as in the
|
||||
/// constructor for the page and register a callback for the LoadState and
|
||||
/// SaveState events.
|
||||
|
@ -62,14 +53,13 @@ namespace Places.Common
|
|||
/// this.navigationHelper.SaveState += navigationHelper_SaveState;
|
||||
/// }
|
||||
///
|
||||
/// async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
|
||||
/// private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
|
||||
/// { }
|
||||
/// private async void navigationHelper_SaveState(object sender, LoadStateEventArgs e)
|
||||
/// { }
|
||||
/// </code>
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// 2) Register the page to call into the NavigationManager whenever the page participates
|
||||
///
|
||||
/// 2) Register the page to call into the NavigationHelper whenever the page participates
|
||||
/// in navigation by overriding the <see cref="Windows.UI.Xaml.Controls.Page.OnNavigatedTo"/>
|
||||
/// and <see cref="Windows.UI.Xaml.Controls.Page.OnNavigatedFrom"/> events.
|
||||
/// <code>
|
||||
|
@ -83,156 +73,127 @@ namespace Places.Common
|
|||
/// navigationHelper.OnNavigatedFrom(e);
|
||||
/// }
|
||||
/// </code>
|
||||
/// </para>
|
||||
/// </example>
|
||||
[Windows.Foundation.Metadata.WebHostHidden]
|
||||
public class NavigationHelper : DependencyObject
|
||||
{
|
||||
#region Private constants
|
||||
/// <summary>
|
||||
/// Page instance
|
||||
/// </summary>
|
||||
private readonly Page page;
|
||||
|
||||
/// <summary>
|
||||
/// RelayCommand instance for go back command
|
||||
/// </summary>
|
||||
private RelayCommand goBackCommand;
|
||||
|
||||
/// <summary>
|
||||
/// RelayCommand instance for go forward command
|
||||
/// </summary>
|
||||
private RelayCommand goForwardCommand;
|
||||
|
||||
/// <summary>
|
||||
/// Page key
|
||||
/// </summary>
|
||||
private string pageKey;
|
||||
#endregion
|
||||
private Page Page { get; set; }
|
||||
private Frame Frame { get { return this.Page.Frame; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NavigationHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="page">
|
||||
/// A reference to the current page used for navigation.
|
||||
/// <param name="page">A reference to the current page used for navigation.
|
||||
/// This reference allows for frame manipulation and to ensure that keyboard
|
||||
/// navigation requests only occur when the page is occupying the entire window.
|
||||
/// </param>
|
||||
/// navigation requests only occur when the page is occupying the entire window.</param>
|
||||
public NavigationHelper(Page page)
|
||||
{
|
||||
this.page = page;
|
||||
this.Page = page;
|
||||
|
||||
// When this page is part of the visual tree make two changes:
|
||||
// 1) Map application view state to visual state for the page
|
||||
// 2) Handle keyboard and mouse navigation requests
|
||||
this.page.Loaded += (sender, e) =>
|
||||
// 2) Handle hardware navigation requests
|
||||
this.Page.Loaded += (sender, e) =>
|
||||
{
|
||||
#if WINDOWS_PHONE_APP
|
||||
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
|
||||
#else
|
||||
// Keyboard and mouse navigation only apply when occupying the entire window
|
||||
if (this.page.ActualHeight == Window.Current.Bounds.Height && this.page.ActualWidth == Window.Current.Bounds.Width)
|
||||
if (this.Page.ActualHeight == Window.Current.Bounds.Height &&
|
||||
this.Page.ActualWidth == Window.Current.Bounds.Width)
|
||||
{
|
||||
// Listen to the window directly so focus isn't required
|
||||
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated += CoreDispatcher_AcceleratorKeyActivated;
|
||||
Window.Current.CoreWindow.PointerPressed += this.CoreWindow_PointerPressed;
|
||||
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated +=
|
||||
CoreDispatcher_AcceleratorKeyActivated;
|
||||
Window.Current.CoreWindow.PointerPressed +=
|
||||
this.CoreWindow_PointerPressed;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// Undo the same changes when the page is no longer visible
|
||||
this.page.Unloaded += (sender, e) =>
|
||||
this.Page.Unloaded += (sender, e) =>
|
||||
{
|
||||
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated -= CoreDispatcher_AcceleratorKeyActivated;
|
||||
Window.Current.CoreWindow.PointerPressed -= this.CoreWindow_PointerPressed;
|
||||
#if WINDOWS_PHONE_APP
|
||||
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
|
||||
#else
|
||||
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated -=
|
||||
CoreDispatcher_AcceleratorKeyActivated;
|
||||
Window.Current.CoreWindow.PointerPressed -=
|
||||
this.CoreWindow_PointerPressed;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register this event on the current page to populate the page
|
||||
/// with content passed during navigation as well as any saved
|
||||
/// state provided when recreating a page from a prior session.
|
||||
/// </summary>
|
||||
public event LoadStateEventHandler LoadState;
|
||||
#region Navigation support
|
||||
|
||||
RelayCommand _goBackCommand;
|
||||
RelayCommand _goForwardCommand;
|
||||
|
||||
/// <summary>
|
||||
/// Register this event on the current page to preserve
|
||||
/// state associated with the current page in case the
|
||||
/// application is suspended or the page is discarded from
|
||||
/// the navigation cache.
|
||||
/// </summary>
|
||||
public event SaveStateEventHandler SaveState;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="RelayCommand"/> used to bind to the back Button's Command
|
||||
/// property for navigating to the most recent item in back navigation history, if a Frame
|
||||
/// <see cref="RelayCommand"/> used to bind to the back Button's Command property
|
||||
/// for navigating to the most recent item in back navigation history, if a Frame
|
||||
/// manages its own navigation history.
|
||||
/// <para>
|
||||
///
|
||||
/// The <see cref="RelayCommand"/> is set up to use the virtual method <see cref="GoBack"/>
|
||||
/// as the Execute Action and <see cref="CanGoBack"/> for CanExecute.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public RelayCommand GoBackCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.goBackCommand == null)
|
||||
if (_goBackCommand == null)
|
||||
{
|
||||
this.goBackCommand = new RelayCommand(
|
||||
_goBackCommand = new RelayCommand(
|
||||
() => this.GoBack(),
|
||||
() => this.CanGoBack());
|
||||
}
|
||||
return this.goBackCommand;
|
||||
return _goBackCommand;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.goBackCommand = value;
|
||||
_goBackCommand = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="RelayCommand"/> used for navigating to the most recent item in
|
||||
/// <see cref="RelayCommand"/> used for navigating to the most recent item in
|
||||
/// the forward navigation history, if a Frame manages its own navigation history.
|
||||
/// <para>
|
||||
///
|
||||
/// The <see cref="RelayCommand"/> is set up to use the virtual method <see cref="GoForward"/>
|
||||
/// as the Execute Action and <see cref="CanGoForward"/> for CanExecute.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public RelayCommand GoForwardCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.goForwardCommand == null)
|
||||
if (_goForwardCommand == null)
|
||||
{
|
||||
this.goForwardCommand = new RelayCommand(
|
||||
_goForwardCommand = new RelayCommand(
|
||||
() => this.GoForward(),
|
||||
() => this.CanGoForward());
|
||||
}
|
||||
return this.goForwardCommand;
|
||||
return _goForwardCommand;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current page
|
||||
/// </summary>
|
||||
private Frame Frame
|
||||
{
|
||||
get { return this.page.Frame; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtual method used by the <see cref="GoBackCommand"/> property
|
||||
/// to determine if the <see cref="Frame"/> can go back.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// True if the <see cref="Frame"/> has at least one entry
|
||||
/// true if the <see cref="Frame"/> has at least one entry
|
||||
/// in the back navigation history.
|
||||
/// </returns>
|
||||
public virtual bool CanGoBack()
|
||||
{
|
||||
return this.Frame != null && this.Frame.CanGoBack;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtual method used by the <see cref="GoForwardCommand"/> property
|
||||
/// to determine if the <see cref="Frame"/> can go forward.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// True if the <see cref="Frame"/> has at least one entry
|
||||
/// true if the <see cref="Frame"/> has at least one entry
|
||||
/// in the forward navigation history.
|
||||
/// </returns>
|
||||
public virtual bool CanGoForward()
|
||||
|
@ -246,80 +207,32 @@ namespace Places.Common
|
|||
/// </summary>
|
||||
public virtual void GoBack()
|
||||
{
|
||||
if (this.Frame != null && this.Frame.CanGoBack)
|
||||
{
|
||||
this.Frame.GoBack();
|
||||
}
|
||||
if (this.Frame != null && this.Frame.CanGoBack) this.Frame.GoBack();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtual method used by the <see cref="GoForwardCommand"/> property
|
||||
/// to invoke the <see cref="Windows.UI.Xaml.Controls.Frame.GoForward"/> method.
|
||||
/// </summary>
|
||||
public virtual void GoForward()
|
||||
{
|
||||
if (this.Frame != null && this.Frame.CanGoForward)
|
||||
{
|
||||
this.Frame.GoForward();
|
||||
}
|
||||
if (this.Frame != null && this.Frame.CanGoForward) this.Frame.GoForward();
|
||||
}
|
||||
|
||||
#if WINDOWS_PHONE_APP
|
||||
/// <summary>
|
||||
/// Invoked when this page is about to be displayed in a Frame.
|
||||
/// This method calls <see cref="LoadState"/>, where all page specific
|
||||
/// navigation and process lifetime management logic should be placed.
|
||||
/// Invoked when the hardware back button is pressed. For Windows Phone only.
|
||||
/// </summary>
|
||||
/// <param name="e">Event data that describes how this page was reached.
|
||||
/// This parameter is typically used to configure the page.</param>
|
||||
public void OnNavigatedTo(NavigationEventArgs e)
|
||||
/// <param name="sender">Instance that triggered the event.</param>
|
||||
/// <param name="e">Event data describing the conditions that led to the event.</param>
|
||||
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
|
||||
{
|
||||
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
|
||||
this.pageKey = "Page-" + this.Frame.BackStackDepth;
|
||||
if (e.NavigationMode == NavigationMode.New)
|
||||
if (this.GoBackCommand.CanExecute(null))
|
||||
{
|
||||
// Clear existing state for forward navigation when adding a new page to the
|
||||
// navigation stack
|
||||
var nextPageKey = this.pageKey;
|
||||
int nextPageIndex = this.Frame.BackStackDepth;
|
||||
while (frameState.Remove(nextPageKey))
|
||||
{
|
||||
nextPageIndex++;
|
||||
nextPageKey = "Page-" + nextPageIndex;
|
||||
}
|
||||
// Pass the navigation parameter to the new page
|
||||
if (this.LoadState != null)
|
||||
{
|
||||
this.LoadState(this, new LoadStateEventArgs(e.Parameter, null));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pass the navigation parameter and preserved page state to the page, using
|
||||
// the same strategy for loading suspended state and recreating pages discarded
|
||||
// from cache
|
||||
if (this.LoadState != null)
|
||||
{
|
||||
this.LoadState(this, new LoadStateEventArgs(e.Parameter, (Dictionary<string, object>)frameState[this.pageKey]));
|
||||
}
|
||||
e.Handled = true;
|
||||
this.GoBackCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page will no longer be displayed in a Frame.
|
||||
/// This method calls <see cref="SaveState"/>, where all page specific
|
||||
/// navigation and process lifetime management logic should be placed.
|
||||
/// </summary>
|
||||
public void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
|
||||
var pageState = new Dictionary<string, object>();
|
||||
if (this.SaveState != null)
|
||||
{
|
||||
this.SaveState(this, new SaveStateEventArgs(pageState));
|
||||
}
|
||||
frameState[this.pageKey] = pageState;
|
||||
}
|
||||
|
||||
#else
|
||||
/// <summary>
|
||||
/// Invoked on every keystroke, including system keys such as Alt key combinations, when
|
||||
/// this page is active and occupies the entire window. Used to detect keyboard navigation
|
||||
|
@ -327,9 +240,11 @@ namespace Places.Common
|
|||
/// </summary>
|
||||
/// <param name="sender">Instance that triggered the event.</param>
|
||||
/// <param name="e">Event data describing the conditions that led to the event.</param>
|
||||
private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs e)
|
||||
private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender,
|
||||
AcceleratorKeyEventArgs e)
|
||||
{
|
||||
var virtualKey = e.VirtualKey;
|
||||
|
||||
// Only investigate further when Left, Right, or the dedicated Previous or Next keys
|
||||
// are pressed
|
||||
if ((e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown ||
|
||||
|
@ -344,13 +259,16 @@ namespace Places.Common
|
|||
bool shiftKey = (coreWindow.GetKeyState(VirtualKey.Shift) & downState) == downState;
|
||||
bool noModifiers = !menuKey && !controlKey && !shiftKey;
|
||||
bool onlyAlt = menuKey && !controlKey && !shiftKey;
|
||||
if (((int)virtualKey == 166 && noModifiers) || (virtualKey == VirtualKey.Left && onlyAlt))
|
||||
|
||||
if (((int)virtualKey == 166 && noModifiers) ||
|
||||
(virtualKey == VirtualKey.Left && onlyAlt))
|
||||
{
|
||||
// When the previous key or Alt+Left are pressed navigate back
|
||||
e.Handled = true;
|
||||
this.GoBackCommand.Execute(null);
|
||||
}
|
||||
else if (((int)virtualKey == 167 && noModifiers) || (virtualKey == VirtualKey.Right && onlyAlt))
|
||||
else if (((int)virtualKey == 167 && noModifiers) ||
|
||||
(virtualKey == VirtualKey.Right && onlyAlt))
|
||||
{
|
||||
// When the next key or Alt+Right are pressed navigate forward
|
||||
e.Handled = true;
|
||||
|
@ -366,84 +284,171 @@ namespace Places.Common
|
|||
/// </summary>
|
||||
/// <param name="sender">Instance that triggered the event.</param>
|
||||
/// <param name="e">Event data describing the conditions that led to the event.</param>
|
||||
private void CoreWindow_PointerPressed(CoreWindow sender, PointerEventArgs e)
|
||||
private void CoreWindow_PointerPressed(CoreWindow sender,
|
||||
PointerEventArgs e)
|
||||
{
|
||||
var properties = e.CurrentPoint.Properties;
|
||||
|
||||
// Ignore button chords with the left, right, and middle buttons
|
||||
if (properties.IsLeftButtonPressed || properties.IsRightButtonPressed || properties.IsMiddleButtonPressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (properties.IsLeftButtonPressed || properties.IsRightButtonPressed ||
|
||||
properties.IsMiddleButtonPressed) return;
|
||||
|
||||
// If back or foward are pressed (but not both) navigate appropriately
|
||||
bool backPressed = properties.IsXButton1Pressed;
|
||||
bool forwardPressed = properties.IsXButton2Pressed;
|
||||
if (backPressed ^ forwardPressed)
|
||||
{
|
||||
e.Handled = true;
|
||||
if (backPressed)
|
||||
if (backPressed) this.GoBackCommand.Execute(null);
|
||||
if (forwardPressed) this.GoForwardCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Process lifetime management
|
||||
|
||||
private String _pageKey;
|
||||
|
||||
/// <summary>
|
||||
/// Register this event on the current page to populate the page
|
||||
/// with content passed during navigation as well as any saved
|
||||
/// state provided when recreating a page from a prior session.
|
||||
/// </summary>
|
||||
public event LoadStateEventHandler LoadState;
|
||||
/// <summary>
|
||||
/// Register this event on the current page to preserve
|
||||
/// state associated with the current page in case the
|
||||
/// application is suspended or the page is discarded from
|
||||
/// the navigaqtion cache.
|
||||
/// </summary>
|
||||
public event SaveStateEventHandler SaveState;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page is about to be displayed in a Frame.
|
||||
/// This method calls <see cref="LoadState"/>, where all page specific
|
||||
/// navigation and process lifetime management logic should be placed.
|
||||
/// </summary>
|
||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
||||
/// property provides the group to be displayed.</param>
|
||||
public void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
|
||||
this._pageKey = "Page-" + this.Frame.BackStackDepth;
|
||||
|
||||
if (e.NavigationMode == NavigationMode.New)
|
||||
{
|
||||
// Clear existing state for forward navigation when adding a new page to the
|
||||
// navigation stackOnLaunched
|
||||
var nextPageKey = this._pageKey;
|
||||
int nextPageIndex = this.Frame.BackStackDepth;
|
||||
while (frameState.Remove(nextPageKey))
|
||||
{
|
||||
this.GoBackCommand.Execute(null);
|
||||
nextPageIndex++;
|
||||
nextPageKey = "Page-" + nextPageIndex;
|
||||
}
|
||||
if (forwardPressed)
|
||||
|
||||
// Pass the navigation parameter to the new page
|
||||
if (this.LoadState != null)
|
||||
{
|
||||
this.GoForwardCommand.Execute(null);
|
||||
this.LoadState(this, new LoadStateEventArgs(e.Parameter, null));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pass the navigation parameter and preserved page state to the page, using
|
||||
// the same strategy for loading suspended state and recreating pages discarded
|
||||
// from cache
|
||||
if (this.LoadState != null)
|
||||
{
|
||||
this.LoadState(this, new LoadStateEventArgs(e.Parameter, (Dictionary<String, Object>)frameState[this._pageKey]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page will no longer be displayed in a Frame.
|
||||
/// This method calls <see cref="SaveState"/>, where all page specific
|
||||
/// navigation and process lifetime management logic should be placed.
|
||||
/// </summary>
|
||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
||||
/// property provides the group to be displayed.</param>
|
||||
public void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
|
||||
var pageState = new Dictionary<String, Object>();
|
||||
if (this.SaveState != null)
|
||||
{
|
||||
this.SaveState(this, new SaveStateEventArgs(pageState));
|
||||
}
|
||||
frameState[_pageKey] = pageState;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the event data required when a page attempts to load state.
|
||||
/// Represents the method that will handle the <see cref="NavigationHelper.LoadState"/>event
|
||||
/// </summary>
|
||||
public delegate void LoadStateEventHandler(object sender, LoadStateEventArgs e);
|
||||
/// <summary>
|
||||
/// Represents the method that will handle the <see cref="NavigationHelper.SaveState"/>event
|
||||
/// </summary>
|
||||
public delegate void SaveStateEventHandler(object sender, SaveStateEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// Class used to hold the event data required when a page attempts to load state.
|
||||
/// </summary>
|
||||
public class LoadStateEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The parameter value passed to <see cref="Frame.Navigate(Type, Object)"/>
|
||||
/// when this page was initially requested.
|
||||
/// </summary>
|
||||
public Object NavigationParameter { get; private set; }
|
||||
/// <summary>
|
||||
/// A dictionary of state preserved by this page during an earlier
|
||||
/// session. This will be null the first time a page is visited.
|
||||
/// </summary>
|
||||
public Dictionary<string, Object> PageState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LoadStateEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="navigationParameter">
|
||||
/// The parameter value passed to <see cref="Frame.Navigate(Type, Object)"/>
|
||||
/// The parameter value passed to <see cref="Frame.Navigate(Type, Object)"/>
|
||||
/// when this page was initially requested.
|
||||
/// </param>
|
||||
/// <param name="pageState">
|
||||
/// A dictionary of state preserved by this page during an earlier
|
||||
/// session. This will be null the first time a page is visited.
|
||||
/// session. This will be null the first time a page is visited.
|
||||
/// </param>
|
||||
public LoadStateEventArgs(object navigationParameter, Dictionary<string, object> pageState): base()
|
||||
public LoadStateEventArgs(Object navigationParameter, Dictionary<string, Object> pageState)
|
||||
: base()
|
||||
{
|
||||
this.NavigationParameter = navigationParameter;
|
||||
this.PageState = pageState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter value passed to <see cref="Frame.Navigate(Type, Object)"/>
|
||||
/// when this page was initially requested.
|
||||
/// </summary>
|
||||
public object NavigationParameter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary of state preserved by this page during an earlier
|
||||
/// session. This will be null the first time a page is visited.
|
||||
/// </summary>
|
||||
public Dictionary<string, object> PageState { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the event data required when a page attempts to save state.
|
||||
/// Class used to hold the event data required when a page attempts to save state.
|
||||
/// </summary>
|
||||
public class SaveStateEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty dictionary to be populated with serializable state.
|
||||
/// </summary>
|
||||
public Dictionary<string, Object> PageState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SaveStateEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
|
||||
public SaveStateEventArgs(Dictionary<string, object> pageState): base()
|
||||
public SaveStateEventArgs(Dictionary<string, Object> pageState)
|
||||
: base()
|
||||
{
|
||||
this.PageState = pageState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an empty dictionary to be populated with serializable state.
|
||||
/// </summary>
|
||||
public Dictionary<string, object> PageState { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
Двоичные данные
Places/Help/LumiaSensorCoreSDK.chm
Двоичные данные
Places/Help/LumiaSensorCoreSDK.chm
Двоичный файл не отображается.
Двоичные данные
Places/Help/SensorCoreSDK.chw
Двоичные данные
Places/Help/SensorCoreSDK.chw
Двоичный файл не отображается.
|
@ -0,0 +1,125 @@
|
|||
<Page
|
||||
x:Class="Places.HistoryPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Places"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="#A4C400">
|
||||
<!-- Set properties of ListBox control -->
|
||||
<Page.Resources>
|
||||
<Style TargetType="ListBoxItem" x:Key="ItemContainerStyle">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="FontSize" Value="20" />
|
||||
<Setter Property="Margin" Value="12,0,12,0" />
|
||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBoxItem">
|
||||
<Border x:Name="LayoutRoot"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver"/>
|
||||
<VisualState x:Name="Disabled"/>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="PressedBackground"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListBoxItemPressedForegroundThemeBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<Grid x:Name="InnerGrid"
|
||||
Background="Transparent">
|
||||
<Rectangle x:Name="PressedBackground"
|
||||
Fill="{ThemeResource ListBoxItemPressedBackgroundThemeBrush}"
|
||||
Opacity="0" />
|
||||
<ContentPresenter x:Name="ContentPresenter"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Margin="{TemplateBinding Padding}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Page.Resources>
|
||||
<Grid x:Name ="LayoutRoot">
|
||||
<Grid.ChildrenTransitions>
|
||||
<TransitionCollection>
|
||||
<EntranceThemeTransition/>
|
||||
</TransitionCollection>
|
||||
</Grid.ChildrenTransitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<!-- TitlePanel -->
|
||||
<StackPanel Grid.Row="0" Margin="24,17,0,28">
|
||||
<TextBlock x:Uid="Application"
|
||||
Text=""
|
||||
Style="{ThemeResource TitleTextBlockStyle}"
|
||||
Typography.Capitals="SmallCaps"
|
||||
Foreground="Black"/>
|
||||
<TextBlock x:Uid="HistoryPage"
|
||||
Text=""
|
||||
Margin="0,12,0,0"
|
||||
FontSize="60"
|
||||
Style="{ThemeResource HeaderTextBlockStyle}"
|
||||
Foreground="Black"/>
|
||||
</StackPanel>
|
||||
<!-- ListBox for places history -->
|
||||
<ScrollViewer Grid.Row="1">
|
||||
<StackPanel x:Name="ContentPanel" Margin="12,0,12,0">
|
||||
<ListBox x:Name="PlacesSummary"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||
Background="Transparent"
|
||||
ItemContainerStyle="{StaticResource ItemContainerStyle}"
|
||||
ItemsSource ="{Binding}" >
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="200"/>
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="60"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0" Source="{Binding ImagePath}"/>
|
||||
<TextBlock Text="{Binding Text}"
|
||||
TextWrapping="Wrap"
|
||||
HorizontalAlignment="Center"
|
||||
Padding="3"
|
||||
Grid.Column="1"/>
|
||||
</Grid>
|
||||
<Rectangle Grid.Row="1"
|
||||
Fill="LightGray"
|
||||
Height="3"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Page>
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
using System.Collections.Generic;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using Places.Utilities;
|
||||
|
||||
/// <summary>
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkID=390556
|
||||
/// </summary>
|
||||
namespace Places
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class HistoryPage : Page
|
||||
{
|
||||
#region Private members
|
||||
/// <summary>
|
||||
/// List with place history
|
||||
/// </summary>
|
||||
private List<string> _myData;
|
||||
|
||||
/// <summary>
|
||||
/// Image Path for the place type image
|
||||
/// </summary>
|
||||
private string _imagePath;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public HistoryPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Loaded += HistoryPage_Loaded;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called when page loading is done
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">Contains state information and event data associated with a routed event.</param>
|
||||
void HistoryPage_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Find the Image control inside the ListBox Data Template
|
||||
CreatePlacesHistory();
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
// Get the list of history data passed from previous page
|
||||
_myData = e.Parameter as List<string>;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add places to listbox
|
||||
/// </summary>
|
||||
/// <param name="targetElement"></param>
|
||||
private void CreatePlacesHistory()
|
||||
{
|
||||
var places = new List<PlaceHistory>();
|
||||
// Set image source for each type of place
|
||||
foreach (var p in _myData)
|
||||
{
|
||||
if (p.Contains("Home"))
|
||||
{
|
||||
_imagePath = "ms-appx:///Assets/show-home.png";
|
||||
}
|
||||
if (p.Contains("Work"))
|
||||
{
|
||||
_imagePath = "ms-appx:///Assets/show-work.png";
|
||||
}
|
||||
if (p.Contains("Frequent"))
|
||||
{
|
||||
_imagePath = "ms-appx:///Assets/show-current-location.png";
|
||||
}
|
||||
if (p.Contains("Known"))
|
||||
{
|
||||
_imagePath = "ms-appx:///Assets/show-current-location.png";
|
||||
}
|
||||
if (p.Contains("Frequent"))
|
||||
{
|
||||
_imagePath = "ms-appx:///Assets/show-next-favorite.png";
|
||||
}
|
||||
PlaceHistory placeHistory = new PlaceHistory() { Text = p, ImagePath = _imagePath };
|
||||
places.Add(placeHistory);
|
||||
}
|
||||
this.PlacesSummary.DataContext = places;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@
|
|||
x:Class="Places.MapPage"
|
||||
mc:Ignorable="d"
|
||||
Background="#A4C400">
|
||||
<Grid x:Name="LayoutRoot">
|
||||
<Page.Resources>
|
||||
<CollectionViewSource x:Name="listSource"/>
|
||||
</Page.Resources>
|
||||
<Grid x:Name="LayoutRoot">
|
||||
<Grid.ChildrenTransitions>
|
||||
<TransitionCollection>
|
||||
<EntranceThemeTransition/>
|
||||
|
@ -26,7 +29,8 @@
|
|||
<!--Content should be placed within the following grid-->
|
||||
<Grid Grid.Row="1" x:Name="ContentRoot" >
|
||||
<maps:MapControl x:Name="PlacesMap" Margin="0,0,0,0"
|
||||
MapTapped="OnTapped" ZoomLevel="12"/>
|
||||
ZoomLevel="13"/>
|
||||
<TextBlock x:Name="FilterTime" FontSize="24" TextAlignment="Right" Width="480" Height="30" HorizontalAlignment="Right" VerticalAlignment="Top" Foreground="#7F000000" Margin="5,5"/>
|
||||
<SymbolIcon x:Name="FullScreeButton" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,15,31" Symbol="FullScreen" Tapped="FullScreeButton_OnTapped" RenderTransformOrigin="0.5,0.5" Grid.Column="1">
|
||||
<SymbolIcon.RenderTransform>
|
||||
<CompositeTransform ScaleX="2" ScaleY="2"/>
|
||||
|
@ -58,6 +62,18 @@
|
|||
</AppBarButton>
|
||||
<CommandBar.SecondaryCommands>
|
||||
<AppBarButton x:Uid="AboutButton" x:Name="AboutButton" Label="" Click="OnAboutClicked"/>
|
||||
<AppBarButton x:Uid="HistoryButton" x:Name="HistoryButton" Label="" Click="OnPollHistory"/>
|
||||
<AppBarButton x:Uid="FilterButton" x:Name="FilterButton" Label="" Click="SelectButton_Click">
|
||||
<MenuFlyout x:Name="menuFlyout">
|
||||
<MenuFlyout.MenuFlyoutPresenterStyle>
|
||||
<Style TargetType="MenuFlyoutPresenter">
|
||||
<Setter Property="BorderBrush" Value="Blue"/>
|
||||
<Setter Property="BorderThickness" Value="5"/>
|
||||
</Style>
|
||||
</MenuFlyout.MenuFlyoutPresenterStyle>
|
||||
<MenuFlyoutItem x:Name="flyoutItem" Background="Black" Click="flyoutItem_Click" Margin="0,0,20.833,0"/>
|
||||
</MenuFlyout>
|
||||
</AppBarButton>
|
||||
</CommandBar.SecondaryCommands>
|
||||
</CommandBar>
|
||||
</Page.BottomAppBar>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -39,6 +40,9 @@ using Windows.Devices.Geolocation.Geofencing;
|
|||
using System.Collections.Generic;
|
||||
using Monitor = Lumia.Sense.PlaceMonitor;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Storage.Streams;
|
||||
using System.Globalization;
|
||||
using Windows.Foundation;
|
||||
|
||||
/// <summary>
|
||||
/// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkID=390556
|
||||
|
@ -57,6 +61,11 @@ namespace Places
|
|||
/// </summary>
|
||||
private readonly Color PlacesColorHome = Color.FromArgb(AlphaLevelOfPlacesCircle, 31, 127, 31);
|
||||
|
||||
/// <summary>
|
||||
/// holds all the pushpins in the map
|
||||
/// </summary>
|
||||
List<PushPin> pins = null;
|
||||
|
||||
/// <summary>
|
||||
/// Work color mapping
|
||||
/// </summary>
|
||||
|
@ -115,16 +124,31 @@ namespace Places
|
|||
/// </summary>
|
||||
private Places.App _app = Application.Current as Places.App;
|
||||
|
||||
/// <summary>
|
||||
/// List of places
|
||||
/// </summary>
|
||||
private List<string> resultStr = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Place monitor instance
|
||||
/// </summary>
|
||||
private Monitor _placeMonitor;
|
||||
|
||||
/// <summary>
|
||||
/// check to see launching finished or not
|
||||
/// </summary>
|
||||
private bool iLaunched = false;
|
||||
|
||||
/// <summary>
|
||||
/// Geolocator instance
|
||||
/// </summary>
|
||||
private Geolocator _geoLocator;
|
||||
|
||||
/// <summary>
|
||||
/// List of activities for a place
|
||||
/// </summary>
|
||||
List<Activity> activitiesToShow = new List<Activity>();
|
||||
|
||||
/// <summary>
|
||||
/// CancellationToken Source instance
|
||||
/// </summary>
|
||||
|
@ -149,81 +173,122 @@ namespace Places
|
|||
/// <summary>
|
||||
/// Initialize SensorCore and find the current position
|
||||
/// </summary>
|
||||
private async void InitCore()
|
||||
private async Task InitCore()
|
||||
{
|
||||
if (_placeMonitor == null)
|
||||
try
|
||||
{
|
||||
// This is not implemented by the simulator, uncomment for the PlaceMonitor
|
||||
if (await Monitor.IsSupportedAsync())
|
||||
// Following code assumes that device has new software(SensorCoreSDK1.1 based)
|
||||
if (!(await PlaceMonitor.IsSupportedAsync()))
|
||||
{
|
||||
// Init SensorCore
|
||||
if (await CallSensorcoreApiAsync(async () => { _placeMonitor = await Monitor.GetDefaultAsync(); }))
|
||||
{
|
||||
Debug.WriteLine("PlaceMonitor initialized.");
|
||||
// Update list of known places
|
||||
await UpdateKnownPlacesAsync();
|
||||
HomeButton.IsEnabled = true;
|
||||
WorkButton.IsEnabled = true;
|
||||
FrequentButton.IsEnabled = true;
|
||||
CurrentButton.IsEnabled = true;
|
||||
}
|
||||
else return;
|
||||
MessageDialog dlg = new MessageDialog("Unfortunately this device does not support viewing visited places");
|
||||
await dlg.ShowAsync();
|
||||
Application.Current.Exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
var loader = new ResourceLoader();
|
||||
MessageDialog dialog = new MessageDialog(loader.GetString("NoMotionDataSupport/Text"), loader.GetString("Information/Text"));
|
||||
dialog.Commands.Add(new UICommand(loader.GetString("OkButton/Text")));
|
||||
await dialog.ShowAsync();
|
||||
new System.Threading.ManualResetEvent(false).WaitOne(500);
|
||||
Application.Current.Exit();
|
||||
}
|
||||
// Init Geolocator
|
||||
try
|
||||
{
|
||||
_accessInfo = DeviceAccessInformation.CreateFromDeviceClass(DeviceClass.Location);
|
||||
_accessInfo.AccessChanged += OnAccessChanged;
|
||||
// Get a geolocator object
|
||||
_geoLocator = new Geolocator();
|
||||
// Get cancellation token
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
CancellationToken token = _cancellationTokenSource.Token;
|
||||
Geoposition geoposition = await _geoLocator.GetGeopositionAsync().AsTask(token);
|
||||
_currentLocation = new Geopoint(new BasicGeoposition()
|
||||
uint apiSet = await SenseHelper.GetSupportedApiSetAsync();
|
||||
MotionDataSettings settings = await SenseHelper.GetSettingsAsync();
|
||||
if (!settings.LocationEnabled)
|
||||
{
|
||||
Latitude = geoposition.Coordinate.Point.Position.Latitude,
|
||||
Longitude = geoposition.Coordinate.Point.Position.Longitude
|
||||
});
|
||||
// Focus on the current location
|
||||
OnCurrentClicked(this, null);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
if (DeviceAccessStatus.DeniedByUser == _accessInfo.CurrentStatus)
|
||||
{
|
||||
Debug.WriteLine("Location has been disabled by the user. Enable access through the settings charm.");
|
||||
MessageDialog dlg = new MessageDialog("In order to collect and view visited places you need to enable location in system settings. Do you want to open settings now? if no, applicatoin will exit", "Information");
|
||||
dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(async (cmd) => await SenseHelper.LaunchLocationSettingsAsync())));
|
||||
dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler((cmd) => { Application.Current.Exit(); })));
|
||||
await dlg.ShowAsync();
|
||||
}
|
||||
else if (DeviceAccessStatus.DeniedBySystem == _accessInfo.CurrentStatus)
|
||||
if (!settings.PlacesVisited)
|
||||
{
|
||||
Debug.WriteLine("Location has been disabled by the system. The administrator of the device must enable location access through the location control panel.");
|
||||
}
|
||||
else if (DeviceAccessStatus.Unspecified == _accessInfo.CurrentStatus)
|
||||
{
|
||||
Debug.WriteLine("Location has been disabled by unspecified source. The administrator of the device may need to enable location access through the location control panel, then enable access through the settings charm.");
|
||||
MessageDialog dlg = null;
|
||||
if (settings.Version < 2)
|
||||
{
|
||||
//device which has old motion data settings.
|
||||
//this is equal to motion data settings on/off in old system settings(SDK1.0 based)
|
||||
dlg = new MessageDialog("In order to collect and view visited places you need to enable Motion data in Motion data settings. Do you want to open settings now? if no, application will exit", "Information");
|
||||
}
|
||||
else
|
||||
{
|
||||
dlg = new MessageDialog("In order to collect and view visited places you need to 'enable Places visited' and 'DataQuality to detailed' in Motion data settings. Do you want to open settings now? if no, application will exit", "Information");
|
||||
}
|
||||
dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(async (cmd) => await SenseHelper.LaunchSenseSettingsAsync())));
|
||||
dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler((cmd) =>{ Application.Current.Exit(); })));
|
||||
await dlg.ShowAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
// This is not implemented by the simulator, uncomment for the PlaceMonitor
|
||||
if (_placeMonitor == null)
|
||||
{
|
||||
// Init SensorCore
|
||||
if (await CallSensorcoreApiAsync(async () => { _placeMonitor = await Monitor.GetDefaultAsync(); }))
|
||||
{
|
||||
if ((uint)ex.HResult == 0x80004004)
|
||||
{
|
||||
// The application does not have the right capability or the location master switch is off
|
||||
Debug.WriteLine("location is disabled in phone settings.");
|
||||
}
|
||||
Debug.WriteLine("PlaceMonitor initialized.");
|
||||
// Update list of known places
|
||||
await UpdateKnownPlacesAsync();
|
||||
HomeButton.IsEnabled = true;
|
||||
WorkButton.IsEnabled = true;
|
||||
FrequentButton.IsEnabled = true;
|
||||
CurrentButton.IsEnabled = true;
|
||||
await ActivityReader.Instance().Initialize();
|
||||
resultStr = await GetPlacesHistory();
|
||||
}
|
||||
finally
|
||||
else return;
|
||||
}
|
||||
else
|
||||
{
|
||||
var loader = new ResourceLoader();
|
||||
MessageDialog dialog = new MessageDialog(loader.GetString("NoMotionDataSupport/Text"), loader.GetString("Information/Text"));
|
||||
dialog.Commands.Add(new UICommand(loader.GetString("OkButton/Text")));
|
||||
await dialog.ShowAsync();
|
||||
new System.Threading.ManualResetEvent(false).WaitOne(500);
|
||||
Application.Current.Exit();
|
||||
}
|
||||
// Init Geolocator
|
||||
try
|
||||
{
|
||||
_accessInfo = DeviceAccessInformation.CreateFromDeviceClass(DeviceClass.Location);
|
||||
_accessInfo.AccessChanged += OnAccessChanged;
|
||||
// Get a geolocator object
|
||||
_geoLocator = new Geolocator();
|
||||
// Get cancellation token
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
CancellationToken token = _cancellationTokenSource.Token;
|
||||
Geoposition geoposition = await _geoLocator.GetGeopositionAsync().AsTask(token);
|
||||
_currentLocation = new Geopoint(new BasicGeoposition()
|
||||
{
|
||||
_cancellationTokenSource = null;
|
||||
Latitude = geoposition.Coordinate.Point.Position.Latitude,
|
||||
Longitude = geoposition.Coordinate.Point.Position.Longitude
|
||||
});
|
||||
// Focus on the current location
|
||||
OnCurrentClicked(this, null);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
if (DeviceAccessStatus.DeniedByUser == _accessInfo.CurrentStatus)
|
||||
{
|
||||
Debug.WriteLine("Location has been disabled by the user. Enable access through the settings charm.");
|
||||
}
|
||||
else if (DeviceAccessStatus.DeniedBySystem == _accessInfo.CurrentStatus)
|
||||
{
|
||||
Debug.WriteLine("Location has been disabled by the system. The administrator of the device must enable location access through the location control panel.");
|
||||
}
|
||||
else if (DeviceAccessStatus.Unspecified == _accessInfo.CurrentStatus)
|
||||
{
|
||||
Debug.WriteLine("Location has been disabled by unspecified source. The administrator of the device may need to enable location access through the location control panel, then enable access through the settings charm.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if ((uint)ex.HResult == 0x80004004)
|
||||
{
|
||||
// The application does not have the right capability or the location master switch is off
|
||||
Debug.WriteLine("location is disabled in phone settings.");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_cancellationTokenSource = null;
|
||||
}
|
||||
// Activate and deactivate the SensorCore when the visibility of the app changes
|
||||
Window.Current.VisibilityChanged += async (oo, ee) =>
|
||||
|
@ -284,7 +349,7 @@ namespace Places
|
|||
{
|
||||
if (GeofenceMonitor.Current.Geofences.All(v => v.Id != fenceKey))
|
||||
{
|
||||
var position = new BasicGeoposition {Latitude = latitude, Longitude = longitude, Altitude = 0.0};
|
||||
var position = new BasicGeoposition { Latitude = latitude, Longitude = longitude, Altitude = 0.0 };
|
||||
CreateCircle(position, radius, fenceColor);
|
||||
// The geofence is a circular region
|
||||
var geocircle = new Geocircle(position, radius);
|
||||
|
@ -381,19 +446,19 @@ namespace Places
|
|||
/// <returns>List of points</returns>
|
||||
public static List<BasicGeoposition> CreateGeoCircle(BasicGeoposition center, double radiusValue, int numberOfPoints = 360)
|
||||
{
|
||||
var locations = new List<BasicGeoposition>();
|
||||
var radius = radiusValue / 1000;
|
||||
double latCenter = center.Latitude * DegreesToRadian;
|
||||
double lonCenter = center.Longitude * DegreesToRadian;
|
||||
double distance = radius / MEAN_RADIUS;
|
||||
for (int i = 0; i <= numberOfPoints; i++)
|
||||
{
|
||||
double angle = i * DegreesToRadian;
|
||||
var latitude = Math.Asin(Math.Sin(latCenter) * Math.Cos(distance) + Math.Cos(latCenter) * Math.Sin(distance) * Math.Cos(angle));
|
||||
var longitude = ((lonCenter + Math.Atan2(Math.Sin(angle) * Math.Sin(distance) * Math.Cos(latCenter), Math.Cos(distance) - Math.Sin(latCenter) * Math.Sin(latitude)) + Math.PI) % (Math.PI * 2)) - Math.PI;
|
||||
locations.Add(new BasicGeoposition { Latitude = latitude * RadianToDegrees, Longitude = longitude * RadianToDegrees });
|
||||
}
|
||||
return locations;
|
||||
var locations = new List<BasicGeoposition>();
|
||||
var radius = radiusValue / 1000;
|
||||
double latCenter = center.Latitude * DegreesToRadian;
|
||||
double lonCenter = center.Longitude * DegreesToRadian;
|
||||
double distance = radius / MEAN_RADIUS;
|
||||
for (int i = 0; i <= numberOfPoints; i++)
|
||||
{
|
||||
double angle = i * DegreesToRadian;
|
||||
var latitude = Math.Asin(Math.Sin(latCenter) * Math.Cos(distance) + Math.Cos(latCenter) * Math.Sin(distance) * Math.Cos(angle));
|
||||
var longitude = ((lonCenter + Math.Atan2(Math.Sin(angle) * Math.Sin(distance) * Math.Cos(latCenter), Math.Cos(distance) - Math.Sin(latCenter) * Math.Sin(latitude)) + Math.PI) % (Math.PI * 2)) - Math.PI;
|
||||
locations.Add(new BasicGeoposition { Latitude = latitude * RadianToDegrees, Longitude = longitude * RadianToDegrees });
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -405,19 +470,41 @@ namespace Places
|
|||
if (_placeMonitor != null)
|
||||
{
|
||||
_app.Places = null;
|
||||
PlacesMap.MapElements.Clear();
|
||||
if (await CallSensorcoreApiAsync(async () => { _app.Places = await _placeMonitor.GetKnownPlacesAsync();}))
|
||||
{
|
||||
if (_app.Places.Count > 0)
|
||||
PlacesMap.MapElements.Clear();
|
||||
PlacesMap.Children.Clear();
|
||||
if (await CallSensorcoreApiAsync(async () =>
|
||||
{ // Get selected day places, else all places
|
||||
if (_selectedDay != null && !_selectedDay.Name.Equals("All", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("GetPlace: " + _selectedDay.Name);
|
||||
_app.Places = await _placeMonitor.GetPlaceHistoryAsync(_selectedDay.Day, TimeSpan.FromHours(24));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("Places: Get all known places");
|
||||
_app.Places = await _placeMonitor.GetKnownPlacesAsync();
|
||||
}
|
||||
}))
|
||||
{
|
||||
// Make sure that there were Places for the timespan
|
||||
if (_app.Places != null && _app.Places.Count > 0)
|
||||
{
|
||||
PlacesMap.Children.Clear();
|
||||
if (pins != null)
|
||||
{
|
||||
pins.Clear();
|
||||
pins = null;
|
||||
}
|
||||
pins = new List<PushPin>();
|
||||
int i = 0;
|
||||
foreach (var p in _app.Places)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("Place {0} radius {1} Latitude {2} Longitude {3} ", p.Kind, p.Radius, p.Position.Latitude, p.Position.Longitude);
|
||||
var mapIcon = new MapIcon();
|
||||
MapExtensions.SetValue(mapIcon, p);
|
||||
mapIcon.NormalizedAnchorPoint = new Windows.Foundation.Point(0.5, 0.5);
|
||||
mapIcon.Location = new Geopoint(p.Position);
|
||||
mapIcon.Title = p.Kind.ToString();
|
||||
System.Diagnostics.Debug.WriteLine("Place {0} radius {1} Latitude {2} Longitude {3} Total visit count {4} Total length of stay {5} Length of stay {6} Kind {7} ", p.Kind, p.Radius, p.Position.Latitude, p.Position.Longitude, p.TotalVisitCount, p.TotalLengthOfStay, p.LengthOfStay, p.Kind);
|
||||
pins.Add(new PushPin(p, p.Kind.ToString()));
|
||||
MapControl.SetLocation(pins[i], new Geopoint(p.Position));
|
||||
MapControl.SetNormalizedAnchorPoint(pins[i], new Point(0.15, 1));
|
||||
PlacesMap.Children.Add(pins[i]);
|
||||
i = i + 1;
|
||||
Color placesColor;
|
||||
//Set for each type of a place a certain color and set custom image for the MapIcon
|
||||
switch (p.Kind)
|
||||
|
@ -438,8 +525,6 @@ namespace Places
|
|||
placesColor = PlacesColorUnknown;
|
||||
break;
|
||||
}
|
||||
// Use MapElements collection to add a custom image, text and location to MapIcon
|
||||
PlacesMap.MapElements.Add(mapIcon);
|
||||
CreateGeofence(p.Id.ToString(), p.Position.Latitude, p.Position.Longitude, p.Radius, placesColor);
|
||||
}
|
||||
}
|
||||
|
@ -453,7 +538,7 @@ namespace Places
|
|||
/// </summary>
|
||||
/// <param name="action">The function delegate to execute asynchronously when one task in the tasks completes.</param>
|
||||
/// <returns><c>true</c> if call was successful, <c>false</c> otherwise</returns>
|
||||
private async Task<bool> CallSensorcoreApiAsync(Func<Task> action)
|
||||
public async Task<bool> CallSensorcoreApiAsync(Func<Task> action)
|
||||
{
|
||||
Exception failure = null;
|
||||
try
|
||||
|
@ -475,9 +560,13 @@ namespace Places
|
|||
this.Frame.Navigate(typeof(ActivateSensorCore));
|
||||
}
|
||||
return false;
|
||||
case SenseError.GeneralFailure:
|
||||
return false;
|
||||
case SenseError.IncompatibleSDK:
|
||||
MessageDialog dialog2 = new MessageDialog("This application has become outdated. Please update to the latest version.", "Information");
|
||||
await dialog2.ShowAsync();
|
||||
return false;
|
||||
default:
|
||||
MessageDialog dialog = new MessageDialog("Failure: " + SenseHelper.GetSenseError(failure.HResult) + " while initializing Motion data. Application will exit.", "");
|
||||
await dialog.ShowAsync();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -505,5 +594,73 @@ namespace Places
|
|||
FullScreeButton.Symbol = Symbol.FullScreen;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the places history
|
||||
/// </summary>
|
||||
/// <returns>String of all places history</returns>
|
||||
private async Task<List<string>> GetPlacesHistory()
|
||||
{
|
||||
IList<string> resultStrFinal = new List<string>();
|
||||
IList<Place> result = null;
|
||||
if (_placeMonitor != null)
|
||||
{
|
||||
// Returns time ordered list of places visited during given time period
|
||||
await CallSensorcoreApiAsync(async () =>
|
||||
{
|
||||
result = await _placeMonitor.GetPlaceHistoryAsync(DateTime.Today - TimeSpan.FromDays(10), TimeSpan.FromDays(10));
|
||||
});
|
||||
// Returns list of activies occured during given time period
|
||||
await CallSensorcoreApiAsync(async () =>
|
||||
{
|
||||
ActivityReader.Instance().History = await ActivityReader.Instance().ActivityMonitorProperty.GetActivityHistoryAsync(DateTime.Today - TimeSpan.FromDays(10), TimeSpan.FromDays(10));
|
||||
});
|
||||
if (result != null)
|
||||
{
|
||||
IEnumerable<Place> reverse = result.AsEnumerable().Reverse();
|
||||
for (int i = 1; i < reverse.Count(); i++)
|
||||
{
|
||||
activitiesToShow.Clear();
|
||||
for (int j = 1; j < ActivityReader.Instance().History.Count; j++)
|
||||
{
|
||||
// Compare time of entry to the last location and the current location with the activity timestamp
|
||||
// Retrieve the activities in a list
|
||||
if ((ActivityReader.Instance().History.ElementAt(j).Timestamp.ToLocalTime() >= reverse.ElementAt(i - 1).Timestamp.ToLocalTime()) && (ActivityReader.Instance().History.ElementAt(j).Timestamp.ToLocalTime() < reverse.ElementAt(i).Timestamp.ToLocalTime()))
|
||||
{
|
||||
if (!activitiesToShow.Contains(ActivityReader.Instance().History.ElementAt(j).Mode))
|
||||
{
|
||||
//Add the activity to the list
|
||||
activitiesToShow.Add(ActivityReader.Instance().History.ElementAt(j).Mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
string time = reverse.ElementAt(i).Timestamp.ToString("MMM dd yyyy HH:mm:ss", CultureInfo.InvariantCulture);
|
||||
var resultStr = "Place : " + reverse.ElementAt(i).Kind.ToString() + "\nTimestamp : " + time + "\nLenght Of Stay : " + reverse.ElementAt(i).LengthOfStay.ToString() + "\nTotal Lenght Of Stay : " + reverse.ElementAt(i).TotalLengthOfStay.ToString() + "\nTotal Visit Count : " + reverse.ElementAt(i).TotalVisitCount.ToString() + DisplayMembers(activitiesToShow);
|
||||
resultStrFinal.Add(resultStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Returns a list with details of the places history
|
||||
return resultStrFinal.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display activities for given list
|
||||
/// </summary>
|
||||
/// <param name="activities">List of activities</param>
|
||||
/// <returns>String item</returns>
|
||||
public string DisplayMembers(List<Activity> activities)
|
||||
{
|
||||
string displayActivities = string.Empty;
|
||||
if (activities.Count != 0)
|
||||
{
|
||||
displayActivities = "\nActivities: " + string.Join(", ", activities.ToList());
|
||||
}
|
||||
else
|
||||
{
|
||||
displayActivities = "\nActivities: Idle";
|
||||
}
|
||||
return displayActivities;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -31,6 +32,10 @@ using Windows.UI.Xaml.Controls.Maps;
|
|||
using Windows.UI.Xaml.Navigation;
|
||||
using Lumia.Sense;
|
||||
using Places.Common;
|
||||
using System.Collections.Generic;
|
||||
using Windows.Globalization;
|
||||
using Places.Utilities;
|
||||
using System.Threading;
|
||||
|
||||
/// <summary>
|
||||
/// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkID=390556
|
||||
|
@ -49,6 +54,11 @@ namespace Places
|
|||
/// </summary>
|
||||
private NavigationHelper _navigationHelper;
|
||||
|
||||
/// <summary>
|
||||
/// Map Page instance
|
||||
/// </summary>
|
||||
public static MapPage _instanceMap;
|
||||
|
||||
/// <summary>
|
||||
/// View model instance
|
||||
/// This can be changed to a strongly typed view model
|
||||
|
@ -64,6 +74,16 @@ namespace Places
|
|||
/// Constructs a new ResourceLoader object
|
||||
/// </summary>
|
||||
private ResourceLoader _resourceLoader = new ResourceLoader();
|
||||
|
||||
/// <summary>
|
||||
/// List with days for the filter option
|
||||
/// </summary>
|
||||
private readonly List<DaySelectionItem> _optionList = new List<DaySelectionItem>();
|
||||
|
||||
/// <summary>
|
||||
/// Selected day for filter option
|
||||
/// </summary>
|
||||
private DaySelectionItem _selectedDay;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
@ -72,10 +92,16 @@ namespace Places
|
|||
public MapPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
if(_instanceMap == null)
|
||||
_instanceMap = this;
|
||||
this.menuFlyout = new MenuFlyout();
|
||||
this._navigationHelper = new NavigationHelper(this);
|
||||
this._navigationHelper.LoadState += this.NavigationHelper_LoadState;
|
||||
this._navigationHelper.SaveState += this.NavigationHelper_SaveState;
|
||||
PlacesMap.MapServiceToken = "xxx";
|
||||
FillDateList();
|
||||
this.listSource.Source = _optionList;
|
||||
_selectedDay = _optionList.Last();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -143,7 +169,20 @@ namespace Places
|
|||
Application.Current.Exit();
|
||||
}
|
||||
}
|
||||
InitCore();
|
||||
PlacesMap.Center = new Geopoint(new BasicGeoposition()
|
||||
{
|
||||
Latitude = 60.17,
|
||||
Longitude = 24.83
|
||||
});
|
||||
if (ActivityReader.Instance().ActivityMonitorProperty != null)
|
||||
{
|
||||
ActivityReader.Instance().ActivityMonitorProperty.ReadingChanged += ActivityReader.Instance().activityMonitor_ReadingChanged;
|
||||
}
|
||||
if (!iLaunched)
|
||||
{
|
||||
iLaunched = true;
|
||||
await InitCore();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -153,35 +192,95 @@ namespace Places
|
|||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
this._navigationHelper.OnNavigatedFrom(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigates to details page for the selected place
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="args">Provides data about user input for the map tapped</param>
|
||||
private void OnTapped(MapControl sender, MapInputEventArgs args)
|
||||
{
|
||||
try
|
||||
if (ActivityReader.Instance().ActivityMonitorProperty != null)
|
||||
{
|
||||
var elementList = PlacesMap.FindMapElementsAtOffset(args.Position);
|
||||
foreach (var element in elementList)
|
||||
{
|
||||
var mapIcon = element as MapIcon;
|
||||
if (mapIcon != null)
|
||||
{
|
||||
this.Frame.Navigate(typeof(PivotPage), mapIcon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
ActivityReader.Instance().ActivityMonitorProperty.ReadingChanged -= ActivityReader.Instance().activityMonitor_ReadingChanged;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Fill the list with current day of week, and in descending order rest of the weekdays
|
||||
/// </summary>
|
||||
private void FillDateList()
|
||||
{
|
||||
int today = (int)DateTime.Now.DayOfWeek; // Current day
|
||||
int count = 0;
|
||||
for (int i = today; i >= 0; i--)
|
||||
{
|
||||
var item = new DaySelectionItem { Day = DateTime.Now.Date - TimeSpan.FromDays(count) };
|
||||
var nameOfDay = System.Globalization.DateTimeFormatInfo.CurrentInfo.DayNames[i];
|
||||
// Add an indicator to current day
|
||||
if (count == 0)
|
||||
{
|
||||
nameOfDay += " " + _resourceLoader.GetString("Today");
|
||||
}
|
||||
GeographicRegion userRegion = new GeographicRegion();
|
||||
var userDateFormat = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("shortdate", new[] { userRegion.Code });
|
||||
var dateDefault = userDateFormat.Format(item.Day);
|
||||
item.Name = nameOfDay + " " + dateDefault;
|
||||
_optionList.Add(item);
|
||||
count++;
|
||||
// First day of the week, but not all weekdays still listed,
|
||||
// continue from the last weekday
|
||||
if (i == 0 && count <= 6)
|
||||
{
|
||||
i = 7;
|
||||
}
|
||||
else if (count == 10) // All weekdays listed, exit the loop
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
// Add the option to show everything
|
||||
_optionList.Add(new DaySelectionItem { Name = _resourceLoader.GetString("All") });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a menu flyout with options to choose from
|
||||
/// </summary>
|
||||
/// <param name="sender">The control that the action is for.</param>
|
||||
/// <param name="args">Parameter that contains the event data.</param>
|
||||
private void SelectButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (menuFlyout != null)
|
||||
{
|
||||
menuFlyout.Items.Clear();
|
||||
for (int i = 0; i < listSource.View.Count; i++)
|
||||
{
|
||||
flyoutItem = new MenuFlyoutItem();
|
||||
flyoutItem.Text = this.listSource.View[i].ToString();
|
||||
flyoutItem.FontSize = 22;
|
||||
flyoutItem.FlowDirection = Windows.UI.Xaml.FlowDirection.LeftToRight;
|
||||
flyoutItem.Click += flyoutItem_Click;
|
||||
menuFlyout.Items.Add(flyoutItem);
|
||||
}
|
||||
menuFlyout.Items.Add(new MenuFlyoutItem());
|
||||
menuFlyout.ShowAt(CmdBar);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the route for all the tracks in the selected day.
|
||||
/// </summary>
|
||||
/// <param name="sender">The control that the action is for.</param>
|
||||
/// <param name="args">Parameter that contains the event data.</param>
|
||||
private async void flyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var flyoutItem = e.OriginalSource as MenuFlyoutItem;
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < listSource.View.Count; i++)
|
||||
if (flyoutItem.Text.Contains(listSource.View[i].ToString()))
|
||||
_selectedDay = (DaySelectionItem)listSource.View[i];
|
||||
await UpdateKnownPlacesAsync();
|
||||
FilterTime.Text = _selectedDay.Name;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display home on the map, if is recognised
|
||||
/// </summary>
|
||||
|
@ -197,7 +296,7 @@ namespace Places
|
|||
if (place.Kind == PlaceKind.Home)
|
||||
{
|
||||
PlacesMap.Center = new Geopoint(place.Position);
|
||||
PlacesMap.ZoomLevel = 16;
|
||||
PlacesMap.ZoomLevel = 13;
|
||||
foundPlace = true;
|
||||
break;
|
||||
}
|
||||
|
@ -221,14 +320,17 @@ namespace Places
|
|||
private async void OnWorkClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
bool foundPlace = false;
|
||||
foreach (Place place in _app.Places)
|
||||
if (_app.Places != null)
|
||||
{
|
||||
if (place.Kind == PlaceKind.Work)
|
||||
foreach (Place place in _app.Places)
|
||||
{
|
||||
PlacesMap.Center = new Geopoint(place.Position);
|
||||
PlacesMap.ZoomLevel = 16;
|
||||
foundPlace = true;
|
||||
break;
|
||||
if (place.Kind == PlaceKind.Work)
|
||||
{
|
||||
PlacesMap.Center = new Geopoint(place.Position);
|
||||
PlacesMap.ZoomLevel = 13;
|
||||
foundPlace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// It takes some time for SensorCore SDK to figure out your known locations
|
||||
|
@ -246,10 +348,20 @@ namespace Places
|
|||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">Contains state information and event data associated with a routed event.</param>
|
||||
private void OnCurrentClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
private async void OnCurrentClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
PlacesMap.Center = _currentLocation;
|
||||
PlacesMap.ZoomLevel = 16;
|
||||
if (_currentLocation == null)
|
||||
{
|
||||
var text = _resourceLoader.GetString("CurrentNotFound") + " " + _resourceLoader.GetString("DontWorry/Text");
|
||||
var header = _resourceLoader.GetString("LocationNotDefined");
|
||||
var dialog = new MessageDialog(text, header);
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
PlacesMap.Center = _currentLocation;
|
||||
PlacesMap.ZoomLevel = 13;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -257,24 +369,61 @@ namespace Places
|
|||
/// </summary>
|
||||
/// <param name="sender">The sender of the event</param>
|
||||
/// <param name="e">Contains state information and event data associated with a routed event.</param>
|
||||
private void OnFrequentClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
private async void OnFrequentClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
var notHomeNorWork =
|
||||
from place in _app.Places
|
||||
where place.Kind != PlaceKind.Home && place.Kind != PlaceKind.Work
|
||||
orderby place.Kind descending
|
||||
select place;
|
||||
if (notHomeNorWork.Count() == 0)
|
||||
if (_app.Places != null)
|
||||
{
|
||||
var notHomeNorWork =
|
||||
from place in _app.Places
|
||||
where place.Kind != PlaceKind.Home && place.Kind != PlaceKind.Work
|
||||
orderby place.Kind descending
|
||||
select place;
|
||||
if (notHomeNorWork.Count() == 0)
|
||||
{
|
||||
var text = _resourceLoader.GetString("FrequentNotFound") + " " + _resourceLoader.GetString("DontWorry/Text");
|
||||
var header = _resourceLoader.GetString("LocationNotDefined");
|
||||
var dialog = new MessageDialog(text, header);
|
||||
await dialog.ShowAsync();
|
||||
return;
|
||||
}
|
||||
_chosenFrequentId++;
|
||||
if (_chosenFrequentId >= notHomeNorWork.Count())
|
||||
{
|
||||
_chosenFrequentId = 0;
|
||||
}
|
||||
PlacesMap.Center = new Geopoint(notHomeNorWork.ElementAt(_chosenFrequentId).Position);
|
||||
PlacesMap.ZoomLevel = 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
var text = _resourceLoader.GetString("FrequentNotFound") + " " + _resourceLoader.GetString("DontWorry/Text");
|
||||
var header = _resourceLoader.GetString("LocationNotDefined");
|
||||
var dialog = new MessageDialog(text, header);
|
||||
await dialog.ShowAsync();
|
||||
return;
|
||||
}
|
||||
_chosenFrequentId++;
|
||||
if (_chosenFrequentId >= notHomeNorWork.Count())
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get history button click event handler
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender object</param>
|
||||
/// <param name="e">Event arguments</param>
|
||||
private async void OnPollHistory(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
// Fetch complete stack of places
|
||||
if (resultStr.Count != 0)
|
||||
{
|
||||
_chosenFrequentId = 0;
|
||||
// Pass list of places to HistoryPage
|
||||
this.Frame.Navigate(typeof(HistoryPage), resultStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show message if no history data
|
||||
MessageDialog dialog = new MessageDialog(_resourceLoader.GetString("NoHistoryData/Text"));
|
||||
dialog.Commands.Add(new UICommand(_resourceLoader.GetString("OkButton/Text")));
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
PlacesMap.Center = new Geopoint(notHomeNorWork.ElementAt(_chosenFrequentId).Position);
|
||||
PlacesMap.ZoomLevel = 16;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
|
||||
<Identity Name="NokiaDeveloper.PlacesLumiaSensorCoreSDKsample" Publisher="CN=4AD6DA08-6C39-4A10-98CC-3243374DA59C" Version="1.2.0.1" />
|
||||
<Identity Name="NokiaDeveloper.PlacesLumiaSensorCoreSDKsample" Publisher="CN=4AD6DA08-6C39-4A10-98CC-3243374DA59C" Version="1.2.0.5" />
|
||||
<mp:PhoneIdentity PhoneProductId="4a76e963-c4fa-4884-a385-3e12c6ea994d" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>Places – Lumia SensorCore SDK sample</DisplayName>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -23,12 +24,11 @@ using System;
|
|||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Maps;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using Places.Common;
|
||||
using Places.Utilities;
|
||||
using Lumia.Sense;
|
||||
using Windows.Devices.Geolocation;
|
||||
|
||||
/// <summary>
|
||||
/// The Pivot Application template is documented at http://go.microsoft.com/fwlink/?LinkID=391641
|
||||
|
@ -40,11 +40,16 @@ namespace Places
|
|||
/// </summary>
|
||||
public sealed partial class PivotPage : Page
|
||||
{
|
||||
#region Private members
|
||||
#region Private members
|
||||
/// <summary>
|
||||
/// Navigation Helper instance
|
||||
/// </summary>
|
||||
private readonly NavigationHelper _navigationHelper;
|
||||
|
||||
/// <summary>
|
||||
/// Address of a Geopoint location
|
||||
/// </summary>
|
||||
private string _addressString;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
@ -56,7 +61,6 @@ namespace Places
|
|||
this.NavigationCacheMode = NavigationCacheMode.Required;
|
||||
this._navigationHelper = new NavigationHelper(this);
|
||||
this._navigationHelper.LoadState += this.NavigationHelper_LoadState;
|
||||
this._navigationHelper.SaveState += this.NavigationHelper_SaveState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -82,10 +86,11 @@ namespace Places
|
|||
{
|
||||
if (e.NavigationParameter != null)
|
||||
{
|
||||
var mapIcon = e.NavigationParameter as MapIcon;
|
||||
var mapIcon = e.NavigationParameter.ToString();
|
||||
if (mapIcon != null)
|
||||
{
|
||||
CreatePivotItem(MapExtensions.GetValue(mapIcon));
|
||||
|
||||
CreatePivotItem(mapIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,18 +99,33 @@ namespace Places
|
|||
/// Create a Pivot and PivotItem, and fill with place info
|
||||
/// </summary>
|
||||
/// <param name="place">Place instance</param>
|
||||
private void CreatePivotItem(Place place)
|
||||
private async void CreatePivotItem(string place)
|
||||
{
|
||||
// Get address of a Geopoint location
|
||||
MainGrid.Children.Clear();
|
||||
string[] split = place.Split(new Char[] { '\n', ',' });
|
||||
Geopoint geoPoint = new Geopoint(new BasicGeoposition()
|
||||
{
|
||||
Latitude = Convert.ToDouble(split[1]),
|
||||
Longitude = Convert.ToDouble(split[2])
|
||||
});
|
||||
var newPivot = new Pivot { Title = "MICROSOFT SENSORCORE SAMPLE", Margin = new Thickness(0, 12, 0, 0), Foreground = new SolidColorBrush(Colors.Black) };
|
||||
var pivotItem = new PivotItem { Header = place.Kind.ToString(), Foreground = new SolidColorBrush(Colors.Black)};
|
||||
var pivotItem = new PivotItem { Header = split[0].ToString(), Foreground = new SolidColorBrush(Colors.Black), FontSize = 20 };
|
||||
var stackPanel = new StackPanel();
|
||||
stackPanel.Children.Add(CreateTextBlock("Latitude:", place.Position.Latitude.ToString()));
|
||||
stackPanel.Children.Add(CreateTextBlock("Longitude:", place.Position.Longitude.ToString()));
|
||||
stackPanel.Children.Add(CreateTextBlock("Radius:", place.Radius.ToString() + " m"));
|
||||
// Get address of a Geopoint location
|
||||
var addressTask = GeoLocationHelper.GetAddress(geoPoint);
|
||||
stackPanel.Children.Add(CreateTextBlock("Latitude:", split[1].ToString()));
|
||||
stackPanel.Children.Add(CreateTextBlock("Longitude:", split[2].ToString()));
|
||||
stackPanel.Children.Add(CreateTextBlock("Radius:", split[3].ToString() + " m"));
|
||||
stackPanel.Children.Add(CreateTextBlock("Length of stay:", split[4].ToString()));
|
||||
stackPanel.Children.Add(CreateTextBlock("Total length of stay:", split[5].ToString()));
|
||||
stackPanel.Children.Add(CreateTextBlock("Total visit count:", split[6].ToString()));
|
||||
pivotItem.Content = stackPanel;
|
||||
newPivot.Items.Add(pivotItem);
|
||||
newPivot.Items.Add(pivotItem);
|
||||
MainGrid.Children.Add(newPivot);
|
||||
_addressString = await addressTask;
|
||||
//Add address to the pivot
|
||||
stackPanel.Children.Add(CreateTextBlock("Address:", _addressString));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -134,7 +154,7 @@ namespace Places
|
|||
/// <param name="e">Event data that provides an empty dictionary to be populated with
|
||||
/// serializable state.</param>
|
||||
private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
#region NavigationHelper registration
|
||||
|
|
|
@ -74,6 +74,10 @@
|
|||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="HistoryPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="MapPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -82,6 +86,10 @@
|
|||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="PushPin.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AboutPage.xaml.cs">
|
||||
|
@ -98,6 +106,9 @@
|
|||
<Compile Include="Common\ObservableDictionary.cs" />
|
||||
<Compile Include="Common\RelayCommand.cs" />
|
||||
<Compile Include="Common\SuspensionManager.cs" />
|
||||
<Compile Include="HistoryPage.xaml.cs">
|
||||
<DependentUpon>HistoryPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MapPage.xaml.cs">
|
||||
<DependentUpon>MapPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -108,7 +119,14 @@
|
|||
<DependentUpon>PivotPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PushPin.xaml.cs">
|
||||
<DependentUpon>PushPin.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Utilities\ActivityReader.cs" />
|
||||
<Compile Include="Utilities\DaySelectionItem.cs" />
|
||||
<Compile Include="Utilities\GeoLocationHelper.cs" />
|
||||
<Compile Include="Utilities\MapExtensions.cs" />
|
||||
<Compile Include="Utilities\PlaceHistory.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
|
@ -127,8 +145,6 @@
|
|||
<Content Include="Assets\StoreLogo.scale-240.png" />
|
||||
<Content Include="Assets\WideLogo.scale-240.png" />
|
||||
<Content Include="Common\ReadMe.txt" />
|
||||
<None Include="Help\LumiaSensorCoreSDK.chm" />
|
||||
<None Include="packages.config" />
|
||||
<PRIResource Include="Strings\en-US\ActivateSensorCore.resw" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -167,12 +183,6 @@
|
|||
<Name>Microsoft Visual C++ 2013 Runtime Package for Windows Phone</Name>
|
||||
</SDKReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Lumia.Sense, Version=255.255.255.255, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\LumiaSensorCoreSDK.1.0.3.263\lib\portable-wpa81+wp81\x86\Lumia.Sense.winmd</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
|
@ -180,13 +190,4 @@
|
|||
<TargetPlatformIdentifier>WindowsPhoneApp</TargetPlatformIdentifier>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\$(TargetPlatformVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<Import Project="..\packages\LumiaSensorCoreSDK.1.0.3.263\build\wpa81\LumiaSensorCoreSDK.targets" Condition="Exists('..\packages\LumiaSensorCoreSDK.1.0.3.263\build\wpa81\LumiaSensorCoreSDK.targets')" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<!-- 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>
|
|
@ -0,0 +1,28 @@
|
|||
<UserControl
|
||||
x:Class="Places.PushPin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Places"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
FontFamily="{StaticResource PhoneFontFamilyNormal}"
|
||||
Foreground="{StaticResource PhoneForegroundBrush}"
|
||||
d:DesignHeight="480" d:DesignWidth="480">
|
||||
<Grid x:Name="LayoutRoot" Background="Transparent">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Border Background="#FF8330" CornerRadius="10" Height="65" Width="170" x:Name="imgborder" HorizontalAlignment="Center" >
|
||||
<TextBlock x:Name="Lbltext" Tapped="PushPinTapped" VerticalAlignment="Center"
|
||||
FontSize="20" Text="" TextWrapping="Wrap" Margin="5,5,5,5" >
|
||||
</TextBlock>
|
||||
</Border>
|
||||
<Path Data="M0,0 L0,1 L1,0"
|
||||
Fill="#FF8330"
|
||||
Stretch="Fill"
|
||||
Margin="32,0"
|
||||
Height="12"
|
||||
Width="18"
|
||||
HorizontalAlignment="Left" x:Name="imgpath" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Lumia.Sense;
|
||||
using System.Globalization;
|
||||
|
||||
/// <summary>
|
||||
/// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
/// </summary>
|
||||
namespace Places
|
||||
{
|
||||
/// <summary>
|
||||
/// class to display the popup(pushpin) on the map.
|
||||
/// </summary>
|
||||
public partial class PushPin : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// holds address of the place.
|
||||
/// </summary>
|
||||
private string _placeKind;
|
||||
/// <summary>
|
||||
/// Place Instance
|
||||
/// </summary>
|
||||
private Place _place ;
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
public PushPin(Place place, string placeKind)
|
||||
{
|
||||
InitializeComponent();
|
||||
_place = place;
|
||||
_placeKind = placeKind;
|
||||
Loaded += PushPin_Loaded;
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// page load event. sets the pushpin text.
|
||||
// </summary>
|
||||
// <param name="sender">event details</param>
|
||||
// <param name="e">event sender</param>
|
||||
void PushPin_Loaded( object sender, RoutedEventArgs e )
|
||||
{
|
||||
Lbltext.Text = "'" + _placeKind + "'" + " place";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tapped event on the pushpin to display details.
|
||||
/// </summary>
|
||||
/// <param name="sender">event details</param>
|
||||
/// <param name="e">event sender</param>
|
||||
private void PushPinTapped( object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e )
|
||||
{
|
||||
var frame = Window.Current.Content as Frame;
|
||||
var resultStr = _place.Kind + "\n" + _place.Position.Latitude.ToString() + "\n"+_place.Position.Longitude.ToString() + "\n" +
|
||||
_place.Radius.ToString() +"\n" + _place.LengthOfStay.ToString() + "\n" + _place.TotalLengthOfStay.ToString() + "\n" + _place.TotalVisitCount.ToString();
|
||||
frame.Navigate(typeof(PivotPage),resultStr);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -132,33 +132,66 @@
|
|||
<data name="AddAppBarButton.Label" xml:space="preserve">
|
||||
<value>add</value>
|
||||
</data>
|
||||
<data name="AdressNotFound" xml:space="preserve">
|
||||
<value>A street address could not be found.</value>
|
||||
</data>
|
||||
<data name="All" xml:space="preserve">
|
||||
<value>All</value>
|
||||
</data>
|
||||
<data name="Application.Text" xml:space="preserve">
|
||||
<value>LUMIA SENSORCORE SAMPLE</value>
|
||||
</data>
|
||||
<data name="ApplicationName.Text" xml:space="preserve">
|
||||
<value>Places</value>
|
||||
</data>
|
||||
<data name="CurrentNotFound" xml:space="preserve">
|
||||
<value>The current location has not been resolved yet.</value>
|
||||
</data>
|
||||
<data name="DetailedSetting.DataCollectionQuality" xml:space="preserve">
|
||||
<value>To get more accurate data you need to enable detailed data collection in Motion data settings. Do you want to open settings now?</value>
|
||||
</data>
|
||||
<data name="DontWorry.Text" xml:space="preserve">
|
||||
<value>Don't worry, just give your phone some time to determine this location.</value>
|
||||
</data>
|
||||
<data name="FeatureDisabled.Title" xml:space="preserve">
|
||||
<value>Information</value>
|
||||
</data>
|
||||
<data name="FilterButton.Label" xml:space="preserve">
|
||||
<value>day filter</value>
|
||||
</data>
|
||||
<data name="FrequentNotFound" xml:space="preserve">
|
||||
<value>Frequent place has not been recognised yet.</value>
|
||||
</data>
|
||||
<data name="Header.Text" xml:space="preserve">
|
||||
<value>PLACES</value>
|
||||
</data>
|
||||
<data name="HideAppBarButton.Label" xml:space="preserve">
|
||||
<value>hide</value>
|
||||
</data>
|
||||
<data name="HistoryButton.Label" xml:space="preserve">
|
||||
<value>places history</value>
|
||||
</data>
|
||||
<data name="HistoryPage.Text" xml:space="preserve">
|
||||
<value>places summary</value>
|
||||
</data>
|
||||
<data name="HomeNotFound" xml:space="preserve">
|
||||
<value>The location of your home has not been figured out yet.</value>
|
||||
</data>
|
||||
<data name="Information.Text" xml:space="preserve">
|
||||
<value>Information</value>
|
||||
</data>
|
||||
<data name="KnwonNotFound" xml:space="preserve">
|
||||
<value>Known place has not been recognised yet.</value>
|
||||
</data>
|
||||
<data name="LocationNotDefined" xml:space="preserve">
|
||||
<value>Location not defined</value>
|
||||
</data>
|
||||
<data name="NavigationFailedExceptionMessage" xml:space="preserve">
|
||||
<value>Navigation failed.</value>
|
||||
</data>
|
||||
<data name="NoHistoryData.Text" xml:space="preserve">
|
||||
<value>No places found</value>
|
||||
</data>
|
||||
<data name="NoLocationOrMotionDataError.Text" xml:space="preserve">
|
||||
<value>This application does not function without location and motion data. The application will be closed.</value>
|
||||
</data>
|
||||
|
@ -171,6 +204,12 @@
|
|||
<data name="Pivot.Title" xml:space="preserve">
|
||||
<value>PLACES</value>
|
||||
</data>
|
||||
<data name="PlaceVisitedSetting" xml:space="preserve">
|
||||
<value>In order to collect and view visited places you need to enable Places visited in Motion data settings. Do you want to open settings now?</value>
|
||||
</data>
|
||||
<data name="Today" xml:space="preserve">
|
||||
<value>(Today)</value>
|
||||
</data>
|
||||
<data name="Version.Text" xml:space="preserve">
|
||||
<value>version</value>
|
||||
<comment>.</comment>
|
||||
|
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Lumia.Sense;
|
||||
using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.UI.Core;
|
||||
|
||||
namespace Places.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Data class for getting users activities
|
||||
/// </summary>
|
||||
public class ActivityReader : INotifyPropertyChanged
|
||||
{
|
||||
#region Private members
|
||||
/// <summary>
|
||||
/// List of activities and durations
|
||||
/// </summary>
|
||||
private List<MyQuantifiedData> _listData = null;
|
||||
|
||||
/// <summary>
|
||||
/// Data instance
|
||||
/// </summary>
|
||||
private static ActivityReader _activityReader;
|
||||
|
||||
/// <summary>
|
||||
/// List of history data
|
||||
/// </summary
|
||||
private IList<ActivityMonitorReading> _historyData;
|
||||
|
||||
/// <summary>
|
||||
/// Activity monitor instance
|
||||
/// </summary>
|
||||
private IActivityMonitor _activityMonitor = null;
|
||||
|
||||
/// <summary>
|
||||
/// Activity instance
|
||||
/// </summary>
|
||||
private Activity _activityMode = Activity.Idle;
|
||||
|
||||
/// <summary>
|
||||
/// Time window index, 0 = today, -1 = yesterday
|
||||
/// </summary>
|
||||
private double _timeWindowIndex = 0;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a property value changes.
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by the Set accessor of each property.
|
||||
/// The CallerMemberName attribute that is applied to the optional propertyName
|
||||
/// parameter causes the property name of the caller to be substituted as an argument.
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
|
||||
{
|
||||
if (PropertyChanged != null)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public ActivityReader()
|
||||
{
|
||||
_listData = new List<MyQuantifiedData>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activity monitor property. Gets and sets the activity monitor
|
||||
/// </summary>
|
||||
public IActivityMonitor ActivityMonitorProperty
|
||||
{
|
||||
get
|
||||
{
|
||||
return _activityMonitor;
|
||||
}
|
||||
set
|
||||
{
|
||||
_activityMonitor = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create new instance of the class
|
||||
/// </summary>
|
||||
/// <returns>Data instance</returns>
|
||||
static public ActivityReader Instance()
|
||||
{
|
||||
if (_activityReader == null)
|
||||
_activityReader = new ActivityReader();
|
||||
return _activityReader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when activity changes
|
||||
/// </summary>
|
||||
/// <param name="sender">Sender object</param>
|
||||
/// <param name="args">Event arguments</param>
|
||||
public async void activityMonitor_ReadingChanged(IActivityMonitor sender, ActivityMonitorReading args)
|
||||
{
|
||||
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
{
|
||||
this.ActivityEnum = args.Mode;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes activity monitor
|
||||
/// </summary>
|
||||
public async Task Initialize()
|
||||
{
|
||||
if (ActivityMonitorProperty == null)
|
||||
{
|
||||
if (await MapPage._instanceMap.CallSensorcoreApiAsync(async () => { ActivityMonitorProperty = await ActivityMonitor.GetDefaultAsync(); }))
|
||||
{
|
||||
Debug.WriteLine("ActivityMonitorSimulator initialized.");
|
||||
}
|
||||
if (ActivityMonitorProperty != null)
|
||||
{
|
||||
// Set activity observer
|
||||
ActivityMonitorProperty.ReadingChanged += activityMonitor_ReadingChanged;
|
||||
ActivityMonitorProperty.Enabled = true;
|
||||
// read current activity
|
||||
ActivityMonitorReading reading = null;
|
||||
if (await MapPage._instanceMap.CallSensorcoreApiAsync(async () => { reading = await ActivityMonitorProperty.GetCurrentReadingAsync(); }))
|
||||
{
|
||||
if (reading != null)
|
||||
{
|
||||
this.ActivityEnum = reading.Mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing to do if we cannot use the API
|
||||
// in a real app do make an effort to make the user experience better
|
||||
return;
|
||||
}
|
||||
// Must call DeactivateAsync() when the application goes to background
|
||||
Window.Current.VisibilityChanged += async (sender, args) =>
|
||||
{
|
||||
if (_activityMonitor != null)
|
||||
{
|
||||
await MapPage._instanceMap.CallSensorcoreApiAsync(async () =>
|
||||
{
|
||||
if (!args.Visible)
|
||||
{
|
||||
await _activityMonitor.DeactivateAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await _activityMonitor.ActivateAsync();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current activity
|
||||
/// </summary>
|
||||
public string CurrentActivity
|
||||
{
|
||||
get
|
||||
{
|
||||
return _activityMode.ToString().ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the current activity
|
||||
/// </summary>
|
||||
public Activity ActivityEnum
|
||||
{
|
||||
set
|
||||
{
|
||||
_activityMode = value;
|
||||
NotifyPropertyChanged("CurrentActivity");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the time window
|
||||
/// </summary>
|
||||
public double TimeWindow
|
||||
{
|
||||
get
|
||||
{
|
||||
return _timeWindowIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the time window to today
|
||||
/// </summary>
|
||||
public void NextDay()
|
||||
{
|
||||
if (_timeWindowIndex < 0)
|
||||
{
|
||||
_timeWindowIndex++;
|
||||
NotifyPropertyChanged("TimeWindow");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the time window to previous day
|
||||
/// </summary>
|
||||
public void PreviousDay()
|
||||
{
|
||||
if (_timeWindowIndex >= -9)
|
||||
{
|
||||
_timeWindowIndex--;
|
||||
NotifyPropertyChanged("TimeWindow");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of activities occured during given time period.
|
||||
/// </summary>
|
||||
public IList<ActivityMonitorReading> History
|
||||
{
|
||||
get
|
||||
{
|
||||
return _historyData;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_historyData == null)
|
||||
{
|
||||
_historyData = new List<ActivityMonitorReading>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_historyData.Clear();
|
||||
}
|
||||
_historyData = value;
|
||||
QuantifyData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of activities and durations
|
||||
/// </summary>
|
||||
public List<MyQuantifiedData> ListData
|
||||
{
|
||||
get
|
||||
{
|
||||
return _listData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populate the list of activities and durations to display in the UI
|
||||
/// </summary>
|
||||
private void QuantifyData()
|
||||
{
|
||||
if (_listData != null)
|
||||
{
|
||||
_listData.Clear();
|
||||
}
|
||||
_listData = new List<MyQuantifiedData>();
|
||||
if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled)
|
||||
{
|
||||
List<string> _activitiesList = new List<string>(Enum.GetNames(typeof(Activity)));
|
||||
Dictionary<Activity, int> indexer = new Dictionary<Activity, int>();
|
||||
TimeSpan[] _durations = new TimeSpan[_activitiesList.Count];
|
||||
Activity[] values = (Activity[])Enum.GetValues(typeof(Activity));
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
indexer.Add(values[i], i);
|
||||
}
|
||||
// there could be days with no data (e.g. of phone was turned off
|
||||
if (_historyData.Count > 0)
|
||||
{
|
||||
// first entry may be from previous time window, is there any data from current time window?
|
||||
bool hasDataInTimeWindow = false;
|
||||
// insert new fist entry, representing the last activity of the previous time window
|
||||
// this helps capture that activity's duration but only from the start of current time window
|
||||
ActivityMonitorReading first = _historyData[0];
|
||||
if (first.Timestamp <= DateTime.Now.Date.AddDays(_timeWindowIndex))
|
||||
{
|
||||
// create new "first" entry, with the same mode but timestamp set as 0:00h in current time window
|
||||
_historyData.Insert(1, new ActivityMonitorReading(first.Mode, DateTime.Now.Date.AddDays(_timeWindowIndex)));
|
||||
// remove previous entry
|
||||
_historyData.RemoveAt(0);
|
||||
hasDataInTimeWindow = _historyData.Count > 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the first entry belongs to the current time window
|
||||
// there is no known activity before it
|
||||
hasDataInTimeWindow = true;
|
||||
}
|
||||
// if at least one activity is recorded in this time window
|
||||
if (hasDataInTimeWindow)
|
||||
{
|
||||
// insert a last activity, marking the begining of the next time window
|
||||
// this helps capturing the correct duration of the last activity stated in this time window
|
||||
ActivityMonitorReading last = _historyData.Last();
|
||||
if (last.Timestamp < DateTime.Now.Date.AddDays(_timeWindowIndex + 1))
|
||||
{
|
||||
// is this today's time window
|
||||
if (_timeWindowIndex == 0)
|
||||
{
|
||||
// last activity duration measured until this instant time
|
||||
_historyData.Add(new ActivityMonitorReading(last.Mode, DateTime.Now));
|
||||
}
|
||||
else
|
||||
{
|
||||
// last activity measured until the begining of the next time index
|
||||
_historyData.Add(new ActivityMonitorReading(last.Mode, DateTime.Now.Date.AddDays(_timeWindowIndex + 1)));
|
||||
}
|
||||
}
|
||||
// calculate duration for each current activity by subtracting its timestamp from that of the next one
|
||||
for (int i = 0; i < _historyData.Count - 1; i++)
|
||||
{
|
||||
ActivityMonitorReading current = _historyData[i];
|
||||
ActivityMonitorReading next = _historyData[i + 1];
|
||||
_durations[indexer[current.Mode]] += next.Timestamp - current.Timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
// populate the list to be displayed in the UI
|
||||
for (int i = 0; i < _activitiesList.Count; i++)
|
||||
{
|
||||
_listData.Add(new MyQuantifiedData(_activitiesList[i], _durations[i]));
|
||||
}
|
||||
}
|
||||
NotifyPropertyChanged("ListData");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class to create a list of activities and their timestamp
|
||||
/// </summary>
|
||||
public class MyQuantifiedData
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="s">Activity name</param>
|
||||
/// <param name="i">Activity time</param>
|
||||
public MyQuantifiedData(string s, TimeSpan i)
|
||||
{
|
||||
//split activity string by capital letter
|
||||
ActivityName = System.Text.RegularExpressions.Regex.Replace(s, @"([A-Z])(?<=[a-z]\1|[A-Za-z]\1(?=[a-z]))", " $1");
|
||||
ActivityTime = i;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activity name
|
||||
/// </summary>
|
||||
public string ActivityName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activity time
|
||||
/// </summary>
|
||||
public TimeSpan ActivityTime
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
|
||||
namespace Places.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to select the days from a list
|
||||
/// </summary>
|
||||
public class DaySelectionItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the selected day
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Selected day in DateTime format
|
||||
/// </summary>
|
||||
public DateTime Day { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Convert to string
|
||||
/// </summary>
|
||||
/// <returns>Name in string format</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Devices.Geolocation;
|
||||
using Windows.Services.Maps;
|
||||
|
||||
namespace Places.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to find a geopoint location
|
||||
/// </summary>
|
||||
public class GeoLocationHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Find the address of a Geopoint location
|
||||
/// </summary>
|
||||
/// <param name="geopoint"></param>
|
||||
/// <returns><c>address</c> upon success, <c>error message</c> otherwise</returns>
|
||||
public static async Task<string> GetAddress(Geopoint geopoint)
|
||||
{
|
||||
var loader = new ResourceLoader();
|
||||
// Find the address of the tapped location
|
||||
MapLocationFinderResult result = await MapLocationFinder.FindLocationsAtAsync(geopoint);
|
||||
// If successful then display the address.
|
||||
if (result.Status == MapLocationFinderStatus.Success)
|
||||
{
|
||||
string displayAddress = null;
|
||||
// Get the list of locations found by MapLocationFinder
|
||||
if (result.Locations.Count > 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(result.Locations[0].Address.Street))
|
||||
{
|
||||
// If the address of a geographic loaction is empty or null, get only the town and region
|
||||
var region = result.Locations[0].Address.Region != "" ? ", " + result.Locations[0].Address.Region : null;
|
||||
displayAddress = result.Locations[0].Address.Town + region;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the complete address of a geographic location
|
||||
displayAddress = result.Locations[0].Address.StreetNumber + " " + result.Locations[0].Address.Street;
|
||||
}
|
||||
return displayAddress;
|
||||
}
|
||||
// Show message error if location is not found
|
||||
else
|
||||
{
|
||||
var msg = loader.GetString("AdressNotFound");
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
// Show message error if the query location is not successful
|
||||
var error = loader.GetString("LocationNotDefined");
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
namespace Places.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class to describe a place in history page
|
||||
/// </summary>
|
||||
public class PlaceHistory
|
||||
{
|
||||
/// <summary>
|
||||
/// Informations about history place
|
||||
/// </summary>
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///Path Image
|
||||
/// </summary>
|
||||
public string ImagePath { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="LumiaSensorCoreSDK" version="1.0.3.263" targetFramework="wpa81" />
|
||||
|
||||
</packages>
|
|
@ -64,7 +64,7 @@ file the capabilities required for it to work:
|
|||
|
||||
3. Version history
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
* Version 1.2.0.5: Updated to use latest Lumia SensorCore SDK 1.1 Preview
|
||||
* Version 1.2.0.1: Some bug fixes made in this release.
|
||||
* Version 1.2: Updated to use version 1.0 of Lumia SensorCore SDK, added support
|
||||
for frequent places and few other minor updates.
|
||||
|
@ -76,6 +76,7 @@ file the capabilities required for it to work:
|
|||
|
||||
| Project | Release | Download |
|
||||
| ------- | --------| -------- |
|
||||
| Places | v1.2.0.5 | [places-1.2.0.5.zip](https://github.com/Microsoft/places/archive/v1.2.0.5.zip) |
|
||||
| Places | v1.2.0.1 | [places-1.2.0.1.zip](https://github.com/Microsoft/places/archive/v1.2.0.1.zip) |
|
||||
| Places | v1.2 | [places-1.2.zip](https://github.com/Microsoft/places/archive/v1.2.zip) |
|
||||
| Places | v1.0 | [places-1.0.zip](https://github.com/Microsoft/places/archive/v1.0.zip) |
|
||||
|
|
Загрузка…
Ссылка в новой задаче