MAx*_*xeF 7 android download-manager android-listview android-progressbar android-download-manager
我有一个ListView,其中每个项目代表一个PDF文件.当用户单击某个项目时,该应用程序必须在外部存储上下载该文件.现在下载无法正常运行,但这不是问题.我想要一个ProgressBar,旋转轮样式,在下载文件时出现在列表的每个项目旁边.
我的问题是:我找不到如何使纺车出现.在下载管理器之前,我尝试使用AsyncTask并且旋转轮工作.
这是我的代码:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果我不使纺车轮消失,点击该项目后它将始终可见.使用隐藏它的行,它甚至不会出现.
编辑:
我添加了一个BroadcastReceiver.
将这两行放在onCreate()中:
final DownloadManager mgr=(DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
Run Code Online (Sandbox Code Playgroud)
并补充说:
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
loader.setVisibility(View.GONE);
}
};
@Override
public void onDestroy(){
super.onDestroy();
unregisterReceiver(onComplete);
}
Run Code Online (Sandbox Code Playgroud)
编辑2: 好的,这是我做的一些改变:
我将下载的ID保存在变量中:
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));
Run Code Online (Sandbox Code Playgroud)
根据下载的状态,我想做不同的事情:
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;
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
问题是,旋转轮只隐藏在listView中单击的最后一个项目.我尝试使用调试模式,但该程序具有正确的行为(loader.setVisibility(View.GONE)每次下载都会调用该含义).我不知道为什么除了点击的最后一项外,纺车不会隐藏.
编辑:3 我知道为什么除了点击的最后一项外,纺车不会隐藏.
当我点击多个项目时,lastDownload会获取最后一个项目的ID.因此,在广播接收器中,它点击最后一个项目的情况下点击了项目的数量.
我尝试将lastDownload更改为longs数组/表,并将其与referenceId进行比较,我相信它是intent中包含的id.
这是新代码(y = 0,ld是单击的项目数):
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;
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
我没有编写将变量放回0的部分,但是现在代码几乎按预期工作.剩下的唯一问题是我制造的纺车消失了最后一个项目的纺车轮点击.而且我知道为什么.因为这一行: loader = ((ProgressBar) view.findViewById(R.id.spinWheel2));位于onItemClicked方法中.我不认为我可以把它放在其他地方,因为它所在的视图不是活动的视图.
简而言之:我必须找到一种方法来访问我点击的项目/视图的进度条,知道我可以在第一个到达广播接收器之前点击多个项目.
编辑:4好的所以我这样做了:
y,z和ld被设置为0在开始时.
单击某个项目时:
// 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;
Run Code Online (Sandbox Code Playgroud)
广播接收器:
// 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;
}
}
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
工作正常,除非在下载大文件时单击一个小文件的项目.小文件优先,下载管理器不再遵循表的顺序,导致加载轮不会消失.
编辑:5
我找到了一种方法来做我想做的事,看看我的回答.
谢谢你的帮助.
好吧,我设法用 HashTable 做我想做的事情:
\n\n// HashTable to store download id\'s and loaders\nHashtable<Long, SyncedProgressBar> storeTable = new Hashtable<Long, SyncedProgressBar>();\nRun Code Online (Sandbox Code Playgroud)\n\n在我的 onClickListener 方法中,在loader[z]和之后lastDownload[ld]获取它们的值之后,我将它们放入 HashTable 中:(下载 id 将是键,加载器将是值)
// Storing download id and loader in HashTable\nstoreTable.put(lastDownload[ld], loader[z]);\nRun Code Online (Sandbox Code Playgroud)\n\n在我的广播接收器的 onReceive 方法中,而不是这样做:
\n\nif(lastDownload[y] == referenceId)\nRun Code Online (Sandbox Code Playgroud)\n\n我查看 HashTable 是否包含意图的下载 id:
\n\nif(storeTable.containsKey(referenceId))\nRun Code Online (Sandbox Code Playgroud)\n\n我将正确的值放入加载程序中:
\n\nloader[y] = storeTable.get(referenceId);\nRun Code Online (Sandbox Code Playgroud)\n\n然后我只需要把加载器的可见性设置为GONE我想要的位置即可。这个解决方案对我有用,但如果我发现新的东西,我会更新它。
这是我的新代码:
\n\n在onClickListener方法中:(这里不完整)
\n\n// Loader of the clicked item is made visible\nloader[z].setVisibility(View.VISIBLE);\n\n// Construction of the URL\nSharedPreferences codeSaveUrl = getSharedPreferences(PREFS_TEXT,Context.MODE_PRIVATE);\nurl2 = codeSaveUrl.getString("defaut", ""); // Organization code\nuri = url10 + url2 + "&file=" + udl ;\n\n// URL parse to URI\nUri myuri = Uri.parse(uri);\n\n// Enqueue file to downloads, with notification. Storage of download id in a table\nlastDownload[ld] = mgr.enqueue(new DownloadManager.Request(myuri)\n.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |DownloadManager.Request.NETWORK_MOBILE)\n.setAllowedOverRoaming(false)\n.setTitle(udl + ".pdf")\n.setDescription("T\xc3\xa9l\xc3\xa9chargement en cours")\n.setDestinationInExternalPublicDir("/Protocols/", (udl+".pdf"))\n.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE));\n\n// Storing download id and loader in HashTable\nstoreTable.put(lastDownload[ld], loader[z]);\n\n// Increment variables for next downloads\nld=ld+1;\nz=z+1;\nRun Code Online (Sandbox Code Playgroud)\n\n广播接收器:
\n\n// Broadcast Receiver called when a download is finished\nBroadcastReceiver onComplete = new BroadcastReceiver() {\n public void onReceive(Context context, Intent intent) {\n // referenceId is the download\'s id for which the method is called\n long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);\n // If y (=0 at the beginning) is inferior to the number of downloads\n if(y <ld){\n // If the HashTable contains the Key-download-id for which the method is called\n if(storeTable.containsKey(referenceId)){\n // Loader takes the value for the key\n loader[y] = storeTable.get(referenceId);\n // We define a cursor depending on the id\n Cursor c = mgr.query(new DownloadManager.Query().setFilterById(referenceId));\n if(c.moveToFirst()){\n // Download status recovery\n int x = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));\n switch(x){\n // If download is paused, pending or running, we do nothing\n case DownloadManager.STATUS_PAUSED:\n case DownloadManager.STATUS_PENDING:\n case DownloadManager.STATUS_RUNNING:\n break;\n // If file has successfully been downloaded, loader is hidden\n case DownloadManager.STATUS_SUCCESSFUL:\n loader[y].setVisibility(View.GONE); \n // Increment y to go to next download\n y=y+1;\n break;\n // If download failed, it is retried\n case DownloadManager.STATUS_FAILED:\n //TODO: retry download\n break;\n }\n }\n }\n }\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
4267 次 |
| 最近记录: |