Condividi tramite


File e cartelle nelle raccolte Musica, Immagini e Video

Aggiungere cartelle esistenti di musica, immagini o video alle librerie corrispondenti. È anche possibile rimuovere cartelle dalle raccolte, ottenere l'elenco di cartelle in una raccolta e individuare 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 l'app o una delle app predefinite. Ad esempio, la Raccolta Immagini include la cartella Immagini nota per impostazione predefinita. L'utente può aggiungere cartelle o rimuoverle dalla raccolta immagini usando l'app o l'app Foto predefinita.

Prerequisiti

  • Informazioni sulla 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 informazioni su come scrivere app asincrone in C++, vedere Programmazione asincrona in C++.

  • Autorizzazioni di accesso alla posizione

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

    • Libreria Musicale
    • Libreria Immagini
    • Libreria Video

    Per altre informazioni, vedere Autorizzazioni di accesso ai file.

Ottenere un riferimento a una libreria

Annotazioni

Ricordarsi 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. Fornire il valore corrispondente dall'enumerazione KnownLibraryId.

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

Ottenere l'elenco delle cartelle in una raccolta

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

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

Trovare la cartella di una raccolta in cui i nuovi file vengono salvati 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 raccolta

Per aggiungere una cartella a una libreria, chiamare il StorageLibrary.RequestAddFolderAsync. Prendendo la raccolta immagini come esempio, la chiamata di questo metodo fa sì che un selettore di cartelle venga visualizzato all'utente con un pulsante Aggiungi questa cartella a Immagini. Se l'utente seleziona una cartella, la cartella rimane nel percorso originale su disco e diventa un elemento nella proprietà StorageLibrary.Folders (e nell'app Foto predefinita), ma la cartella non viene visualizzata come figlio della cartella Immagini in Esplora file.

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

Rimuovere una cartella da una raccolta

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 chiami 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 nel percorso 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 raccolta

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 della libreria multimediale

Un dispositivo fornisce cinque percorsi predefiniti per gli utenti e le app per archiviare i file multimediali. Le app integrate archiviano sia i contenuti creati dall'utente che quelli 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 audiobook.

  • 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. Per altre informazioni, vedere Accedere alla scheda SD.

Consultazione delle 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 comunque 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 raccolta 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 un'immagine a bassa risoluzione che un'immagine ad alta risoluzione di ogni immagine, le query profonde restituiscono solo l'immagine a bassa risoluzione.

Il Rullino fotografico e la cartella Immagini salvate non supportano le query approfondite.

Apertura di una foto nell'applicazione che l'ha scattata

Se vuoi consentire all'utente di aprire nuovamente una foto più avanti nell'app che l'ha acquisita, puoi salvare CreatorAppId con i metadati della foto usando codice simile all'esempio seguente. In questo esempio testPhoto è un 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 raccolta 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 riescono 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 tramite. 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);
            }
        }
    }
}