Pliki i foldery w Windows Phone 8 - Obsługa kart SD
Pobierz i uruchom |
Tłumaczenie na podstawie Reading from the SD card on Windows Phone 8: Aurelia Tokarek
Opublikowano: 2013-01-28
W tym odcinku dowiesz się, jak programowo obsłużyć odczyt i zapis kart SD. Aplikacje Windows Phone mogą odczytywać określone typy plików z kart SD, używając API Microsoft.Phone.Storage. Aby odczytać pliki, Twoja aplikacja musi zarejestrować w pliku manifestu rozszerzenia plików, które może obsługiwać. Ponieważ skojarzenie pliku jest wymagane, Twoja aplikacja zostanie także włączona do obsługi plików, które nie są na karcie SD. Więcej informacji o skojarzeniu plików znajdziesz w Auto-launching apps using file and URI associations for Windows Phone 8.
Kod z tego odcinka pochodzi z przykładu Route Mapper sample, który demonstruje podstawowe kroki umożliwiające obsługę plików i odczyt z karty SD.
Uwaga!
Przykład Route Mapper odczytuje drogi z pliku GPX i wyświetla je na kontrolce mapy. Może czytać pliki GPX z karty SD oraz ze skojarzonych plików. Strona RoutPage.xaml używana jest do obsługi obu przypadków. Aby odczytać plik GPX z karty SD, MainPage.xaml wysyła do RoutePage.xaml ścieżkę do żądanego pliku poprzez adres URI, uruchamiając w ten sposób stronę. Więcej informacji znajdziesz w sample.
- Definicja w pliku manifestu – w pliku manifestu WMAppManifest.xml określ możliwość ID_CAP_REMOVEABLE_STORAGE dostępu do karty SD:
<Capability Name="ID_CAP_REMOVABLE_STORAGE" />
- Rejestrowanie rozszerzeń – aby Twoja aplikacja mogła obsłużyć pliki z określonym rozszerzeniem musisz je określić w manifeście – WMAppManifest.xml. Zaraz po elemencie Tokens, wewnątrz elementu Extensions, rozszerzenie pliku określane jest poprzez element FileTypeAssociation:
<FileTypeAssociation TaskID="_default" Name="GPX" 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/gpx">.gpx</FileType>
</SupportedFileTypes>
</FileTypeAssociation>
Windows Phone Manifest Designer nie obsługuje elementu Extensions. Więcej informacji o edytowaniu rozszerzeń znajdziesz w How to modify the app manifest file for Windows Phone.
- Mapa włączająca URI – ponieważ skojarzenie plików wymagane jest do odczytu określonego typu pliku z karty SD, Twoja aplikacja może zostać włączona do obsługi plików, które nie znajdują się na karcie. Aby obsłużyć ten scenariusz, dodaj niestandardowe mapowanie URI w celu przekazania tokena skojarzonych plików do właściwej strony. Ten kod pochodzi z pliku CustomerURIMapper.cs przykładu Route Mapper:
using System;
using System.Windows.Navigation;
using Windows.Phone.Storage.SharedAccess;
namespace sdkRouteMapperWP8CS
{
class CustomURIMapper : UriMapperBase
{
private string tempUri;
public override Uri MapUri(Uri uri)
{
tempUri = uri.ToString();
// File association launch
// Example launch URI: /FileTypeAssociation?fileToken=89819279-4fe0-4531-9f57-d633f0949a19
if (tempUri.Contains("/FileTypeAssociation"))
{
// Get the file ID (after "fileToken=").
int fileIDIndex = tempUri.IndexOf("fileToken=") + 10;
string fileID = tempUri.Substring(fileIDIndex);
// Map the file association launch to route page.
return new Uri("/RoutePage.xaml?fileToken=" + fileID, UriKind.Relative);
}
// Otherwise perform normal launch.
return uri;
}
}
}
W tym przykładzie, kiedy skojarzenie pliku uruchamia aplikację, URI przekazywany jest od strony nazwanej RoutePage.xaml, wraz z zawartościąfileToken, do docelowej strony. Jeśli aplikacja włączy się z innego powodu, mapowanie zwróci oryginalny stan przychodzącego URI.
Poniższy kod pokazuje, w jaki sposób mapowanie URI przypisywane jest do obiektu App w metodzie InitializePhoneApplication pliku App.xaml.cs:
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Assign the URI-mapper class to the application frame.
RootFrame.UriMapper = new CustomURIMapper();
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Handle reset requests for clearing the backstack
RootFrame.Navigated += CheckForResetNavigation;
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
- Obsługa parametrów URI – kiedy strona jest uruchomiona, może uzyskać dostęp do wszystkich parametrów URI (uruchamiającego stronę), używając właściwości QueryString obiektu NavigationContext. Poniższy przykład pokazuje, w jaki sposób wartość parametru fileToken wyodrębniana jest z URI i przypisywana do zmiennej, do późniejszego użycia. Ten kod pochodzi z pliku RoutePage.xaml.cs przykładu Route Mapper:
// Assign the path or token value, depending on how the page was launched.
protected override async void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
// Route is from a file association.
if (NavigationContext.QueryString.ContainsKey("fileToken"))
{
_fileToken = NavigationContext.QueryString["fileToken"];
await ProcessExternalGPXFile(_fileToken);
}
// Route is from the SD card.
else if (NavigationContext.QueryString.ContainsKey("sdFilePath"))
{
_sdFilePath = NavigationContext.QueryString["sdFilePath"];
await ProcessSDGPXFile(_sdFilePath);
}
}
Ścieżka do pliku na karcie SD została przekazana do RoutePage.xaml z MainPage.xaml przy użyciu parametru sdFilePath. Kod został wyjaśniony w kroku 6.
- Pobranie pliku z tokenem – w przekazanym adresie URI znajduje się fileToken, który może być użyty do dostępu do pliku, w którym jest uruchamiany. Jak pokazano w poprzednim kroku, kopiując token z mapowanego URI do strony, strona otrzymuje dostęp do pliku. Użyj CopySharedFileAsync w celu kopiowania pliku do lokalnego folderu aplikacji zanim go użyjesz. Jeśli chcesz najpierw uzyskać dostęp do nazwy pliku przed skopiowaniem, możesz wywołać metodę GetSharedFileName ze strony mapowanego URI. W pliku RoutePage.xaml z przykładu Route Mapper metoda ProcessExternalGPXFile używa tokena do kopiowania pliku do lokalnego folderu aplikacji:
// Process a route from a file association.
public async Task ProcessExternalGPXFile(string fileToken)
{
// Create or open the routes folder.
IStorageFolder routesFolder = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFolderAsync(ROUTES_FOLDER_NAME, CreationCollisionOption.OpenIfExists);
// Get the full file name of the route (.GPX file) from the file association.
string incomingRouteFilename = Windows.Phone.Storage.SharedAccess.SharedStorageAccessManager.GetSharedFileName(fileToken);
// Copy the route (.GPX file) to the Routes folder.
IStorageFile routeFile = await Windows.Phone.Storage.SharedAccess.SharedStorageAccessManager.CopySharedFileAsync((StorageFolder)routesFolder, incomingRouteFilename, NameCollisionOption.GenerateUniqueName, fileToken);
// Create a stream for the route.
var routeStream = await routeFile.OpenReadAsync();
// Read the route data.
ReadGPXFile(routeStream.AsStream());
}
Metoda ReadGPXFile przetwarza dane ścieżki i wyrysowuje je na kontrolce mapy. Więcej informacji o używaniu mapy znajdziesz w Maps and navigation for Windows Phone 8.
- Pobranie pliku z karty SD – w przykładzie Route Mapper podzielono funkcje karty SD na dwie osobne części: skanowanie karty SD i otwieranie pliku z Path. W poniższym kodzie, aplikacja skanuje kartę SD z pliku GPX i zapisuje ścieżki jej pliku na ObservableCollection<T>, nazwanym Routes. W MainPage.xaml Routes powiązany jest z ListBox, nazwanym gpxFileListBox, dlatego aplikacja może wyświetlać nazwy plików GPX, które umieszczone są na karcie SD:
// Connect to the current SD card.
ExternalStorageDevice _sdCard = (await ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault();
// If the SD card is present, add GPX files to the Routes collection.
if (_sdCard != null)
{
try
{
// Look for a folder on the SD card named Routes.
ExternalStorageFolder routesFolder = await _sdCard.GetFolderAsync("Routes");
// Get all files from the Routes folder.
IEnumerable<ExternalStorageFile> routeFiles = await routesFolder.GetFilesAsync();
// Add each GPX file to the Routes collection.
foreach (ExternalStorageFile esf in routeFiles)
{
if (esf.Path.EndsWith(".gpx"))
{
Routes.Add(esf);
}
}
}
catch (FileNotFoundException)
{
// No Routes folder is present.
MessageBox.Show("The Routes folder is missing on your SD card. Add a Routes folder containing at least one .GPX file and try again.");
}
}
else
{
// No SD card is present.
MessageBox.Show("The SD card is mssing. Insert an SD card that has a Routes folder containing at least one .GPX file and try again.");
}
Kiedy użytkownik wskaże plik GPX w gpxFilesListBox, MainPage.xaml uruchomi RoutePage.xaml i przekaże ścieżkę pliku jako parametr URI. Ponieważ gpxFileListBox powiązany jest z Routes, a Routes jest typu ExternalStorageFile, parametr sender zwraca zdarzenie gpxFilesListBox_SelectionChanged_1, które może być używane jako dostęp do ścieżki pliku karty SD:
// When a different route is selected, launch the RoutePage and send the file path with the URI.
private void gpxFilesListBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
ListBox lb = (ListBox)sender;
if (lb.SelectedItem != null)
{
ExternalStorageFile esf = (ExternalStorageFile)lb.SelectedItem;
NavigationService.Navigate(new Uri("/RoutePage.xaml?sdFilePath=" + esf.Path, UriKind.Relative));
}
}
Wreszcie, na stronie RoutePage.xaml, metoda ProcessSDGPXFile używa ścieżki do pobrania pliku z karty SD i otwarcia strumienia dla metody ReadGPXFiles:
// Process a route from the SD card.
private async Task ProcessSDGPXFile(string _sdFilePath)
{
// Connect to the current SD card.
ExternalStorageDevice sdCard = (await ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault();
// If the SD card is present, get the route from the SD card.
if (sdCard != null)
{
try
{
// Get the route (.GPX file) from the SD card.
ExternalStorageFile file = await sdCard.GetFileAsync(_sdFilePath);
// Create a stream for the route.
Stream s = await file.OpenForReadAsync();
// Read the route data.
ReadGPXFile(s);
}
catch (FileNotFoundException)
{
// The route is not present on the SD card.
MessageBox.Show("That route is missing on your SD card.");
}
}
else
{
// No SD card is present.
MessageBox.Show("The SD card is mssing. Insert an SD card that has a Routes folder containing at least one .GPX file and try again.");
}
}
Więcej informacji o wyświetlaniuReadGPXFiles na kontrolce mapy pobierzesz z Route Mapper Sample.
Podsumowanie
W tym odcinku dowiedziałeś się, jak obsłużyć programowo odczyt i zapis kart SD. W kolejnym odcinku nauczysz się odczytywać i zapisywać ustawienia w aplikacji.