• 37、RemoveableStorage


    namespace Windows.Storage
    {   
        // 提供对其中包含用户内容的常见位置的访问。
        public static class KnownFolders
        {        
           // 获取文档库。
            // 返回结果:  文档库。
            public static StorageFolder DocumentsLibrary { get; }
              
           // 获取家庭组文件夹。
            // 返回结果: 家庭组文件夹。
            public static StorageFolder HomeGroup { get; }
            
            // 获取媒体服务器(数字生活网络联盟(DLNA))设备文件夹。       
            // 返回结果:  媒体服务器 (DLNA) 设备的文件夹。
            public static StorageFolder MediaServerDevices { get; }
          
           // 获取音乐库。
            // 返回结果:   音乐库。
            public static StorageFolder MusicLibrary { get; }
            
           // 获取图片库。
            // 返回结果:  图片库。
            public static StorageFolder PicturesLibrary { get; }
           
           // 获取可移动的设备文件夹。
            // 返回结果: 可移动的设备文件夹。
            public static StorageFolder RemovableDevices { get; }
          
           //获取视频库。
            // 返回结果: 视频库。
            public static StorageFolder VideosLibrary { get; }
        }
    }

    1、List removeable storage devices:

          使用  KnownFolders.RemovableDevices.GetFoldersAsync()  方法,遍历并显示插在电脑上的移动存储设备。

          有两种方法获得移动存储设备:

              1)可以使用 Removeable Devices KnownFolder 去获得当前连接到计算机的存储设备的 快照 (作为 StorageFolders )(本示例讲述)。

              2)另一种方法是使用 Windows.Devices.Enumeration (在 2、中讲述)。

       Windows.Devices.Enumeration 支持更高级的操作,比如为设备订阅、删除、更新等。

    操作截图:

    点击按钮,输出结果(我的移动硬盘的三个分区):

    页面的 xaml :

     <Button x:Name="ScenarioInput"  Content="List Storages" Click="ListStorages_Click"/>
    
     <TextBlock x:Name="ScenarioOutput" TextWrapping="Wrap" />

    相应的 C# :

     async private void ListStorages_Click(object sender, RoutedEventArgs e)
            {
                ScenarioOutput.Text = "";
    
                // Known folder 找到所有存储设备
                //GetFoldersAsync() : 在当前文件夹中获取文件夹。
                 var removableStorages = await KnownFolders.RemovableDevices.GetFoldersAsync();
                if (removableStorages.Count > 0)
                {
                    // 显示每个存储设备
                    foreach (StorageFolder storage in removableStorages)
                    {
                        ScenarioOutput.Text += storage.DisplayName + "\n";
                    }
                }
                else
                {
                    //没有移动存储连接到电脑
                 }
            }


    2、Send file to storage device :

        把一张图片文件传输到移动存储设备里。

    操作截图:

    点击按钮,在列表中列举出移动设备的分区:

    选中一个分区,然后从本地图片库选择一张图片:

    点击打开后,这张图片便被拷贝到移动设备中:

    页面的 xaml :

    //检索移动设备
    <Button x:Name="ScenarioInput"  Content="Send Image"  Click="SendImage_Click"/>
    
    
    //显示移动设备的所有分区
    <ListBox x:Name="DeviceList" Margin="0,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"
        ScrollViewer.HorizontalScrollBarVisibility="Auto" Tapped="DeviceList_Tapped" MaxHeight="125">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.Resources>
            <Style TargetType="ListBoxItem">
                <Setter Property="Padding" Value="8,10,20,10"/>
            </Style>
        </ListBox.Resources>
    </ListBox>


    相应的 C# :

    //声明在页面的全局变量
    // 表示设备的集合。
    private DeviceInformationCollection _deviceInfoCollection = null;

    按钮的单击事件 :

     async private void SendImage_Click(object sender, RoutedEventArgs e)
     {
         await ShowDeviceSelectorAsync();
     }
    async private Task ShowDeviceSelectorAsync()
            {
                _deviceInfoCollection = null;
    
                //使用 Windows.Devices.Enumeration 类寻找所有的存储设备
                // GetDeviceSelector() : 标识存储设备的高级查询语法 (AQS) 字符串。
                //FindAllAsync() : 枚举与指定的高级查询语法 (AQS) 字符串相匹配的 DeviceInformation 对象。
                _deviceInfoCollection = await DeviceInformation.FindAllAsync(StorageDevice.GetDeviceSelector());
                if (_deviceInfoCollection.Count > 0)
                {
                    var items = new List<object>();
                    foreach (DeviceInformation deviceInfo in _deviceInfoCollection)
                    {
                        items.Add(new
                        {
                            Name = deviceInfo.Name,
                        });
                    }
                    DeviceList.ItemsSource = items;
                    DeviceSelector.Visibility = Visibility.Visible;
                }
                else
                {
                   //没有移动存储连接到电脑
                }
            }


     

    当单击列表中的设备时:

    async private void DeviceList_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
            {
                DeviceSelector.Visibility = Visibility.Collapsed;
                if (_deviceInfoCollection == null)
                {
                    return; // 没有填充
                }
    
                var deviceInfo = _deviceInfoCollection[DeviceList.SelectedIndex];
                await SendImageFileToStorageAsync(deviceInfo);
            }
     async private Task SendImageFileToStorageAsync(DeviceInformation deviceInfoElement)
            {
                //判断当前应用的视图是否处于 snapped 状态,如果是,则尝试 unsnap 当前的窗口,从而打开文件选择器
                  var currentState = Windows.UI.ViewManagement.ApplicationView.Value;
                if (currentState == Windows.UI.ViewManagement.ApplicationViewState.Snapped 
    && !Windows.UI.ViewManagement.ApplicationView.TryUnsnap()) { //请使当前应用的视图是处于 unsnapped 状态 } else { // 启动选择器选择一个图像文件 var picker = new FileOpenPicker { FileTypeFilter = { ".jpg", ".png", ".gif" }, SuggestedStartLocation = PickerLocationId.PicturesLibrary }; var sourceFile = await picker.PickSingleFileAsync(); if (sourceFile != null) { // 把选中的设备信息元素转换为一个 StorageFolder 对象 //Id : 表示 DeviceInformation 的标识的字符串。 //FromId() : 基于某个存储项的接口 ID 获取该存储项。 var storage = StorageDevice.FromId(deviceInfoElement.Id); var storageName = deviceInfoElement.Name; // 拷贝文件 + sourceFile.Name + " to " + storageName await CopyFileToFolderOnStorageAsync(sourceFile, storage); } else { //没有选择文件 } } }

    把选择的图片文件拷贝到存储分区的第一个文件夹内:

     async private Task CopyFileToFolderOnStorageAsync(StorageFile sourceFile, StorageFolder storage)
            {
                var storageName = storage.Name;
    
               // 构建一个指向当前存储的第一个子文件夹的索引
                // 默认的(浅)查询应该足够找到第一层次的子文件夹。
                //如果第一个层次的子文件夹不是可写的,一个深查询+递归复制可能是必要的。
              //在当前文件夹中获取文件夹。
                var folders = await storage.GetFoldersAsync();
                if (folders.Count > 0)
                {
                    var destinationFolder = folders[0];
                    var destinationFolderName = destinationFolder.Name;
    
                    //尝试向第一个子文件夹中拷贝文件
                    try
                    {
                       //NameCollisionOption.GenerateUniqueName :  重命名、移动或复
                       //制具有自动生成的唯一名称的文件或文件夹。此唯一名称是通过向要重
                       //命名、移动或复制的文件或文件夹的名称附加一个数字而生成的。
                        var newFile = await sourceFile.CopyAsync(destinationFolder, 
    sourceFile.Name, NameCollisionOption.GenerateUniqueName);
    //文件 newFile.Name destinationFolderName 在 storageName文件夹中创建了 } catch (Exception e) { //复制文件失败,可能存储不允许在顶级目录下发送文件 } } else { //没有找到子文件夹 } }


    3、Get image file from storage device :

          在移动存储设备中查找并显示第一个可用的图片文件。

    操作截图:

    点击按钮,把移动设备的所有分区显示在下面的列表中:

    选择第二个分区,同时检索该分区下的第一个图片文件,并显示:

    页面的 xaml :

    <Button x:Name="ScenarioInput"  Content="Get Image"  Click="GetImage_Click"/>
    
    //显示移动设备中的所有分区
      <ListBox x:Name="DeviceList" Margin="0,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"
          ScrollViewer.HorizontalScrollBarVisibility="Auto" Tapped="DeviceList_Tapped" MaxHeight="125">
          <ListBox.ItemTemplate>
              <DataTemplate>
                  <TextBlock Text="{Binding Name}"/>
              </DataTemplate>
          </ListBox.ItemTemplate>
          <ListBox.Resources>
              <Style TargetType="ListBoxItem">
                  <Setter Property="Padding" Value="8,10,20,10"/>
              </Style>
          </ListBox.Resources>
      </ListBox>
    
    
    
    //显示选中分区中的第一个文件图片
     <Image x:Name="ScenarioOutputImage"  AutomationProperties.Name="A placeholder image" Source="Assets/placeholder-sdk.png"

    相应的 C# :

    //按钮的单击事件
     async private void GetImage_Click(object sender, RoutedEventArgs e)
            {
                await ShowDeviceSelectorAsync();
            }
            //显示所有的移动设备的分区
            async private Task ShowDeviceSelectorAsync()
            {
                _deviceInfoCollection = null;
    
                // 使用 Windows.Devices.Enumeration 类枚举所有的分区
                  _deviceInfoCollection = await DeviceInformation.FindAllAsync(StorageDevice.GetDeviceSelector());
                if (_deviceInfoCollection.Count > 0)
                {
                    var items = new List<object>();
                    foreach (DeviceInformation deviceInfo in _deviceInfoCollection)
                    {
                        items.Add(new
                        {
                            Name = deviceInfo.Name,
                        });
                    }
                    DeviceList.ItemsSource = items;
                    DeviceSelector.Visibility = Visibility.Visible;
                }
            }

    选择一个分区:

     async private void DeviceList_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
            {
                DeviceSelector.Visibility = Visibility.Collapsed;
                if (_deviceInfoCollection == null)
                {
                    return; 
                }
    
                var deviceInfo = _deviceInfoCollection[DeviceList.SelectedIndex];
                await GetFirstImageFromStorageAsync(deviceInfo);
            }
    async private Task GetFirstImageFromStorageAsync(DeviceInformation deviceInfoElement)
            {
                
                var storage = StorageDevice.FromId(deviceInfoElement.Id);
                var storageName = deviceInfoElement.Name;
    
                // 构造查询的图像文件
                 var queryOptions = new QueryOptions(CommonFileQuery.OrderByName, new List<string> { ".jpg", ".png", ".gif" });
                var imageFileQuery = storage.CreateFileQueryWithOptions(queryOptions);
    
                //返回由对象 storageFile 表示的文件列表(类型 IVectorView)
                 var imageFiles = await imageFileQuery.GetFilesAsync();
                if (imageFiles.Count > 0)
                {
                    var imageFile = imageFiles[0];
                  
                    await DisplayImageAsync(imageFile);
                }          
            }
     async private Task DisplayImageAsync(StorageFile imageFile)
            {
                //返回作为 BasicProperties 对象的当前文件的基本属性。
                 var imageProperties = await imageFile.GetBasicPropertiesAsync();
                if (imageProperties.Size > 0)
                {
                   // Displaying: imageFile.Name , date modified: imageProperties.DateModified, size:  imageProperties.Size bytes
                   //  在文件中打开一个随机访问流。
                    var stream = await imageFile.OpenAsync(FileAccessMode.Read);
    
                    //  应该在 UI 线程调用 BitmapImage.SetSource 方法
                    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        var bitmap = new BitmapImage();
                        bitmap.SetSource(stream);
                        ScenarioOutputImage.SetValue(Image.SourceProperty, bitmap);
                    });
                }           
            }


    4、Get image file from camera or camera memory (Autoplay) :

      Finds and displays the first available image file (.jpg, .png, or .gif) on the camera or camera memory. To use this scenario, choose this app from the AutoPlay prompt when connecting a camera or camera memory.

    (略)

  • 相关阅读:
    案例分析
    202103226-1 编程作业
    阅读任务
    准备工作
    结对作业
    案列分析
    202103226-1 编程作业
    《构建之法》有感
    准备工作
    案例分析作业
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/2721656.html
Copyright © 2020-2023  润新知