【问题标题】:Check if user added new music on Windows Phone 8.1检查用户是否在 Windows Phone 8.1 上添加了新音乐
【发布时间】:2014-05-20 08:56:05
【问题描述】:

我正在尝试了解自上次使用应用后用户是否将新音乐添加到手机上的音乐文件夹中。

我尝试通过检查 Music 文件夹的 DateModified 来做到这一点(向手机添加新音乐时会在计算机上正确更新):

async void GetModifiedDate ()
{
    BasicProperties props = await KnownFolders.MusicLibrary.GetBasicPropertiesAsync();
    Debug.WriteLine("DATEMODIFIED: " + props.DateModified.ToString());
}

不幸的是,这会返回:

DATEMODIFIED: 1/1/1601 1:00:00 AM +01:00

是我做错了什么还是有其他快速方法可以检查用户是否添加了新音乐?

【问题讨论】:

    标签: c# windows-8 windows-8.1 windows-phone-8.1


    【解决方案1】:

    KnownFolders.MusicLibraryvirtual location。因此我认为,获取它的属性可能是个问题。

    另一个问题是DateModified 可能是个坏主意,因为当用户添加文件时它可能保持不变。你不能转发它。 (some information)。您可以检查一下 - 当我尝试在文件夹中移动文件时,它们的 DateModified 没有改变。

    因此,在这种情况下,恐怕您必须在 MusicLibrary 中列出您的文件,然后再决定保存哪些内容以供将来比较。文件大小的总和可能是个好主意,因此两个不同的音乐文件大小相同的可能性很小。这还取决于您是否希望在用户将文件从一个文件夹移动到另一个文件夹时收到通知(总大小不会改变)。如果你想确保更多,你可以记住Tuple<file.FolderRelativeId, fileSize> 的整个列表(对于 ecample)。

    由于 Windows Phone 尚不支持 FileQueries,您必须递归检索文件,简单代码如下所示:

    // first - a method to retrieve files from folder recursively 
    private async Task RetriveFilesInFolder(List<StorageFile> list, StorageFolder parent)
    {
        foreach (var item in await parent.GetFilesAsync()) list.Add(item);
        foreach (var item in await parent.GetFoldersAsync()) await RetriveFilesInFolder(list, item);
    }
    
    private async Task<List<StorageFile>> GetFilesInMusic()
    {
        StorageFolder folder = KnownFolders.MusicLibrary;
        List<StorageFile> listOfFiles = new List<StorageFile>();
        await RetriveFilesInFolder(listOfFiles, folder);
        return listOfFiles;
    }
    

    获得文件列表后,您可以决定记住哪些内容,以便在下次应用启动时进行进一步比较。

    【讨论】:

    • +1 获取所有文件的一种更懒惰的方法是使用 KnownFolders.MusicLibrary.GetFilesAsync(CommonFileQuery.OrderByName);默认情况下这是一个深度查询。它将在一个查询中获取所有文件。
    • @Adam 是的,但我遇到了一些problems with CommonFileQuery - 它不仅返回文件夹和子文件夹中的文件,还返回其他文件。我列出了手机和 SD 上的所有文件。
    • 是的,这是预期的行为。它是媒体的“设备深度”。这样做的目的是让您不必遍历文件系统来查找 SD 卡 + 手机上的所有媒体,这可能会非常慢。
    • @Adam 我同意这是一个很好的行为,但我怀疑这是预期的(这种情况下的描述也具有误导性)。如果我想搜索整个系统,那么我会使用 Query: Music 和 RemovableStorage 文件夹进行搜索。例如,在这种情况下,我无法轻松搜索特定文件夹及其子文件夹中的所有音乐文件 - 它总是会抛出每个文件夹中的所有文件。我认为它不应该那样工作。
    【解决方案2】:

    您可以改为检查文件夹大小:

    ulong musicFolderSize = (ulong)ApplicationData.Current.LocalSettings.Values["musicFolderSize"];
    
    BasicProperties props = await KnownFolders.MusicLibrary.GetBasicPropertiesAsync();
    if (props.Size != musicFolderSize)
    {
        //  ...
        ApplicationData.Current.LocalSettings.Values["musicFolderSize"] = props.Size;
    }
    

    【讨论】:

    • 好主意。不幸的是,它总是返回 0。我找不到比比较 MusicLibrary 中的 StorageItems 数量更好的解决方案。
    【解决方案3】:

    添加到 Romansz 的答案:

    保证您知道文件更改的唯一方法是跟踪设备上的文件,然后比较两次启动之间是否有更改。

    获取所有文件的一种更懒惰的方法是使用KnownFolders.MusicLibrary.GetFilesAsync(CommonFileQuery.OrderByName);,默认情况下这是一个深度查询。它将在一个查询中获取所有文件,但在大量目录上可能会非常慢。然后,您必须按所示浏览所有文件

            //cache the virtual storage folder for the loop
            StorageFolder musicLibrary = KnownFolders.MusicLibrary; 
            uint stepSize= 50;
            uint startIndex = 0;
            while (true)
            {
                IReadOnlyList<StorageFile> files = await musicLibrary.GetFilesAsync(CommonFileQuery.OrderByName,startIndex,stepSize);
    
                foreach (var file in files)
                {
                    //compare to see if file is in your list
                }
                if (files.Count < stepSize) break; 
                startIndex += stepSize;
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多