Pliki i foldery w Windows Phone 8 - Obsługa kart SD  Udostępnij na: Facebook

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.

  1. 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" />
  1. 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.

  1. 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;
}
  1. 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.

  1. 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.

  1. 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.