내보내기(0) 인쇄
모두 확장
정보
요청한 주제가 아래에 표시됩니다. 그러나 이 주제는 이 라이브러리에 포함되지 않습니다.

Windows Phone 8의 SD 카드에서 읽기

2014-06-18

적용 대상: Windows Phone 8 및 Windows Phone Silverlight 8.1만

Windows Phone 앱은 Microsoft.Phone.Storage API를 사용하여 SD 카드에서 특정 파일 형식을 읽을 수 있습니다. 파일을 읽으려면 앱이 앱 매니페스트 파일에서 파일 연결을 등록하고 처리할 수 있는 파일 형식(확장명)을 선언해야 합니다. 파일 연결이 필요하므로 앱을 시작하여 SD 카드에 없는 파일을 처리할 수도 있습니다. 파일 연결에 대한 자세한 내용은 Windows Phone 8의 파일 및 URI 연결을 사용하여 앱 자동 실행을 참조하세요.

이 항목에 나오는 코드는 경로 매퍼 샘플에서 가져온 것입니다. 샘플에서는 파일 연결을 처리하고 SD 카드에서 읽는 기본 단계를 보여 줍니다.

참고참고:

경로 매퍼 샘플에서는 GPX 파일에서 경로를 읽어 지도 컨트롤에 표시합니다. GPX 파일은 SD 카드 및 파일 연결에서 읽을 수 있습니다. 단일 페이지 RoutePage.xaml을 사용하여 두 가지 경우를 모두 처리합니다. SD 카드에서 GPX 파일을 읽으려면 MainPage.xaml에서 페이지를 시작하는 URI를 통해 파일로 RoutePage.xaml 경로를 보냅니다. 자세한 내용은 샘플을 참조하세요.

이 항목에는 다음 단원이 포함되어 있습니다.

앱 매니페스트 파일 WMAppManifest.xml에서 ID_CAP_REMOVEABLE_STORAGE 기능을 지정하여 SD 카드에 액세스합니다.

<Capability Name="ID_CAP_REMOVABLE_STORAGE" />

특정 파일 형식을 처리하려면 파일 연결 확장명을 등록합니다. 확장은 WMAppManifest.xml에서 지정합니다. Tokens 요소 바로 뒤 Extensions 요소 내에서 다음 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 매니페스트 디자이너는 Extensions 요소를 지원하지 않습니다. 확장을 편집하는 방법에 대한 자세한 내용은 Windows Phone 8의 앱 매니페스트 파일을 수정하는 방법을 참조하세요.

파일 연결은 SD 카드에서 특정 파일 형식을 읽는 데 필요하므로 앱을 시작하여 SD 카드에 없는 파일을 처리할 수 있습니다. 해당 시나리오를 처리하려면 사용자 지정 URI 매퍼를 추가하여 파일 연결의 토큰을 올바른 페이지에 전달합니다. 이 코드는 샘플의 CustomURIMapper.cs 파일에서 가져온 것입니다.


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


이 예제에서는 파일 연결에서 앱을 시작하면 URI 매퍼에서 들어오는 URI를 RoutePage.xaml이라는 페이지에 매핑하고 fileToken 값을 대상 페이지에 전달하여 해당 페이지에서 파일을 열 수 있도록 합니다. 어떤 이유로든 앱이 시작되면 매퍼에서 들어오는 URI를 원래 상태로 반환합니다.

다음 코드에서는 URI 매퍼가 App.xaml.cs 파일에서 InitializePhoneApplication 메서드의 App 개체에 할당되는 방법을 보여 줍니다.


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


실행된 페이지는 페이지 NavigationContext 개체의 QueryString 속성을 사용하여 페이지를 실행한 URI의 모든 매개 변수에 액세스할 수 있습니다. 다음 예제에서는 fileToken 매개 변수의 값을 URI에서 추출하여 나중에 사용하도록 변수에 할당하는 방법을 보여 줍니다. 이 코드는 샘플의 RoutePage.xaml.cs 파일에서 가져온 것입니다.


// 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);
    }
}


SD 카드에 있는 파일의 경로가 sdFilePath이라는 매개 변수를 사용하여 MainPage.xaml에서 RoutePage.xaml로 전달됩니다. 해당 코드는 6단계에서 설명합니다.

파일 연결에서는 시작할 파일에 액세스하는 데 사용할 수 있는 fileToken 토큰을 앱 시작 URI에 포함합니다. 이전 단계에 표시된 대로 토큰을 URI 매퍼에서 페이지로 복사하여 페이지에서 파일에 액세스할 수 있도록 합니다. 파일을 사용하기 전에 CopySharedFileAsync를 사용하여 앱의 로컬 폴더에 복사합니다. 파일을 복사하기 전에 파일 이름에 액세스하려면 페이지 또는 URI 매퍼에서 GetSharedFileName 메서드를 호출할 수 있습니다. 샘플의 RoutePage.xaml에서 ProcessExternalGPXFile 메서드는 토큰을 사용하여 파일을 앱의 로컬 폴더에 복사합니다.


// 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());
}


이 예제에 표시된 ReadGPXFile 메서드는 경로 데이터를 처리하여 지도 컨트롤에 그립니다. 앱에서 지도 사용에 대한 자세한 내용은 Windows Phone 8의 지도 및 탐색을 참조하세요.

경로 매퍼 샘플에서는 SD 카드 기능을 두 가지 별도의 부분 즉, SD 카드 스캔과 Path에서 파일 열기로 구분합니다. 다음 코드에서 앱은 SD 카드에서 GPX 파일을 스캔하고 해당 파일 경로를 Routes라는 ObservableCollection<T>에 저장합니다. MainPage.xaml에서 RoutesgpxFilesListBox라는 ListBox에 바인딩되어 앱이 SD 카드에 있는 GPX 파일의 이름을 표시할 수 있도록 합니다.


// 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.");
}


사용자가 gpxFilesListBox에 표시된 GPX 파일을 탭하면 MainPage.xaml에서 RoutePage.xaml을 시작하고 파일 경로를 URI 매개 변수로 전달합니다. gpxFilesListBoxRoutes에 바인딩되고 RoutesExternalStorageFile 형식이므로 gpxFilesListBox_SelectionChanged_1 이벤트 처리기에서 반환하는 sender 매개 변수를 사용하여 SD 카드 파일 경로에 액세스할 수 있습니다. 다음과 같이 Path는 URI를 만들 때 액세스합니다.


// 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));
    }
}


마지막으로 RoutePage.xaml에서 ProcessSDGPXFile 메서드는 경로를 사용하여 SD 카드에서 파일을 가져오고 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.");
    }
}


ReadGPXFiles에서 지도 컨트롤에 경로를 표시하는 방법에 대한 자세한 내용을 보려면 경로 매퍼 샘플을 다운로드하세요.

Microsoft는 MSDN 웹 사이트에 대한 귀하의 의견을 이해하기 위해 온라인 설문 조사를 진행하고 있습니다. 참여하도록 선택하시면 MSDN 웹 사이트에서 나가실 때 온라인 설문 조사가 표시됩니다.

참여하시겠습니까?
표시:
© 2014 Microsoft