我有一个按钮可以从localhost下载文件。它适用于小型文件,例如1-2 MB,但不适用于10-15 MB(例如10-15 MB)。我已经附加了我的代码。
pdf_download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse(base_url+pdf);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
Long reference = downloadManager.enqueue(request);
}
});
我还使用了不同的方式从服务器下载文件。
您已经使用为 dowanloadManager
的第一个第二个是使用asynctask下载文件。
class DownloadTask : AsyncTask<String, Int, String>() {
lateinit var downloadTaskListener: DownloadTaskListener
lateinit var pm: PowerManager
private var mWakeLock: PowerManager.WakeLock? = null
// private lateinit var mProgressBar: ProgressBar
private var fileName: String? = null
private var fileNameWithoutExtn: String? = null
private val dialog: Dialog? = null
// private var alertDialog: AlertDialog? = null
//lateinit var txtFileSize: TextView
internal var total: Long = 0
private var fileLength: Int = 0
//lateinit var btnCancel: Button
override fun doInBackground(vararg sUrl: String): String? {
var input: InputStream? = null
var output: OutputStream? = null
var connection: HttpURLConnection? = null
var outPutFile: File? = null
try {
val url = URL(sUrl[0])
connection = url.openConnection() as HttpURLConnection
connection.connect()
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.responseCode != HttpURLConnection.HTTP_OK) {
return ("Server returned HTTP " + connection.responseCode
+ " " + connection.responseMessage)
}
// this will be useful to display download percentage
// might be -1: server did not report the length
fileLength = connection.contentLength
// download the file
input = connection.inputStream
fileName = sUrl[0].substring(sUrl[0].lastIndexOf('/') + 1, sUrl[0].length)
fileNameWithoutExtn = fileName!!.substring(0, fileName!!.lastIndexOf('.'))
Log.d("check", "name $fileName without extention $fileNameWithoutExtn")
outPutFile = downloadTaskListener.getFilePath("$fileNameWithoutExtn.apk")
output = FileOutputStream(outPutFile)
val data = ByteArray(4096)
total = 0
var count: Int=input.read(data)
while (count != -1) {
// allow canceling with back button or click on Cancel button
if (isCancelled) {
output.flush()
output.close()
input!!.close()
return null
}
total += count.toLong()
// publishing the progress....
if (fileLength > 0)
// only if total length is known
Log.d("check", total.toString() + "")
publishProgress((total * 100 / fileLength).toInt())
output.write(data, 0, count)
}
} catch (e: Exception) {
return e.toString()
} finally {
try {
output?.close()
input?.close()
// outPutFile!!.setReadable(true, false)
} catch (ignored: IOException) {
}
connection?.disconnect()
}
return null
}
override fun onPreExecute() {
super.onPreExecute()
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
// val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
mWakeLock = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
javaClass.name
)
mWakeLock!!.acquire()
//
// val dialogBuilder = AlertDialog.Builder(context)
// // ...Irrelevant code for customizing the buttons and title
// val inflater = LayoutInflater.from(context)
// val customProgress = inflater.inflate(R.layout.custom_progress_dialog, null)
// dialogBuilder.setView(customProgress)
//
// alertDialog = dialogBuilder.create()
// alertDialog!!.setCancelable(false)
//
// mProgressBar = customProgress.findViewById(R.id.downloadProgressBar)
// mProgressBar!!.progressDrawable = context.resources.getDrawable(R.drawable.custom_progress)
// txtFileSize = customProgress.findViewById(R.id.txt_file_size)
// txtFileSize.text = "Downloading is starting ...."
// btnCancel = customProgress.findViewById(R.id.btnCancel)
downloadTaskListener.showDialog()
// txtFileSize= alertDialog!!.txt_file_size
// mProgressBar= alertDialog!!.downloadProgressBar
// btnCancel= alertDialog!!.btnCancel
downloadTaskListener.getCancelButton().setOnClickListener { cancel(true) }
downloadTaskListener.updateDialogData(0,"Downloading is starting ....")
// dialog.show();
// alertDialog!!.show()
downloadTaskListener.showDialog().show()
}
// Display the async tas progress
override fun onProgressUpdate(vararg values: Int?) {
downloadTaskListener.updateDialogData(values[0]!!,"Download progress : " + Utils.bytes2String(total) + "/" + Utils.bytes2String(fileLength.toLong()))
// mProgressBar.progress = values[0]!!
// mProgressBar.setMax(100)
// txtFileSize.text = "Download progress : " + Utils.bytes2String(total) + "/" + Utils.bytes2String(fileLength.toLong())
// downloadTaskListener.showToast("Downloaded ${values[0]} %")
super.onProgressUpdate(values[0])
}
override fun onPostExecute(result: String?) {
mWakeLock!!.release()
//mProgressDialog.dismiss();
//dialog.dismiss();
downloadTaskListener.showDialog()!!.dismiss()
if (result != null)
// Toast.makeText(context, "Download error: $result", Toast.LENGTH_LONG).show()
downloadTaskListener.showToast("Download error: $result")
else {
// Toast.makeText(context, "Apk downloaded", Toast.LENGTH_SHORT).show()
downloadTaskListener.showToast("Apk downloaded")
// txtFileSize.text = "APK Downloaded Completely."
downloadTaskListener.updateDialogData(100,"APK Downloaded Completely.")
// val file = File(Utils.getAbsoluteFile("", context), "$fileNameWithoutExtn.apk")
val file=downloadTaskListener.getFilePath("$fileNameWithoutExtn.apk")
//File file = new File("/sdcard/update.apk");
var fileUri = Uri.fromFile(file)
if (file.exists()) {
Log.d("check", "file exists " + file.absolutePath + fileUri)
} else {
Log.d("check", "file does not exist " + file.absolutePath)
}
if (Build.VERSION.SDK_INT >= 24) {
// fileUri = FileProvider.getUriForFile(
// context,
// context.applicationContext.packageName + ".my.package.name.provider",
// file
// )
}
val intent = Intent(Intent.ACTION_VIEW, fileUri)
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive")
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
// context.startActivity(intent)
downloadTaskListener.startActivity(intent)
}
}
override fun onCancelled(s: String) {
super.onCancelled(s)
Log.d("TASK TAG", "Cancelled.")
// txtFileSize.text = "Downloading Cancelled"
// Toast.makeText(context, "Downloading Cancelled ", Toast.LENGTH_SHORT).show()
downloadTaskListener.showToast("Downloading Cancelled ")
// mProgressBar!!.progress = 0
//alertDialog!!.dismiss()
downloadTaskListener.updateDialogData(0, "Downloading Cancelled")
downloadTaskListener.showDialog().dismiss()
}
interface DownloadTaskListener{
fun showToast(text: String)
fun startActivity(intent: Intent)
fun getFilePath(fileName:String):File
fun showDialog():AlertDialog
fun updateDialogData(progress:Int,msg:String)
fun getCancelButton():Button
}
}
我认为最适合大型文件下载文件的第三个第三方第三方库 Android网络库首先将图书馆放入gradle
implementation 'com.amitshekhar.android:android-networking:1.0.2'
然后编写此代码
AndroidNetworking.download(url,dirPath,fileName)
.setTag("downloadTest")
.setPriority(Priority.MEDIUM)
.build()
.setDownloadProgressListener(new DownloadProgressListener() {
@Override
public void onProgress(long bytesDownloaded, long totalBytes) {
// do anything with progress
}
})
.startDownload(new DownloadListener() {
@Override
public void onDownloadComplete() {
// do anything after completion
}
@Override
public void onError(ANError error) {
// handle error
}
});
要下载如此大的文件,您需要在块中下载这些文件。您是否可以使用任何支持HTTP范围选项的库来允许在多个零件中拉下单个文件,支持简历等。
或者您可以在服务器上拆分大型文件,然后将每个文件的MD5 Hash带有一个文本文件,当您首次开始下载时,然后在完成后获取MD5文件,然后检查哈希与下载的部分匹配。如果他们不删除该作品,然后将其添加到要下载的物品队列中。
一旦下载了所有零件,并且MD5都可以使用,您可以将这些件作为单个文件放回原处。
如果您想在SD卡中下载文件,则FAT32是默认文件系统。
您可以按照修改文件保存过程而不是下载管理器
https://futurestud.io/tutorials/retrofit-2-how-to-download-files-from-server