Come ormai noto, Windows Phone non permette l'esecuzione multipla di applicazioni, ma esegue solo quella in foreground scelta dall'utente. Il modello scelto tutela l'utente dando la possibilità allo sviluppatore di eseguire task in background ad intervalli regolari, con il pieno controllo da parte dell'utente che può scegliere se disabilitarli o meno.
Se nella propria applicazione la necessità è quella di scaricare o caricare contenuti dal web e questi file sono di grandi dimensione, vi è la possibilità, con Windows Phone 7.5, di effettuare queste operazioni in background, senza che l'applicazione sia attiva. Questo è possibile grazie ad un engine del sistema che prende in carico le richieste di tutte le applicazioni e le gestisce in base alle impostazioni dell'utente e allo stato del telefono.
Per usufruire di questa funzionalità, utile anche quando l'applicazione è in foreground, perché si vuole dare libertà all'utente di entrare e uscire dall'app, non bisogna più usare HttpWebRequest/WebClient, ma una nuova classe di nome BackgroundTransferRequest. La si istanzia passando l'URI da scaricare e impostando il percorso dell'isolated storaged dove salvare il file. Poiché il download è gestito dal sistema, anche quando l'app non è attiva, non è possibile gestire manualmente lo stream, ma è il sistema che se ne occupa e deposita il file nell'isolated storage. Ecco quindi come creare la richiesta:
// Creo la nuova richiesta BackgroundTransferRequest request = new BackgroundTransferRequest(new Uri("https://www.winphoneitalia.com/")); request.Method = "GET"; // Posizione dove salvare il file request.DownloadLocation = new Uri("/shared/transfers/file.html", UriKind.Relative); // Concesso il trasferimento con batteria request.TransferPreferences = TransferPreferences.AllowBattery; // Gestisco gli eventi e lo stato della richiesta HandleRequest(request); // Affido la richiesta all'engine di sistema BackgroundTransferService.Add(request);
Tra le informazioni che è possibile impostare vi è la proprietà TransferPreferences che permette di indicare se il download può essere effettuato anche quando il dispositivo non è in carica, oppure quando il dispositivo non è connesso ad una rete wi-fi. Normalmente, infatti, il download inizia e prosegue solo quando il dispositivo è in carica e connesso in wi-fi, con lo scopo di preservare la batteria. Il download dev'essere inoltre obbligatoriamente scaricato nella cartella di sistema /shared/transfers/. Nell'esempio precedente si usa poi BackgroundTransferService per affidare la richiesta al sistema. A questo punto è possibile gestire gli eventi di essa per conoscere lo stato del trasferimento e quando è terminato.
private void HandleRequest(BackgroundTransferRequest request) { // Gestisco gli eventi request.TransferStatusChanged += request_TransferStatusChanged; request.TransferProgressChanged += request_TransferProgressChanged; // Processo lo stato corrente ProcessStatus(request); } void request_TransferProgressChanged(object sender, BackgroundTransferEventArgs e) { Debug.WriteLine("{0}/{1}", e.Request.BytesReceived, e.Request.TotalBytesToReceive); } void request_TransferStatusChanged(object sender, BackgroundTransferEventArgs e) { ProcessStatus(e.Request); }
La funzione ProcessStatus controlla la proprietà TransferStatus per conoscere lo stato della richiesta. Si esegue questo controllo immediatamente e sull'evento TransferStatusChanged per reagire al cambio di stato. Se lo stato è completato è possibile poi accedere all'isolated storage per leggere il file come normalmente è possibile fare con tutti gli altri.
private static void ProcessStatus(BackgroundTransferRequest request) { switch (request.TransferStatus) { case TransferStatus.Completed: // Rimuovo sempre la richiesta dall'engine BackgroundTransferService.Remove(request); // Gestisco gli eventuali errori if (request.TransferError != null) MessageBox.Show("Errore: " + request.TransferError.Message); else if (request.StatusCode != 200 && request.StatusCode != 206) MessageBox.Show("Errore nel trasferimento: " + request.StatusCode); else { MessageBox.Show("Download completato"); } break; case TransferStatus.Waiting: break; case TransferStatus.WaitingForWiFi: break; case TransferStatus.WaitingForExternalPower: break; case TransferStatus.Transferring: break; } }
Le proprietà StatusCode e TransferError permettono di conoscere l'esito della richiesta e agire di conseguenza in base al flusso della propria applicazione.
Poiché l'utente potrebbe chiudere e riaprire l'app, nell'entry point dell'applicazione è opportuno richiamare HandleRequest su tutte le richieste attive, in modo da intercettare gli eventi e controllare lo stato delle richieste già in corso.
// Gestisco tutti i trasferimenti attivi foreach (BackgroundTransferRequest request in BackgroundTransferService.Requests) { HandleRequest(request); }
Infine, se si usa questa tecnica, le guidelines prevedono che l'utente venga avvisato ed eventualmente gli venga data la facoltà di scegliere la modalità di trasferimento del file.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare il metodo ExceptBy per eseguire operazione di sottrazione tra liste
Eseguire script pre e post esecuzione di un workflow di GitHub
Effettuare il refresh dei dati di una QuickGrid di Blazor
Conoscere il rendering Server o WebAssembly a runtime in Blazor
Migliorare l'organizzazione delle risorse con Azure Policy
Eseguire i worklow di GitHub su runner potenziati
Recuperare automaticamente un utente e aggiungerlo ad un gruppo di Azure DevOps
Gestione dei nomi con le regole @layer in CSS
Ottimizzare le pull con Artifact Cache di Azure Container Registry
Cambiare la chiave di partizionamento di Azure Cosmos DB
Eliminare una project wiki di Azure DevOps
Ottenere un token di accesso per una GitHub App