Using Launcher.LaunchFileAsync to launch file from Isolated File Storage on the Window Phone 8 SDK

Assuming you have saved your file to the Isolated File Storage like so:

using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())

{

//create a local file with the same name using the input stream and saving through the output stream

using (IsolatedStorageFileStream outputStream = ISF.CreateFile(fileName))

{

try

{

byte[] bytes = new byte[inputStream.Length];

inputStream.Read(bytes, 0, (int)inputStream.Length);

outputStream.Write(bytes, 0, bytes.Length);

outputStream.Flush();

}

catch

{}

}

loadingProgressBar.IsVisible = false;

 

//have saved our file now lets launch it

LaunchFile(fileName);

}

 

private async void LaunchFile(string fileName)

{

var file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);

await Windows.System.Launcher.LaunchFileAsync(file);

}

Develop Windows Phone 8 (WP8) SDK to fetch data from SharePoint Online or 2013

So you want to have a go at developing native windows phone apps that interact with SharePoint Online or even SharePoint 2013 on-premise (as long as your device browser has access to the site)….lets begin!

Pre-reqs:

  • OS – Windows 8/8.1 Pro or better
  • Windows Phone 8 or 8.1 SDK
    • If you go with the Windows Phone 8 SDK please ensure you update it to the current Update 4.  The older versions have issues debugging.
  • SharePoint SDK for Windows Phone

 

Create the project

Open Visual Studio Express for Windows Phone.

Click File > New Project > Visual C Sharp > Windows Phone > Empty SharePoint Project

 

I find it easier going with an empty SharePoint project and adding what you need rather than the SharePoint list project and then having to remove unnecessary stuff.

 

Explore the created files and folders

In particular App.xaml, the assets icons and the AppManifest in the properties.

 

Make the UI

OK so we get a rather plain looking xaml screen (MainPage.xaml) to start with. Lets make it look better by adding a pivot control or panorama. If you don’t know what they are check out this msdn blog.  My personal preference is a pivot control as i think the screen look a lot cleaner with it.  Im going to add 4 pivot items to the pivot control: Home, News, Documents, Sales thats because i have this data in sharepoint and want to show it in the app on a user interface of my choice rather than the standard boring sharepoint app which just shows standard lists.

<phone:Pivot Title=”My app” x:Name=”MainPivot” SelectionChanged=”MainPivot_SelectionChanged” >

<phone:PivotItem Header=”Home”>

<phone:PivotItem Header=”News”>

<phone:PivotItem Header=”Docs”>

<phone:PivotItem Header=”Sales”>

</phone:Pivot>

Im not going to go into the details of creating the UI but in essence the home pivot will have a nice looking grid with buttons and icons to switch the pivots. In the code above ive highlighted the SelectionChanged event. Since we have a lot of data in sharepoint we dont want to load all the tabs at once instead they will be loaded on demand.  Ive also added a progress indication to the xaml which will be set with IsVisible=true in the codebehind when loading content:

<shell:SystemTray.ProgressIndicator>

<shell:ProgressIndicator IsIndeterminate=”True” IsVisible=”True” Text=”Loading data …”

x:Name=”loadingPr

ogressBar” />

</shell:SystemTray.ProgressIndicator>

 

Id strongly recommend switch between Blend and VS when creating the UI. Blend is a lot easier.

 

 

Authenticate with SharePo

int

I want to login the authentication piece out of the way for the user right at the start.

 

For this ive added a Context property to the code.

 

private ClientContext m_Context;

public ClientContext Context

{

get

{

if (m_Context != null)

return m_Context;

m_Context = new ClientContext(“https://isharepoint.sharepoint.com”);

Authenticator at = new Authenticator();

at.CookieCachingEnabled = true; //Allows authenticator to save cookies for future usage

m_Context.Credentials = at;

return m_Context;

}

}

Ive added a Loaded event:

private void TitlePanel_Loaded_1(object sender, RoutedEventArgs e)

{

web = Context.Web;

Context.Load(web);

//you cannot authentication on the main thread, so call a new thread

//so you push the clientcontext loading into a new thread

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(LoginThreadCallback), Context);

}

private void LoginThreadCallback(object s)

{

var context = (ClientContext)s;

context.ExecuteQuery();//start thread work to authenticate and load sp lists

_syncContext.Post(

new SendOrPostCallback(

delegate(object state)

{

LoginThreadComplete();

}), null);

}

private void LoginThreadComplete()

{

loadingProgressBar.IsVisible = false;

}

 

Binding Data

Now that we have the Context object authenticated when the MainPivot_SelectionChanged event is triggered we can use that Context to load the data and bind it onto out PivotItems.

For example on my News pivotitem ive added a longlistselector with an itemtemplate of how i want each article to appear:

<phone:LongListSelector x:Name=”NewsList” ItemsSource=”{Binding ListData}”  >

<phone:LongListSelector.ItemTemplate>

<DataTemplate>

<StackPanel Margin=”0,5″>

<StackPanel Orientation=”Horizontal” Background=”#80FFFFFF”>

<Image Margin=”5,5″ Width=”120″ Height=”80″ Source=”{Binding ImageSrc}” />

<StackPanel>

<TextBlock Text=”{Binding Title}” Width=”300″ TextWrapping=”Wrap” FontSize=”{StaticResource PhoneFontSizeLarge}” />

<TextBlock Text=”{Binding ArticleDate}” />

</StackPanel>

</StackPanel>

</StackPanel>

</DataTemplate>

</phone:LongListSelector.ItemTemplate>

</phone:LongListSelector>

 

Next create a class (Model) to represent a News article:

public class Article

{

public string Title { get; set; }

public BitmapImage ImageSrc { get; set; }

public string ArticleDate { get; set; }

}

Thats our model complete.  In the below code we fetch the data and bind it to the longlistselector with the x:Name of NewsList.  Each article will also have an image from the PublishingImages folder which will have to be downloaded the Isolated File Storage and then added to the xaml.  Ive skipped out that part but theres lots of online resources for it.

private void LoadNewsArticles()

{

loadingProgressBar.IsVisible = true;

web = Context.Web;

spNewsList = web.Lists.GetByTitle(newsList);

Context.Load(spNewsList);

CamlQuery query = new CamlQuery();

query.ViewXml = “<View><Query><Where><IsNotNull><FieldRef Name=’HomePageText’ /></IsNotNull></Where><OrderBy><FieldRef Name=’Modified’ Ascending=’FALSE’ /></OrderBy></Query><ViewFields><FieldRef Name=’HomePageText’ /><FieldRef Name=’PublishingRollupImage’ /><FieldRef Name=’Modified’ /></ViewFields><RowLimit>10</RowLimit></View>”;

spNewsItems = spNewsList.GetItems(query);

 

Context.Load(spNewsItems);

 

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(NewsThreadCallback), Context);

}

 

private void NewsThreadCallback(object s)

{

var context = (ClientContext)s;

context.ExecuteQuery();

//send the data to the main thread so that it can update the UI

_syncContext.Post(

new SendOrPostCallback(

delegate(object state)

{

SetNewsData();

}), null);

}

 

protected void SetNewsData()

{

if (spNewsItems.Count > 0)

{

//create list of news articles

List<Article> source = new List<Article>();

foreach (ListItem item in spNewsItems)

{

if (item[“PublishingRollupImage”] != null)

{

string imagesrc = item[“PublishingRollupImage”].ToString();

imagesrc = imagesrc.Substring(imagesrc.IndexOf(“/”));

imagesrc = imagesrc.Substring(0, imagesrc.IndexOf(“\””));

string filename = imagesrc.Substring(imagesrc.LastIndexOf(“/”)+1);

 

DownloadFile(Context, imagesrc, filename);//download image to isolated from storage

BitmapImage image = ThumbImageFromIFS(filename);//getting image file from Isolated File Store

 

string homepagetext = item[“HomePageText”].ToString();

if (homepagetext.Length > 35)

{

homepagetext = homepagetext.Substring(0, 34) + “…”;

}

//add news article to the news articles list

source.Add(new Article() { Title = homepagetext, ImageSrc = image, ArticleDate = DateTime.Parse(item[“Modified”].ToString()).ToShortDateString() });

 

}

}

//set the long list selector source

NewsList.ItemsSource = source;

loadingProgressBar.IsVisible = false;

}

}

 

Thats all folks! Hopefully that all makes sense, if not leave a comment below and ill try to respond.