而使用下载管理器Android的进度中的ListView管理器、进度、Android、ListView

2023-09-05 09:44:28 作者:独守一座空城

我有一个ListView中重新$ P $每个项目psents的PDF文件。当用户点击项目时,该应用程序必须下载关于外部存储该文件。 现在下载不能正常工作,但是这不是问题。我希望有一个进度条,纺轮的风格,同时下载文件列表旁边的每个项目出现。

I have a ListView in which each item represents a PDF file. When the user clicks on an item, the application must download the file on external storage. Now the download doesn't work properly, but that's not the question. I want a ProgressBar, spinning wheel style, to appear next to each item of the list while the file is downloaded.

我的问题是:我无法找到如何使纺车出现。下载管理器之前,我尝试过用的AsyncTask和纺车工作。

My problem is : I can't find how to make the spinning wheel appear. Before the Download Manager I tried it with an AsyncTask and the spinning wheel worked.

下面是我的code:

CategoryActivity.java(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);

    }
}

请注意,如果我不作纺车消失,它总是会点击该项目后可见。随着该行以隐藏它,它甚至没有出现。

Note that if I don't make the spinning wheel disappear, it will always be visible after click on the item. With the line to hide it, it doesn't even appear.

编辑: 我加了一个BroadcastReceiver。

EDIT : I added a BroadcastReceiver.

放入的onCreate()这两行:

Put these two lines in onCreate() :

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

和添加这样的:

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

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

编辑2: 好了,所以这里有一些改变我做:

EDIT 2 : Ok so here are some changes I made :

我保存下载的ID在一个变量:

I save the id of the download in a variable :

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));

根据下载的状态,我想要做不同的事情:

Depending on the status of the download, I want to do different things :

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;
                }
            }

        }
    };

现在的问题是,纺轮只隐藏的点击在ListView中的最后一项。我试着用调试模式,但程序有一个正确的行为(指 loader.setVisibility(View.GONE)被调用每次下载)。我不知道为什么纺车不会躲除了最后单击的项目。

The problem is, the spinning wheel only hides for the last item clicked in the listView. I tried with debug mode, but the program has a correct behavior (meaning loader.setVisibility(View.GONE) is called for every download). I don't know why the spinning wheel won't hide except for the last item clicked.

编辑:3 我知道为什么纺车不会躲除了最后单击的项目。

EDIT : 3 I know why the spinning wheel won't hide except for the last item clicked.

当我点击多个项目,lastDownload采取的最后一个ID点击。因此,在广播接收器,它的最后一个项目的情况下,点击次数的项数点击。 我试着用改变lastDownload成多头阵列/表,并将其与referenceId,我相信这是包含在意图ID比较。 这是新的code(Y = 0和LD是项目的数量点击):

When I click on multiple items, lastDownload takes the id of the last one clicked. So in the broadcast receiver, it does the case of the last item clicked times the number of items clicked. I tried with changing lastDownload into an array/table of longs, and comparing it with referenceId, which I believe is the id contained in the intent. Here is the new code (y=0 and ld is the number of items clicked):

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;

                   }
            }   
        }
    };

我没有写的部分,我把变量返回0,但对于现在的code pretty的作品不多预期。剩下唯一的问题是,纺轮我做消失的最后一个项目的纺车点击。我知道这是为什么。由于此行:装载机=((进度)view.findViewById(R.id.spinWheel2)); 位于 onItemClicked 方法。我不认为我可以把它放在任何地方,因为认为它是不活动的看法。

I didn't write the part where I put the variables back to 0, but for now the code pretty much works as expected. The only problem remaining is that the spinning wheel I make disappear is the spinning wheel of the last item clicked. And I know why. Because this line : loader = ((ProgressBar) view.findViewById(R.id.spinWheel2)); is located in the onItemClicked method. I don't think I can put it anywhere else because the view it is in is not the view of the activity.

长话短说:我必须找到一种方法来访问项目/视图我点击的进度条,知道我可以在多个项目然后再单击第一个到达的广播接收器

Long story short : I must find a way to access the progress bar of the item/view I clicked on, knowing that I can click on multiple items before the first one reaches the Broadcast Receiver.

编辑:4 确定,所以我这样做:

EDIT : 4 Ok so I did this :

以Z LD 设置以 0 在开始时。

y,z, and ld are set to 0 at the begining.

当一个项目被点击了:

// 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;

广播接收器:

Broadcast Receiver :

// 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;
                    }
                }
            }
        }
    }
};

工作正常,除了当一个小文件的项目被点击了正在下载一个大文件时。小文件采用优先级和下载管理器不遵循表的顺序了,导致装载轮不会消失。

Works ok, except when an item of a small file is being clicked while a big file is being downloaded. The small file takes the priority and the download manager doesn't follow the order of the tables anymore, causing the loading wheel to not disappear.

编辑:5

我找到了一种方法做我想要的,看我的答案。

I found a way to do what I wanted, see my answer.

感谢您的帮助。

推荐答案

好了,所以我设法做我想要做一个哈希表:

Ok so I managed to do what I wanted to do with a HashTable :

// HashTable to store download id's and loaders
Hashtable<Long, SyncedProgressBar> storeTable = new Hashtable<Long, SyncedProgressBar>();

在我onClickListener方法,在装载机[Z] lastDownload [LD] 拿自己的价值,我把他们在哈希表(该downloa ID将是关键,装载机将是值)

In my onClickListener method, after loader[z] and lastDownload[ld] take their value, I put them in the HashTable : ( the downloa id will be the key, the loader will be the value )

// Storing download id and loader in HashTable
storeTable.put(lastDownload[ld], loader[z]);

而不是做这个

在我的广播接收器的的onReceive方法:

In my Broadcast Receiver's onReceive method, instead of doing this :

if(lastDownload[y] == referenceId)

我看,如果哈希表中包含的意图的下载ID:

I look if the HashTable contains the download id of the intent :

if(storeTable.containsKey(referenceId))

和我把正确的值在装载机:

And I put the correct value in the loader :

loader[y] = storeTable.get(referenceId);

然后,我只是把装载机的知名度 GONE 我要在哪里。该解决方案对我的作品,但我会更新,如果我发现一些新的东西。

Then I just have to put the loader's visibility to GONE where I want. This solution works for me, but I will update it if I find something new.

下面是我的新code:

Here is my new code :

在onClickListener方式:(不完全这里)

// 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));

// Storing download id and loader in HashTable
storeTable.put(lastDownload[ld], loader[z]);

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

广播接收器:

// 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 HashTable contains the Key-download-id for which the method is called
            if(storeTable.containsKey(referenceId)){
                // Loader takes the value for the key
                loader[y] = storeTable.get(referenceId);
                // We define a cursor depending on the id
                Cursor c = mgr.query(new DownloadManager.Query().setFilterById(referenceId));
                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;
                    }
                }
            }
        }
    }
};