Android ProgressBar in ListView während der Verwendung von DownloadManager

Ich habe eine ListView, in der jedes Element eine PDF-Datei darstellt. Wenn der Benutzer auf ein Element klickt, muss die Anwendung die Datei auf einen externen Speicher herunterladen. Jetzt funktioniert der Download nicht richtig, aber das ist nicht die Frage. Ich möchte, dass beim Herunterladen der Datei neben jedem Listeneintrag eine ProgressBar mit Drehrad angezeigt wird.

Mein Problem ist: Ich kann nicht finden, wie das sich drehende Rad erscheinen soll. Vor dem Download Manager habe ich es mit einer AsyncTask versucht und das Spinnrad hat funktioniert.

Hier ist mein Code:

CategoryActivity.java (Aktivität der ListView)

@Override
public void onItemClick(AdapterView<?> parent, View view,
    int position, long id) {
    // Récupère les valeurs depuis ListItem
    udl = ((TextView) view.findViewById(R.id.udl)).getText().toString();
    // This is the spinning wheel
    loader = ((ProgressBar) view.findViewById(R.id.spinWheel2));

    filepath = dirpath + udl + ".pdf";
    File file = new File(filepath);
    if (file.exists()) {

        // If the file exists, I open it

    }else{ // Else I download it
        // Setting the spinning wheel to VISIBLE
        loader.setVisibility(View.VISIBLE);

        SharedPreferences codeSaveUrl = getSharedPreferences(PREFS_TEXT,Context.MODE_PRIVATE);
        url2 = codeSaveUrl.getString("defaut", ""); // Code Organisation
        // Constructing the uriString
        uri = url10 + url2 + "&file=" + udl ;

        Uri myuri = Uri.parse(uri);
        DownloadManager mgr=(DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
        mgr.enqueue(new DownloadManager.Request(myuri)
        .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |DownloadManager.Request.NETWORK_MOBILE)
        .setAllowedOverRoaming(false)
        .setTitle(udl + ".pdf")
        .setDescription("Téléchargement en cours")
        .setDestinationInExternalPublicDir("/Protocols/", (udl+".pdf"))
        .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE));                    

        // Hiding the spinning wheel
        loader.setVisibility(View.GONE);

    }
}

Beachten Sie, dass das sich drehende Rad nach dem Klicken immer sichtbar ist, wenn es nicht ausgeblendet wird. Mit der Linie, um es auszublenden, wird es nicht einmal angezeigt.

EDIT:
Ich habe einen BroadcastReceiver hinzugefügt.

Fügen Sie diese beiden Zeilen in onCreate () ein:

final DownloadManager mgr=(DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

Und fügte hinzu:

BroadcastReceiver onComplete = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            loader.setVisibility(View.GONE);
        }
    };

    @Override
    public void onDestroy(){
        super.onDestroy();
        unregisterReceiver(onComplete);
    }

EDIT 2: Ok, hier sind einige Änderungen, die ich vorgenommen habe:

Ich speichere die ID des Downloads in einer Variablen:

lastDownload = mgr.enqueue(new DownloadManager.Request(myuri)
                .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |DownloadManager.Request.NETWORK_MOBILE)
                .setAllowedOverRoaming(false)
                .setTitle(udl + ".pdf")
                .setDescription("Téléchargement en cours")
                .setDestinationInExternalPublicDir("/Protocols/", (udl+".pdf"))
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED));

Abhängig vom Status des Downloads möchte ich verschiedene Dinge tun:

BroadcastReceiver onComplete = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            Cursor c = mgr.query(new DownloadManager.Query().setFilterById(lastDownload));
            if(c.moveToFirst()){
                int x = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
                switch(x){
                case DownloadManager.STATUS_PAUSED:
                case DownloadManager.STATUS_PENDING:
                case DownloadManager.STATUS_RUNNING:
                    break;
                case DownloadManager.STATUS_SUCCESSFUL:
                    loader.setVisibility(View.GONE);
                    break;
                case DownloadManager.STATUS_FAILED:
                    //TODO: retry download
                    break;
                }
            }

        }
    };

Das Problem ist, dass das sich drehende Rad nur für das zuletzt angeklickte Element in der Listenansicht ausgeblendet wird. Ich habe versucht, mit dem Debug-Modus, aber das Programm hat ein korrektes Verhalten (Bedeutungloader.setVisibility(View.GONE) wird bei jedem Download aufgerufen). Ich weiß nicht, warum sich das sich drehende Rad bis auf den zuletzt angeklickten Gegenstand nicht versteckt.

EDIT: 3 Ich weiß, warum sich das sich drehende Rad bis auf den zuletzt angeklickten Gegenstand nicht versteckt.

Wenn ich auf mehrere Elemente klicke, übernimmt lastDownload die ID des zuletzt angeklickten Elements. Im Rundfunkempfänger wird also der Fall des zuletzt angeklickten Elements multipliziert mit der Anzahl der angeklickten Elemente ausgeführt.
Ich habe versucht, lastDownload in ein Array / eine Long-Tabelle zu ändern und es mit referenceId zu vergleichen, von der ich glaube, dass es die ID ist, die in der Absicht enthalten ist.
Hier ist der neue Code (y = 0 und ld ist die Anzahl der angeklickten Elemente):

BroadcastReceiver onComplete = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) { 
            long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            if(y <ld){
                if(lastDownload[y] == referenceId){

            Cursor c = mgr.query(new DownloadManager.Query().setFilterById(lastDownload[y]));
            if(c.moveToFirst()){
                int x = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
                switch(x){
                case DownloadManager.STATUS_PAUSED:
                case DownloadManager.STATUS_PENDING:
                case DownloadManager.STATUS_RUNNING:
                    break;
                case DownloadManager.STATUS_SUCCESSFUL:
                    loader.setVisibility(View.GONE); // This loader is the one of the last item clicked
                    break;
                case DownloadManager.STATUS_FAILED:
                    //TODO: retry download
                    break;
                }

            }

                       y=y+1;

                   }
            }   
        }
    };

Ich habe den Teil, in dem ich die Variablen zurück auf 0 gesetzt habe, nicht geschrieben, aber im Moment funktioniert der Code so ziemlich wie erwartet. Das einzige verbleibende Problem ist, dass das sich drehende Rad, das ich verschwinden lasse, das sich drehende Rad des zuletzt angeklickten Elements ist. Und ich weiß warum. Weil diese Zeile:loader = ((ProgressBar) view.findViewById(R.id.spinWheel2)); befindet sich in deronItemClicked Methode. Ich glaube nicht, dass ich es irgendwo anders hinstellen kann, weil die Ansicht, in der es sich befindet, nicht die Ansicht der Aktivität ist.

Um es kurz zu machen: Ich muss einen Weg finden, um auf die Fortschrittsanzeige des Elements / der Ansicht zuzugreifen, auf das / die ich geklickt habe.

EDIT: 4 Ok, also habe ich das gemacht:

y,z, undld sind eingestellt auf0 am Anfang.

Wenn ein Artikel angeklickt wird:

// Loader of the clicked item is made visible
loader[z].setVisibility(View.VISIBLE);

// Construction of the URL
SharedPreferences codeSaveUrl = getSharedPreferences(PREFS_TEXT,Context.MODE_PRIVATE);
url2 = codeSaveUrl.getString("defaut", ""); // Organization code
uri = url10 + url2 + "&file=" + udl ;

// URL parse to URI
Uri myuri = Uri.parse(uri);

// Enqueue file to downloads, with notification. Storage of download id in a table
lastDownload[ld] = mgr.enqueue(new DownloadManager.Request(myuri)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle(udl + ".pdf")
.setDescription("Téléchargement en cours")
.setDestinationInExternalPublicDir("/Protocols/", (udl+".pdf"))
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE));

// Increment variables for next downloads
ld=ld+1;
z=z+1;

Rundfunkempfänger :

// Broadcast Receiver called when a download is finished
BroadcastReceiver onComplete = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        // referenceId is the download's id for which the method is called
        long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
        // If y (=0 at the beginning) is inferior to the number of downloads
        if(y <ld){
            // If the id of the download corresponds to the one for which the method is called
            if(lastDownload[y] == referenceId){
                // We define a cursor depending on the id
                Cursor c = mgr.query(new DownloadManager.Query().setFilterById(lastDownload[y]));
                if(c.moveToFirst()){
                    // Download status recovery
                    int x = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
                    switch(x){
                    // If download is paused, pending or running, we do nothing
                    case DownloadManager.STATUS_PAUSED:
                    case DownloadManager.STATUS_PENDING:
                    case DownloadManager.STATUS_RUNNING:
                        break;
                    // If file has successfully been downloaded, loader is hidden
                    case DownloadManager.STATUS_SUCCESSFUL:
                        loader[y].setVisibility(View.GONE); 
                        // Increment y to go to next download
                        y=y+1;
                        break;
                    // If download failed, it is retried
                    case DownloadManager.STATUS_FAILED:
                        //TODO: retry download
                        break;
                    }
                }
            }
        }
    }
};

Funktioniert einwandfrei, es sei denn, ein Element einer kleinen Datei wird angeklickt, während eine große Datei heruntergeladen wird. Die kleine Datei hat Priorität und der Download-Manager folgt nicht mehr der Reihenfolge der Tabellen, sodass das Laderad nicht verschwindet.

EDIT: 5

Ich habe einen Weg gefunden, um zu tun, was ich wollte, siehe meine Antwort.

Danke für Ihre Hilfe.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage