我试图写一个简单的应用程序得到更新。为此,我需要一个简单的函数,可以下载文件并在ProgressDialog中显示当前进度。我知道如何做的ProgressDialog,但我不确定如何显示当前的进度,以及如何下载文件放在第一位。
当前回答
我遇到了一个简单文件下载库 获取,重要的是,它有存储访问框架,内容提供程序和URI支持。如果有人还在寻找,可能会有帮助。
//AndroidX .tonyodev.fetch2:xfetch2:3.1.6
实现"com.tonyodev.fetch2:fetch2:3.0.12" //支持lib
需要的权限,如果你不是使用应用程序特定的目录。
< uses-permission android: name = " android.permission.WRITE_EXTERNAL_STORAGE " / >
< uses-permission android: name = " android.permission.READ_EXTERNAL_STORAGE " / >
网络权限
< uses-permission android: name = " android.permission.INTERNET " / >
private Fetch fetch;
FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
.setDownloadConcurrentLimit(3)//Concurrent Download limit
.build();
fetch = Fetch.Impl.getInstance(fetchConfiguration);
String url = "http:www.example.com/test.txt";//URL of file
String file = "/downloads/test.txt";//Path of file
final Request request = new Request(url, file);
request.setPriority(Priority.HIGH);
request.setNetworkType(NetworkType.ALL);//Preferred network type
request.addHeader("clientKey", "SD78DF93_3947&MVNGHE1WONG");//Auth header if any
fetch.enqueue(request, updatedRequest -> {
//Request was successfully enqueued for download.
}, error -> {
//An error occurred enqueuing the request.
});
}
倾听更新和进展
FetchListener fetchListener = new FetchListener() {
@Override
public void onQueued(@NotNull Download download, boolean waitingOnNetwork) {
if (request.getId() == download.getId()) {
showDownloadInList(download);
}
}
@Override
public void onCompleted(@NotNull Download download) {
}
@Override
public void onError(@NotNull Download download) {
Error error = download.getError();
}
@Override
public void onProgress(@NotNull Download download, long etaInMilliSeconds, long downloadedBytesPerSecond) {
if (request.getId() == download.getId()) {
updateDownload(download, etaInMilliSeconds);
}
int progress = download.getProgress();
}
@Override
public void onPaused(@NotNull Download download) {
}
@Override
public void onResumed(@NotNull Download download) {
}
@Override
public void onCancelled(@NotNull Download download) {
}
@Override
public void onRemoved(@NotNull Download download) {
}
@Override
public void onDeleted(@NotNull Download download) {
}
};
fetch.addListener(fetchListener);
//Remove listener when done.
fetch.removeListener(fetchListener);
此示例代码取自所有者页面,所有功劳都归于Tonyo Francis
其他回答
我遇到了一个简单文件下载库 获取,重要的是,它有存储访问框架,内容提供程序和URI支持。如果有人还在寻找,可能会有帮助。
//AndroidX .tonyodev.fetch2:xfetch2:3.1.6
实现"com.tonyodev.fetch2:fetch2:3.0.12" //支持lib
需要的权限,如果你不是使用应用程序特定的目录。
< uses-permission android: name = " android.permission.WRITE_EXTERNAL_STORAGE " / >
< uses-permission android: name = " android.permission.READ_EXTERNAL_STORAGE " / >
网络权限
< uses-permission android: name = " android.permission.INTERNET " / >
private Fetch fetch;
FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
.setDownloadConcurrentLimit(3)//Concurrent Download limit
.build();
fetch = Fetch.Impl.getInstance(fetchConfiguration);
String url = "http:www.example.com/test.txt";//URL of file
String file = "/downloads/test.txt";//Path of file
final Request request = new Request(url, file);
request.setPriority(Priority.HIGH);
request.setNetworkType(NetworkType.ALL);//Preferred network type
request.addHeader("clientKey", "SD78DF93_3947&MVNGHE1WONG");//Auth header if any
fetch.enqueue(request, updatedRequest -> {
//Request was successfully enqueued for download.
}, error -> {
//An error occurred enqueuing the request.
});
}
倾听更新和进展
FetchListener fetchListener = new FetchListener() {
@Override
public void onQueued(@NotNull Download download, boolean waitingOnNetwork) {
if (request.getId() == download.getId()) {
showDownloadInList(download);
}
}
@Override
public void onCompleted(@NotNull Download download) {
}
@Override
public void onError(@NotNull Download download) {
Error error = download.getError();
}
@Override
public void onProgress(@NotNull Download download, long etaInMilliSeconds, long downloadedBytesPerSecond) {
if (request.getId() == download.getId()) {
updateDownload(download, etaInMilliSeconds);
}
int progress = download.getProgress();
}
@Override
public void onPaused(@NotNull Download download) {
}
@Override
public void onResumed(@NotNull Download download) {
}
@Override
public void onCancelled(@NotNull Download download) {
}
@Override
public void onRemoved(@NotNull Download download) {
}
@Override
public void onDeleted(@NotNull Download download) {
}
};
fetch.addListener(fetchListener);
//Remove listener when done.
fetch.removeListener(fetchListener);
此示例代码取自所有者页面,所有功劳都归于Tonyo Francis
我们可以使用协程和工作管理器在kotlin中下载文件。
在build.gradle中添加一个依赖
implementation "androidx.work:work-runtime-ktx:2.3.0-beta01"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.1"
WorkManager类
import android.content.Context
import android.os.Environment
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import com.sa.chat.utils.Const.BASE_URL_IMAGE
import com.sa.chat.utils.Constants
import kotlinx.coroutines.delay
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.net.URL
class DownloadMediaWorkManager(appContext: Context, workerParams: WorkerParameters)
: CoroutineWorker(appContext, workerParams) {
companion object {
const val WORK_TYPE = "WORK_TYPE"
const val WORK_IN_PROGRESS = "WORK_IN_PROGRESS"
const val WORK_PROGRESS_VALUE = "WORK_PROGRESS_VALUE"
}
override suspend fun doWork(): Result {
val imageUrl = inputData.getString(Constants.WORK_DATA_MEDIA_URL)
val imagePath = downloadMediaFromURL(imageUrl)
return if (!imagePath.isNullOrEmpty()) {
Result.success(workDataOf(Constants.WORK_DATA_MEDIA_URL to imagePath))
} else {
Result.failure()
}
}
private suspend fun downloadMediaFromURL(imageUrl: String?): String? {
val file = File(
getRootFile().path,
"IMG_${System.currentTimeMillis()}.jpeg"
)
val url = URL(BASE_URL_IMAGE + imageUrl)
val connection = url.openConnection()
connection.connect()
val lengthOfFile = connection.contentLength
// download the file
val input = BufferedInputStream(url.openStream(), 8192)
// Output stream
val output = FileOutputStream(file)
val data = ByteArray(1024)
var total: Long = 0
var last = 0
while (true) {
val count = input.read(data)
if (count == -1) break
total += count.toLong()
val progress = (total * 100 / lengthOfFile).toInt()
if (progress % 10 == 0) {
if (last != progress) {
setProgress(workDataOf(WORK_TYPE to WORK_IN_PROGRESS,
WORK_PROGRESS_VALUE to progress))
}
last = progress
delay(50)
}
output.write(data, 0, count)
}
output.flush()
output.close()
input.close()
return file.path
}
private fun getRootFile(): File {
val rootDir = File(Environment.getExternalStorageDirectory().absolutePath + "/AppName")
if (!rootDir.exists()) {
rootDir.mkdir()
}
val dir = File("$rootDir/${Constants.IMAGE_FOLDER}/")
if (!dir.exists()) {
dir.mkdir()
}
return File(dir.absolutePath)
}
}
开始下载通过工作管理器在活动类
private fun downloadImage(imagePath: String?, id: String) {
val data = workDataOf(WORK_DATA_MEDIA_URL to imagePath)
val downloadImageWorkManager = OneTimeWorkRequestBuilder<DownloadMediaWorkManager>()
.setInputData(data)
.addTag(id)
.build()
WorkManager.getInstance(this).enqueue(downloadImageWorkManager)
WorkManager.getInstance(this).getWorkInfoByIdLiveData(downloadImageWorkManager.id)
.observe(this, Observer { workInfo ->
if (workInfo != null) {
when {
workInfo.state == WorkInfo.State.SUCCEEDED -> {
progressBar?.visibility = View.GONE
ivDownload?.visibility = View.GONE
}
workInfo.state == WorkInfo.State.FAILED || workInfo.state == WorkInfo.State.CANCELLED || workInfo.state == WorkInfo.State.BLOCKED -> {
progressBar?.visibility = View.GONE
ivDownload?.visibility = View.VISIBLE
}
else -> {
if(workInfo.progress.getString(WORK_TYPE) == WORK_IN_PROGRESS){
val progress = workInfo.progress.getInt(WORK_PROGRESS_VALUE, 0)
progressBar?.visibility = View.VISIBLE
progressBar?.progress = progress
ivDownload?.visibility = View.GONE
}
}
}
}
})
}
当我开始学习android开发时,我知道ProgressDialog是正确的方法。ProgressDialog的setProgress方法可以在下载文件时调用它来更新进度级别。
我在许多应用程序中看到的最好的情况是,它们自定义了进度对话框的属性,使进度对话框的外观和感觉比库存版本更好。很好地保持用户的一些动画,如青蛙,大象或可爱的猫/小狗。任何有进度对话框的动画都能吸引用户,他们不喜欢长时间等待。
如果你要从网上下载东西,别忘了给你的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>
我正在为我现在使用的其他解决方案添加另一个答案,因为Android查询太大了,无法保持健康。所以我搬到了这个https://github.com/amitshekhariitbhu/Fast-Android-Networking。
AndroidNetworking.download(url,dirPath,fileName).build()
.setDownloadProgressListener(new DownloadProgressListener() {
public void onProgress(long bytesDownloaded, long totalBytes) {
bar.setMax((int) totalBytes);
bar.setProgress((int) bytesDownloaded);
}
}).startDownload(new DownloadListener() {
public void onDownloadComplete() {
...
}
public void onError(ANError error) {
...
}
});
推荐文章
- 如何添加JTable在JPanel与空布局?
- Android-Facebook应用程序的键散列
- Statement和PreparedStatement的区别
- 登出时,清除活动历史堆栈,防止“返回”按钮打开已登录的活动
- 如何改变标题的活动在安卓?
- 为什么不能在Java中扩展注释?
- 在Java中使用UUID的最重要位的碰撞可能性
- 转换列表的最佳方法:map还是foreach?
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- 如何隐藏动作栏之前的活动被创建,然后再显示它?
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 是否有一种方法以编程方式滚动滚动视图到特定的编辑文本?
- 使用String.split()和多个分隔符