I have a ListView in which each item represents a PDF file. When the user clicks on an item, the application must upload the file to external storage. Now loading does not work properly, but that is not a question. I want the ProgressBar style, the spinning wheel style, to appear next to each list item while the file is loading.
My problem: I cannot find how to make the spinning wheel appear. Before Download Manager, I tried it with AsyncTask, and the spinning wheel worked.
Here is my code:
CategoryActivity.java (ListView activity)
@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); } }
Please note: if I do not close the spinning wheel, it will always be visible after clicking on an element. With a line to hide her, she does not even appear.
EDIT:
I added BroadcastReceiver.
Put these two lines in onCreate ():
final DownloadManager mgr=(DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE); registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
And added:
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: So, here are some changes I made:
I save the boot id 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 state 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:
The problem is that the spinning wheel is hidden only for the last item clicked in the View list. I tried in debug mode, but the program has the correct behavior ( loader.setVisibility(View.GONE) is called for each download). I do not know why the spinning wheel will not hide, with the exception of the last clicked item.
EDIT: 3 I know why the spinning wheel does not hide, except for the last clicked item.
When I click on a few items, lastDownload accepts the id of the last click. Thus, in the broadcast receiver, in the case of the last element, the number of clicks is clicked. I tried changing lastDownload to an array / table longs and comparing it with referenceId, which I believe is the identifier contained in the intent.
Here is the new code (y = 0 and ld is the number of elements pressed):
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);
I did not write the part where I returned the variables to 0, but at the moment the code is working as expected. The only problem is that the spinning wheel that I am doing disappears, it is the spinning wheel of the last clicked item. And I know why. Because this line: loader = ((ProgressBar) view.findViewById(R.id.spinWheel2)); is in the onItemClicked method. I don’t think I can put it in another place, because the performance in which it is located is not a form of activity.
In short: I have to find a way to access the execution line of the item / view that I clicked on, knowing that I can click on multiple items before the first reaches the broadcast receiver.
EDIT: 4 Ok, so I did this:
y , z and ld are set to 0 at the beginning.
When you click an item:
// 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 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; } } } } } };
It works fine, except when a small file item is clicked while loading a large file. The small file takes precedence, and the download manager no longer performs the order of the tables, as a result of which the boot wheel does not disappear.
EDIT: 5
I found a way to do what I wanted, to see my answer.
Thank you for your help.