我试图写一个简单的应用程序得到更新。为此,我需要一个简单的函数,可以下载文件并在ProgressDialog中显示当前进度。我知道如何做的ProgressDialog,但我不确定如何显示当前的进度,以及如何下载文件放在第一位。
当前回答
您可以使用LiveData和协程观察下载管理器的进度,参见下面的要点
https://gist.github.com/FhdAlotaibi/678eb1f4fa94475daf74ac491874fc0e
data class DownloadItem(val bytesDownloadedSoFar: Long = -1, val totalSizeBytes: Long = -1, val status: Int)
class DownloadProgressLiveData(private val application: Application, private val requestId: Long) : LiveData<DownloadItem>(), CoroutineScope {
private val downloadManager by lazy {
application.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
}
private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun onActive() {
super.onActive()
launch {
while (isActive) {
val query = DownloadManager.Query().setFilterById(requestId)
val cursor = downloadManager.query(query)
if (cursor.moveToFirst()) {
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
Timber.d("Status $status")
when (status) {
DownloadManager.STATUS_SUCCESSFUL,
DownloadManager.STATUS_PENDING,
DownloadManager.STATUS_FAILED,
DownloadManager.STATUS_PAUSED -> postValue(DownloadItem(status = status))
else -> {
val bytesDownloadedSoFar = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))
val totalSizeBytes = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
postValue(DownloadItem(bytesDownloadedSoFar.toLong(), totalSizeBytes.toLong(), status))
}
}
if (status == DownloadManager.STATUS_SUCCESSFUL || status == DownloadManager.STATUS_FAILED)
cancel()
} else {
postValue(DownloadItem(status = DownloadManager.STATUS_FAILED))
cancel()
}
cursor.close()
delay(300)
}
}
}
override fun onInactive() {
super.onInactive()
job.cancel()
}
}
其他回答
使用Android查询库,确实很酷。你可以改变它使用ProgressDialog,就像你在其他例子中看到的那样,这个将从你的布局中显示进度视图,并在完成后隐藏它。
File target = new File(new File(Environment.getExternalStorageDirectory(), "ApplicationName"), "tmp.pdf");
new AQuery(this).progress(R.id.progress_view).download(_competition.qualificationScoreCardsPdf(), target, new AjaxCallback<File>() {
public void callback(String url, File file, AjaxStatus status) {
if (file != null) {
// do something with file
}
}
});
不要忘记用新文件("/mnt/sdcard/…")替换"/sdcard…",否则你会得到一个FileNotFoundException
当我开始学习android开发时,我知道ProgressDialog是正确的方法。ProgressDialog的setProgress方法可以在下载文件时调用它来更新进度级别。
我在许多应用程序中看到的最好的情况是,它们自定义了进度对话框的属性,使进度对话框的外观和感觉比库存版本更好。很好地保持用户的一些动画,如青蛙,大象或可爱的猫/小狗。任何有进度对话框的动画都能吸引用户,他们不喜欢长时间等待。
我个人的建议是使用进度对话框并在执行前进行构建,或者在OnPreExecute()上初始化,如果你使用进度对话框的水平风格的进度条,则经常发布进度。剩下的部分是优化doInBackground的算法。
如果你要从网上下载东西,别忘了给你的manifest文件添加权限!
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.helloandroid"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:debuggable="true">
</application>
</manifest>
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 碎片中的onCreateOptionsMenu
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?