Introduction
With the release of Windows Phone 8, Microsoft introduced the programmatic ability to read content from an SD card. This expands the Windows Phone 8 platform capability, which did not have access to SD cards in prior platform releases. It also allows the Windows Phone 8 platform to align with Windows 8 platform, allowing for some code reuse for application developers who want to target applications for both of the platforms.
API Support
APIs to access an SD card are new to Windows Phone 8 and reside in the Windows.Phone.Storage namespace. One important thing to note is that in order to access SD card content, the Windows Phone application will need to declare the capability (ID_CAP_REMOVALE_STORAGE) in the application manifest file (WMAppManifest.xml).
Note that in Windows Phone 8, only read-access to the SD card contents is provided through the APIs. It is not possible to have write access using the Windows.Phone.Storage APIs.
The following classes in the Windows.Phone.Storage are available to the users.
Class |
Purpose |
ExternalStorage |
This class represents external storage and can be used to get a list of external storage devices available on a Windows Phone device. |
ExternalStorageDevice |
This class represents an SD card on a Windows Phone and can be used to get a specific folder, or a specific file on an SD card. |
ExternalStorageFolder |
This class represents a folder on an SD card and can be used to get the details of the folder or a list of files/folders under a specific folder. |
ExternalStorageFile |
This class represents a file on an SD card and can be used to get the name and/or path of a file on the SD card. |
In Windows Phone 8, there is no support for an SD card in the emulator. Hence, you will need a real device for testing.
How it Works
The architecture of Windows Phone 8 attempts to provide a secure environment for the user. In that light, the user needs declare the extension of files that he/she desires to read through an application. If this is not done, the external storage API will not list any files when the list files API is called.
Now, we can get hands-on and build an application that reads content from an SD card.
Hands-On
Create a new Visual Studio Project using the Windows Phone App template. Title the project WindowsPhoneSDCardDemo.
Create a new Visual Studio Project
When prompted, select “Windows Phone OS 8.0” as the target OS.
Target Windows Phone OS Version
Next, we need to open the application manifest file and declare the capability to access SD card (removable storage). Double click on the WMAppManifest.xml in the Solution explorer.
Double click on WMAppManifest.xml
We need to choose ID_CAP_REMOVABLE_STORAGE capability.
Declare Capability
We need to declare additional capability to register a certain file extension with the application.
To ensure that we can read files of a certain type, we need to register file association via extensions in the Application Manifest file. For this, we need to open the WMAppManifest.xml file as code and make the following changes.
For our application, we will register our application to associate with extension “MDX”.
In WMAppManifest.xml file, add the section highlighted to associate an extension with the application.
<?xml version="1.0" encoding="utf-8"?> <Deployment xmlns="http://schemas.microsoft.com/windowsphone/2012/deployment" AppPlatformVersion="8.0"> <DefaultLanguage xmlns="" code="en-US" /> <App xmlns="" ProductID="{ca8866c1-db3a-4d57-85e6-5af87f422838}" Title="WindowsPhoneSDCardDemo" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal" Author="WindowsPhoneSDCardDemo author" Description="Sample description" Publisher="WindowsPhoneSDCardDemo" PublisherID="{78c2e833-1f17-4f65-b07f-00e1d91beba9}"> <IconPath IsRelative="true" IsResource="false">AssetsApplicationIcon.png</IconPath> <Capabilities> <Capability Name="ID_CAP_NETWORKING" /> <Capability Name="ID_CAP_MEDIALIB_AUDIO" /> <Capability Name="ID_CAP_MEDIALIB_PLAYBACK" /> <Capability Name="ID_CAP_SENSORS" /> <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" /> <Capability Name="ID_CAP_REMOVABLE_STORAGE" /> </Capabilities> <Tasks> <DefaultTask Name="_default" NavigationPage="MainPage.xaml" /> </Tasks> <Tokens> <PrimaryToken TokenID="WindowsPhoneSDCardDemoToken" TaskName="_default"> <TemplateFlip> <SmallImageURI IsRelative="true" IsResource="false">AssetsTilesFlipCycleTileSmall.png</SmallImageURI> <Count>0</Count> <BackgroundImageURI IsRelative="true" IsResource="false">AssetsTilesFlipCycleTileMedium.png</BackgroundImageURI> <Title>WindowsPhoneSDCardDemo</Title> <BackContent> </BackContent> <BackBackgroundImageURI> </BackBackgroundImageURI> <BackTitle> </BackTitle> <DeviceLockImageURI> </DeviceLockImageURI> <HasLarge> </HasLarge> </TemplateFlip> </PrimaryToken> </Tokens> <Extensions> <FileTypeAssociation TaskID="_default" Name="MDX" NavUriFragment="fileToken=%s"> <Logos> <Logo Size="small" IsRelative="true">Assets/Route_Mapper_Logo33x33.png</Logo> <Logo Size="medium" IsRelative="true">Assets/Route_Mapper_Logo69x69.png</Logo> <Logo Size="large" IsRelative="true">Assets/Route_Mapper_Logo176x176.png</Logo> </Logos> <SupportedFileTypes> <FileType ContentType="application/mdx">.mdx</FileType> </SupportedFileTypes> </FileTypeAssociation> </Extensions> <ScreenResolutions> <ScreenResolution Name="ID_RESOLUTION_WVGA" /> <ScreenResolution Name="ID_RESOLUTION_WXGA" /> <ScreenResolution Name="ID_RESOLUTION_HD720P" /> </ScreenResolutions> </App> </Deployment>
In the section above, we have associated file extension MDX with our application.
Next, add a button to the mainPage called “Open SD Card”.
Open SD Card
On the click event of the button, we will write code to read the content of the SD card.
Since the SD card APIs are async, we should called them with “await” C# keyword.
private async void buttonOpenSDCard_Click(object sender, RoutedEventArgs e) { await ListSDCardFileContents(); }
Now, we will implement the API ListSDCardFIleContents().
private async Task ListSDCardFileContents() { // List the first /default SD Card whih is on the device. Since we know Windows Phone devices only support one SD card, this should get us the SD card on the phone. ExternalStorageDevice sdCard = (await ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault(); if (sdCard != null) { // Get the root folder on the SD card. ExternalStorageFolder sdrootFolder = sdCard.RootFolder; if (sdrootFolder != null) { // List all the files on the root folder. var files = await sdrootFolder.GetFilesAsync(); if (files != null) { foreach (ExternalStorageFile file in files) { Stream s = await file.OpenForReadAsync(); if (s != null || s.Length == 0) { long streamLength = s.Length; StreamReader sr = new StreamReader(s); MessageBox.Show(sr.ReadToEnd()); } else { MessageBox.Show("There were no files in the root folder"); } } } } else { MessageBox.Show("Failed to get root folder on SD card"); } } else { MessageBox.Show("SD Card not found on device"); } }
Now, prior to executing the application, create a file titled readme.mdx with the following contents.
//readme.mdx
hello this is line 1
this is line 2
end of file
Copy this file to the Windows Phone SD card.
We are now ready to test the application.
Now, when the application is run in the emulator, you will see the following.
Test the Application in the Emulator
But when you run it on a device, you will see:
Test the Application on a Device
Summary
In this article, we learned about how to read from an SD card on Windows Phone 8 applications. I hope you have found this information useful.
Download Windows Phone SD Card Demo
About the author
Vipul Patel is a Program Manager currently working at Amazon Corporation. He has formerly worked at Microsoft in the Lync team and in the .NET team (in the Base Class libraries and the Debugging and Profiling team). He can be reached at vipul.patel@hotmail.com