File e cartelle nelle raccolte Musica, Immagini e Video

Aggiungere cartelle esistenti di musica, immagini o video alle librerie corrispondenti. Puoi anche rimuovere cartelle dalle raccolte, ottenere l'elenco di cartelle in una raccolta e scoprire foto, musica e video archiviati.

Una libreria è una raccolta virtuale di cartelle, che include una cartella nota per impostazione predefinita e qualsiasi altra cartella aggiunta dall'utente alla raccolta usando la propria app o una delle app predefinite. Ad esempio, la libreria Immagini include la cartella nota Immagini per impostazione predefinita. L'utente può aggiungere cartelle o rimuoverle dalla libreria Immagini usando la propria app o l'app Foto predefinita.

Prerequisiti

  • Familiarità con la programmazione asincrona per le app UWP (Universal Windows Platform)

    Per informazioni su come scrivere app asincrone in C# o Visual Basic, vedere Chiamare API asincrone in C# o Visual Basic. Per scoprire come scrivere app asincrone in C++, vedere Programmazione asincrona in C++.

  • Autorizzazioni di accesso al percorso

    In Visual Studio aprire il file manifesto dell'app in Finestra di progettazione manifesto. Nella pagina Funzionalità selezionare le librerie gestite dall'app.

    • Catalogo musicale
    • Raccolta di immagini
    • Catalogo video

    Per altre informazioni, vedere Autorizzazioni accesso file.

Ottenere un riferimento a una libreria

Nota

Ricordare di dichiarare la funzionalità appropriata. Per ulteriori informazioni, vedere Dichiarazioni di funzionalità delle app.  

Per ottenere un riferimento alla libreria Musica, Immagini o Video dell'utente, chiamare il metodo StorageLibrary.GetLibraryAsync. Specificare il valore corrispondente dall'enumerazione KnownLibraryId.

var myPictures = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);

Ottenere l'elenco delle cartelle in una libreria

Per ottenere l'elenco delle cartelle in una libreria, ottenere il valore della proprietà StorageLibrary.Folders.

using Windows.Foundation.Collections;
IObservableVector<Windows.Storage.StorageFolder> myPictureFolders = myPictures.Folders;

Ottenere la cartella in una libreria in cui vengono salvati nuovi file per impostazione predefinita

Per ottenere la cartella in una libreria in cui vengono salvati nuovi file per impostazione predefinita, ottenere il valore della proprietà StorageLibrary.SaveFolder.

Windows.Storage.StorageFolder savePicturesFolder = myPictures.SaveFolder;

Aggiungere una cartella esistente a una libreria

Per aggiungere una cartella a una libreria, chiamare StorageLibrary.RequestAddFolderAsync. Prendendo la libreria Immagini come esempio, la chiamata a questo metodo determina la visualizzazione di una selezione cartelle all'utente con un pulsante Aggiungi questa cartella a Immagini. Se l'utente seleziona una cartella, la cartella rimane nella posizione originale sul disco e diventa un elemento nella proprietà StorageLibrary.Folders (e nell'app Foto predefinita), ma non viene visualizzata come elemento figlio della cartella Immagini in Esplora file.

Windows.Storage.StorageFolder newFolder = await myPictures.RequestAddFolderAsync();

Rimuovere una cartella da una libreria

Per rimuovere una cartella da una libreria, chiamare il metodo StorageLibrary.RequestRemoveFolderAsync e specificare la cartella da rimuovere. È possibile usare StorageLibrary.Folders e un controllo ListView (o simile) per consentire all'utente di selezionare una cartella da rimuovere.

Quando si chiama StorageLibrary.RequestRemoveFolderAsync, l'utente visualizza una finestra di dialogo di conferma che indica che la cartella "non verrà più visualizzata in Immagini, ma non verrà eliminata". Ciò significa che la cartella rimane nella posizione originale sul disco, viene rimossa dalla proprietà StorageLibrary.Folders e non sarà più inclusa nell'app Foto predefinita.

Nell'esempio seguente si presuppone che l'utente abbia selezionato la cartella da rimuovere da un controllo ListView denominato lvPictureFolders.

bool result = await myPictures.RequestRemoveFolderAsync(folder);

Ricevere una notifica delle modifiche all'elenco di cartelle in una libreria

Per ricevere notifiche sulle modifiche apportate all'elenco di cartelle in una raccolta, registrare un gestore per l'evento StorageLibrary.DefinitionChanged della libreria.

myPictures.DefinitionChanged += MyPictures_DefinitionChanged;

void HandleDefinitionChanged(Windows.Storage.StorageLibrary sender, object args)
{
    // ...
}

Cartelle del catalogo multimediale

Un dispositivo fornisce cinque percorsi predefiniti per gli utenti e le app in cui archiviare i file multimediali. Le app predefinite archiviano sia i supporti creati dall'utente che i supporti scaricati in queste posizioni.

Le posizioni sono:

  • Cartella Immagini. Contiene immagini.

    • Cartella Rullino fotocamera.. Contiene foto e video dalla fotocamera incorporata.

    • Cartella Immagini salvate. Contiene immagini salvate dall'utente da altre app.

  • Cartella Musica. Contiene canzoni, podcast e audiolibri.

  • Cartella Video. Contiene video.

Gli utenti o le app possono anche archiviare file multimediali all'esterno delle cartelle della libreria multimediale nella scheda SD. Per trovare un file multimediale in modo affidabile sulla scheda SD, analizzare il contenuto della scheda SD o chiedere all'utente di individuare il file usando una selezione file. Vedere Accedere alla scheda SD per altre informazioni.

Esecuzione di query sulle librerie multimediali

Per ottenere una raccolta di file, specificare la libreria e il tipo di file desiderati.

using Windows.Storage;
using Windows.Storage.Search;

private async void getSongs()
{
    QueryOptions queryOption = new QueryOptions
        (CommonFileQuery.OrderByTitle, new string[] { ".mp3", ".mp4", ".wma" });

    queryOption.FolderDepth = FolderDepth.Deep;

    Queue<IStorageFolder> folders = new Queue<IStorageFolder>();

    var files = await KnownFolders.MusicLibrary.CreateFileQueryWithOptions
      (queryOption).GetFilesAsync();

    foreach (var file in files)
    {
        // do something with the music files
    }
}

I risultati delle query includono archiviazione interna e rimovibile

Gli utenti possono scegliere di archiviare i file per impostazione predefinita nella scheda SD facoltativa. Le app, tuttavia, possono rifiutare esplicitamente di consentire l'archiviazione dei file nella scheda SD. Di conseguenza, le librerie multimediali possono essere suddivise nell'archiviazione interna del dispositivo e nella scheda SD.

Non è necessario scrivere codice aggiuntivo per gestire questa possibilità. I metodi nello spazio dei nomi Windows.Storage che eseguono query su cartelle note combinano in modo trasparente i risultati della query da entrambe le posizioni. Non è necessario specificare la funzionalità removableStorage nel file manifesto dell'app per ottenere questi risultati combinati.

Prendere in considerazione lo stato dello spazio di archiviazione del dispositivo illustrato nell'immagine seguente:

immagini sul telefono e sulla scheda SD

Se si esegue una query sul contenuto della libreria immagini chiamando await KnownFolders.PicturesLibrary.GetFilesAsync(), i risultati includono sia internalPic.jpg che SDPic.jpg.

Uso delle foto

Nei dispositivi in cui la fotocamera salva sia una versione a bassa risoluzione che una ad alta risoluzione di ogni immagine, le query profonde restituiscono solo l'immagine a bassa risoluzione.

Le cartelle Rullino della fotocamera e Immagini salvate non supportano le query approfondite.

Apertura di una foto nell'app da cui è stata acquisita

Se si vuole consentire all'utente di aprire nuovamente una foto più avanti nell'app che l'ha acquisita, è possibile salvare il CreatorAppId con i metadati della foto usando un codice simile all'esempio seguente. In questo esempio testPhoto è uno StorageFile.

IDictionary<string, object> propertiesToSave = new Dictionary<string, object>();

propertiesToSave.Add("System.CreatorOpenWithUIOptions", 1);
propertiesToSave.Add("System.CreatorAppId", appId);

testPhoto.Properties.SavePropertiesAsync(propertiesToSave).AsyncWait();   

Uso dei metodi di flusso per aggiungere un file a una libreria multimediale

Quando si accede a una raccolta multimediale usando una cartella nota, ad esempio KnownFolders.PictureLibrary, e si usano metodi di flusso per aggiungere un file alla raccolta multimediale, è necessario assicurarsi di chiudere tutti i flussi aperti dal codice. In caso contrario, questi metodi non riusciranno ad aggiungere il file alla libreria multimediale come previsto perché almeno un flusso ha ancora un handle per il file.

Ad esempio, quando si esegue il codice seguente, il file non viene aggiunto alla libreria multimediale. Nella riga di codice, using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0)), sia il metodo OpenAsync che il metodo GetOutputStreamAt aprono un flusso. Tuttavia, solo il flusso aperto dal metodo GetOutputStreamAt viene eliminato come risultato dell'istruzione using. L'altro flusso rimane aperto e impedisce il salvataggio del file.

StorageFolder testFolder = await StorageFolder.GetFolderFromPathAsync(@"C:\test");
StorageFile sourceFile = await testFolder.GetFileAsync("TestImage.jpg");
StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("MyTestImage.jpg");
using (var sourceStream = (await sourceFile.OpenReadAsync()).GetInputStreamAt(0))
{
    using (var destinationStream = (await destinationFile.OpenAsync(FileAccessMode.ReadWrite)).GetOutputStreamAt(0))
    {
        await RandomAccessStream.CopyAndCloseAsync(sourceStream, destinationStream);
    }
}

Per usare correttamente i metodi di flusso per aggiungere un file alla libreria multimediale, assicurarsi di chiudere tutti i flussi aperti dal codice, come illustrato nell'esempio seguente.

StorageFolder testFolder = await StorageFolder.GetFolderFromPathAsync(@"C:\test");
StorageFile sourceFile = await testFolder.GetFileAsync("TestImage.jpg");
StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("MyTestImage.jpg");

using (var sourceStream = await sourceFile.OpenReadAsync())
{
    using (var sourceInputStream = sourceStream.GetInputStreamAt(0))
    {
        using (var destinationStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            using (var destinationOutputStream = destinationStream.GetOutputStreamAt(0))
            {
                await RandomAccessStream.CopyAndCloseAsync(sourceInputStream, destinationStream);
            }
        }
    }
}