• Programmazione Android
  • CORSI ONLINE
  • Web Agency

Logo

Corsi di programmazione web e mobile online
Navigation
  • Home
  • CORSI ONLINE
  • Tutorial Pratici
  • GUIDE COMPLETE
    • Corso completo di C
    • Corso videogame con Cocos2d
    • Programmazione Cocoa Touch
  • Sezioni
    • Libri e manuali
    • Tips & Tricks
    • Risorse utili
    • Strumenti di Sviluppo
    • Materiale OpenSource
    • Framework
    • Guide Teoriche
    • Guide varie
    • Grafica e Design
    • iPad
    • News
    • Video Tutorial
    • Windows Phone
  • Pubblicità
  • About
    • Chi siamo
    • Pubblicazioni
    • Collabora
    • Sostieni devAPP

Android: scaricare grandi file con il DownloadManager

By Giuseppe Maggi | on 5 Settembre 2017 | 0 Comment
Android
Android Tutorial

Tantissime funzionalità delle app mobile richiedono l’interazione con la Rete ed è proprio per tale motivo che il mondo Android dispone di molte librerie dedicate a questo tipo di attività (Volley, OkHttp, Retrofit ed altre ancora) ma per lo scaricamento di file di grandi dimensioni con protocollo HTTP si può ricorrere ad un servizio di sistema già pronto: il DownloadManager. Stiamo parlando del servizio chiamato in causa ogniqualvolta l’utente vuole scaricare sul dispositivo file di dimensioni considerevoli: l’andamento di tutta l’attività viene illustrato mediante notifiche status bar. Il vantaggio principale di questo meccanismo risiede nel completamento del download che viene portanto a termine superando tutte le situazioni possibili: fallimenti, disconnessioni e riavii del sistema.

Come funziona il DownloadManager

Per lavorare con il DownloadManager dobbiamo, per prima cosa, recuperare un’istanza del servizio:

DownloadManager manager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

Prepariamo poi una richiesta – classe Request – che specifica l’indirizzo del file da scaricare (fornito con un oggetto di classe Uri) ed altri dettagli come la cartella locale di salvataggio, la durata della notifica ed altro ancora

Uri uri=Uri.parse("http://www.miosito.it/file-grande-da-scaricare.pdf");

DownloadManager.Request request=new DownloadManager.Request(uri);
request.setTitle("File grande da scaricare");
// ulteriori configurazioni della richiesta

Infine, accodiamo la richiesta composta al DownloadManager

long download_id=manager.enqueue(request);

e da quel momento in poi lo scaricamento del file cessa di riguardare la nostra applicazione ma diventa compentenza del sistema. Il valore long ottenuto, download_id, è un riferimento univoco allo scaricamento con cui potremo indirizzare comandi al DownloadManager.

Uso di base

Vediamo subito un esempio base (il cui codice è disponibile qui) in cui sviluppiamo una semplice Activity che, al click del Floating Action Button, avvia lo scaricamento di un file PDF di alcuni megabyte di dimensione (abbiamo scelto il manuale di OrientDB). Non applicheremo alcuna personalizzazione al comportamento di default proprio perchè ci interessa vedere cosa, di suo, il DownloadManager fa.

Posizioniamo la permission INTERNET nel file AndroidManifest.xml affinchè l’app possa accedere alla rete:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="it.devapp.downloadmanagerexample">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
         ...
         ...
    </application>
</manifest>

Nel metodo onCreate, predisponiamo la richiesta in base all’URI e specifichiamo nome e descrizione che dovranno apparire nella notifica di scaricamento. Inoltre, richiediamo che quest’ultima non scompaia al termine del download. Tutta l’azione del DownloadManager inizia all’interno del listener legato al click del FloatingActionButton:

  • accodiamo la richiesta al DownloadManager;
  • conserviamo in una variabile long il riferimento univoco allo scaricamento;
  • impostiamo come azione della SnackBar la cancellazione dello scaricamento in corso, indicandolo semplicemente con il codice univoco di cui al punto precedente.

Questo il codice dell’Activity:

public class MainActivity extends AppCompatActivity {

    private Uri uri;
    private DownloadManager.Request request;
    private DownloadManager manager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // recuperiamo un riferimento al servizio
        manager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

        // definiamo l'URI da cui scaricare il file
        uri=Uri.parse("http://orientdb.com/docs/2.1/OrientDB-Manual.pdf");

        // Prepariamo la richiesta
        request=new DownloadManager.Request(uri);

        // titolo e descrizione che appariranno nella notifica
        request.setTitle("Manuale di OrientDB");
        request.setDescription("File PDF");

        // al termine dello scaricamento la notifica non scomparirà
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            // riferimento univoco al download
            final long download_id=manager.enqueue(request);
                
            Snackbar.make(view, "Download avviato...", Snackbar.LENGTH_LONG)
                    .setAction("Annulla", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {

                            // cliccando sull'Action otteniamo la cancellazione del download
                            manager.remove(download_id);
                        }
                    }).show();
            }
        });
    }

}

Questa è la SnackBar che apparirà all’avvio del download:

e questa la notifica che apparirà al termine

Il download eseguito risulterà tra quelli effettuati dal sistema tramite l’apposita app “Downloads” mentre, terminato lo scaricamento, potremo aprire il documento: trattandosi di PDF, verrà offerta la possibilità di farlo con una delle applicazioni installate.

Personalizzazione del comportamento

Oltre al comportamento standard, si può personalizzare le reazioni del DownloadManager nei momenti cruciali come il click sulla notifica (anche durante lo scaricamento) e al termine del download.

Questi due eventi verranno comunicati attraverso il sistema con due Intent corrispondenti alle costanti DownloadManager.ACTION_DOWNLOAD_COMPLETE e DownloadManager.ACTION_NOTIFICATION_CLICKED.

Per intercettare questi eventi si può usare una componente delle applicazioni Android appositamente dedicata, il BroadcastReceiver, che va implementato nel progetto come classe Java e segnalato nel file AndroidManifest.xml mediante un blocco come il seguente (all’interno del nodo <application>):

<receiver android:name=".OnCompleteReceiver"
            android:exported="true"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
            </intent-filter>
</receiver>

L’effetto del BroadcastReceiver è puramente di test consistendo nella sola visualizzazione di un Toast eppure dimostra come esso venga attivato dall’evento anche nel caso in cui l’Activity sia stata già chiusa.

public class OnCompleteReceiver extends BroadcastReceiver {
    public OnCompleteReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Fine dello scaricamento!!", Toast.LENGTH_LONG).show();
    }
}

Il BroadcastReceiver – ricordiamo – si presta alla gestione di moltissimi altri tipi di eventi e richiede la sola implementazione del metodo onReceive per gestire la situazione. Questo metodo lavora sul thread principale dell’applicazione pertanto, in caso di attività prolungate, è opportuno avviare un Service dedicato al loro svolgimento in modalità asincrona.

Dati relativi al DownloadManager

E’ inoltre interessante considerare che i dati relativi ai nostri scaricamenti sono disponibili tramite un Content Provider che il DownloadManager mette a disposizione. Tramite questo potremo sapere quali attività di scaricamento la nostra applicazione ha disposto, il loro stato, le dimensioni, titolo e descrizione applicati ed altro ancora.

Per avere tali informazioni, si dovrà utilizzare un oggetto DownloadManager.Query il quale con il metodo query fornirà un Cursor che potrà essere letto ed impiegato come siamo soliti fare nell’interazione con database:

DownloadManager manager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
...
...
DownloadManager.Query query=new DownloadManager.Query();
...
...
Cursor c=manager.query(query);

I campi utilizzabili tramite il Cursor sono disponibili come costanti nel DownloadManager ed hanno nomi che iniziano con il prefisso “COLUMN_”. Ad esempio, avremo COLUMN_TITLE per il titolo del download, COLUMN_ID per recuperare l’identificativo del download (che abbiamo trovato in precedenza nel codice Java sotto forma di variabile long), COLUMN_LAST_MODIFIED_TIMESTAMP per l’informazione temporale dell’ultima modifica in formato timestamp o COLUMN_TOTALE_SIZE_BYTES per le dimensioni misurate in byte: la documentazione ufficiale sarà un buon riferimento per ulteriori informazioni.

Altro aspetto interessante sarà la presenza, anche in questo caso nella classe Query, di due metodi, setFilterById e setFilterByStatus, che permetteranno di raffinare la ricerca concentrandosi, rispettivamente, su uno o più id di download o su uno stato specifico dello scaricamento.

Conclusioni

Osservare come il DownloadManager lavora ci offre due spunti importanti. Innanzitutto che per interagire con la rete non esiste un solo strumento ma una moltitudine, offerti da Android o da realtà di terze parti ma sempre focalizzati su aspetti diversi: in base al lavoro da svolgere dovremo scegliere quello più adatto. In secondo luogo, si può notare che quando esiste un servizio di sistema per le operazioni che dobbiamo svolgere è sempre meglio delegarle a questi guadagnando per la nostra app efficienza ed ordine architetturale.

 

Share this story:
  • tweet

Tags: androidandroid system servicedownloaddownloadmanagerhttpTutorial Pratici

Recent Posts

  • Parte il percorso programmatori iOS in Swift su devACADEMY.it

    20 Dicembre 2017 - 0 Comment
  • Android, crittografare dati velocemente con Encryption

    24 Settembre 2018 - 0 Comment
  • Sql2o, accesso immediato ai database tramite Java

    3 Settembre 2018 - 0 Comment
  • Okio, libreria per ottimizzare l’input/output in Java

    27 Agosto 2018 - 0 Comment

Related Posts

  • IntelliJ IDEA: IDE per programmare in Java e Kotlin

    25 Luglio 2018 - 0 Comment
  • Android: usare Connect Pattern

    10 Luglio 2018 - 0 Comment
  • Android: il metodo findViewById() non richiede più il cast

    21 Giugno 2018 - 0 Comment

Author Description

No Responses to “Android: scaricare grandi file con il DownloadManager”

Leave a Reply

Your email address will not be published. Required fields are marked *


*
*

Corso online di programmazione android e java

SEZIONI

  • Android
  • Comunicazioni
  • Contest
  • Corsi ed Eventi
  • Corso completo di C
  • Corso programmazione videogiochi
  • Framework
  • Grafica e Design
  • Guida rapida alla programmazione Cocoa Touch
  • Guide Teoriche
  • Guide varie
  • iPad
  • Le nostre applicazioni
  • Libri e manuali
  • Materiale OpenSource
  • News
  • Pillole di C++
  • Progetti completi
  • Risorse utili
  • Strumenti di Sviluppo
  • Swift
  • Tips & Tricks
  • Tutorial Pratici
  • Video Tutorial
  • Windows Phone

Siti Amici

  • Adrirobot
  • Allmobileworld
  • Apple Notizie
  • Apple Tribù
  • Avvocato360
  • Blog informatico 360°
  • bubi devs
  • fotogriPhone
  • GiovaTech
  • iApp-Mac
  • iOS Developer Program
  • iPodMania
  • MelaRumors
  • Meritocracy
  • SoloTablet
  • TecnoUser
  • Privacy & Cookie Policy
©2009-2018 devAPP - All Rights Reserved | Contattaci
devAPP.it è un progetto di DEVAPP S.R.L. - Web & Mobile Agency di Torino
Str. Volpiano, 54 - 10040 Leini (TO) - C.F. e P.IVA 11263180017 - REA TO1199665 - Cap. Soc. € 10.000,00 i.v.

devACADEMY.it

Vuoi imparare a programmare?

Iscriviti e accedi a TUTTI i corsi con un’unica iscrizione.
Oltre 70 corsi e migliaia di videolezioni online e in italiano a tua disposizione.

ISCRIVITI SUBITO