因为项目需要做一个下载的功能,虽然目前有众多的下载器,但是简单好用,而且支持断点的下载器,先推荐下这个吧,PRDownloader
GitHub地址镇楼:
https://github.com/MindorksOpenSource/PRDownloader
里面有很详细的说明,不过都是英语的,我用谷歌翻译大概功能如下:
1 PRDownloader可用于下载任何类型的文件,例如图像,视频,pdf,apk等。
2 该文件下载器库支持在下载文件时暂停和继续。
3 支持大文件下载。
4 该下载器库具有一个简单的界面来发出下载请求。
5 我们可以使用给定的下载ID检查下载状态。
6 PRDownloader在下载文件时为onProgress,onCancel,onStart,onError等
提供回调。
7 支持适当的请求取消。
8 可以并行发出许多请求。
9 所有类型的定制都是可能的。
添加依赖:
implementation 'com.mindorks.android:prdownloader:0.6.0'
添加网络申请的权限:
<uses-permission android:name="android.permission.INTERNET" />
使用方法如下,里面都备注好了!!
class MainActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
private var dirPath: String? = null
lateinit var savePic: Button
val REQUEST_CODE_SAVE_IMG = 10
val TAG = "MainActivity"
lateinit var mContext: Context
val URL13 =
"https://img-blog.csdn.net/20170418112008577?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd" +
"GlhbmRpd3V5YQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center"
lateinit var mBtnDown: Button
lateinit var buttonCancelOne: Button
lateinit var mTvProgressing: TextView
lateinit var mPbDownloading: ProgressBar
var downloadIdOne = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mContext = this
setContentView(R.layout.activity_main)
dirPath = com.example.prdownloader.Utils.Utils().getRootDirPath(applicationContext)
//下载按钮
mBtnDown = findViewById(R.id.buttonOne)
//取消下载按钮
buttonCancelOne = findViewById(R.id.buttonCancelOne)
//保存图片按钮
savePic = findViewById(R.id.btn_savePic)
//进度展示文字显示
mTvProgressing = findViewById(R.id.textViewProgressOne)
//进度下载进度条显示
mPbDownloading = findViewById(R.id.progressBarOne)
onClickListnerOne()
}
private fun onClickListnerOne() {
mBtnDown.setOnClickListener {
//此处判断运行的状态,如果在运行中时,点击暂停
if (Status.RUNNING == PRDownloader.getStatus(downloadIdOne)) {
PRDownloader.pause(downloadIdOne)
return@setOnClickListener
}
//设置控件的激活状态,false为未激活状态,任何点击效果都没用
mBtnDown.isEnabled = false
//进度条启动无限循环动画(进入不确定模式)
mPbDownloading.isIndeterminate = true
//绘制进度条在不确定模式中的样式
mPbDownloading.indeterminateDrawable.setColorFilter(
Color.BLUE, android.graphics.PorterDuff.Mode.SRC_IN
)
//此处判断运行的状态,如果在中止时,点击重启
if (Status.PAUSED == PRDownloader.getStatus(downloadIdOne)) {
PRDownloader.resume(downloadIdOne)
return@setOnClickListener
}
//改变downloadIdOne状态
downloadIdOne = PRDownloader.download(URL13, dirPath, "facebook.apk")
.build()
//监听启动或者重启状态
.setOnStartOrResumeListener(object : OnStartOrResumeListener {
override fun onStartOrResume() {
mPbDownloading.isIndeterminate = false
mBtnDown.isEnabled = true
// buttonOne.text=R.string.pause.toString()
mBtnDown.setText(R.string.pause)
buttonCancelOne.isEnabled = true
}
})
//在暂停时调用
.setOnPauseListener(object : OnPauseListener {
override fun onPause() {
// buttonOne.text=R.string.resume.toString()
mBtnDown.setText(R.string.resume)
}
})
//监听取消后
.setOnCancelListener(object : OnCancelListener {
override fun onCancel() {
// buttonOne.text=R.string.start.toString()
mBtnDown.setText(R.string.start)
buttonCancelOne.isEnabled = false
mPbDownloading.progress = 0
mTvProgressing.text = ""
downloadIdOne = 0
mPbDownloading.isIndeterminate = false
}
})
//进度条监听,
.setOnProgressListener(object : OnProgressListener {
override fun onProgress(progress: Progress) {
var progressPercent = progress.currentBytes * 100 / progress.totalBytes
mPbDownloading.progress = progressPercent.toInt()
mTvProgressing.text = com.example.prdownloader.Utils.Utils()
.getProgressDisplayLine(progress.currentBytes, progress.totalBytes)
mPbDownloading.isIndeterminate = false
}
})
.start(object : OnDownloadListener {
//下载完成时调用
override fun onDownloadComplete() {
mBtnDown.isEnabled = false
buttonCancelOne.isEnabled = false
// buttonOne.text=R.string.completed.toString()
mBtnDown.setText(R.string.completed)
}
//下载出现错误时调用
override fun onError(error: Error?) {
// buttonOne.text=R.string.start.toString()
mBtnDown.setText(R.string.start)
Toast.makeText(
applicationContext,
getString(R.string.some_error_occurred) + "" + 1,
Toast.LENGTH_SHORT
).show()
mTvProgressing.text = ""
mPbDownloading.progress = 0
downloadIdOne = 0
buttonCancelOne.isEnabled = false
mPbDownloading.isIndeterminate = false
mBtnDown.isEnabled = true
}
})
}
buttonCancelOne.setOnClickListener {
PRDownloader.cancel(downloadIdOne)
}
btn_savePic.setOnClickListener {
requestPermission()
}
}
fun requestPermission() {
if (Build.VERSION.SDK_INT >= 23) {
//读取sd卡的权限
val mPermissionList = arrayOf<String>(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
if (EasyPermissions.hasPermissions(mContext, mPermissionList.toString())) {
//已经同意过
saveImage()
} else {
//未同意过,或者说是拒绝了,再次申请权限
EasyPermissions.requestPermissions(
this,
"保存图片需要读取sd卡的权限", REQUEST_CODE_SAVE_IMG,
mPermissionList.toString()
)
}
} else {
saveImage()
}
}
//保存图片
fun saveImage() {
val bitmap = BitmapFactory.decodeResource(resources, R.mipmap.fj)
var isSaveSuccess = ImgUtils().saveImageToGallery(mContext, bitmap)
if (isSaveSuccess) {
Toast.makeText(mContext, "保存图片成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, "保存图片失败,请稍后重试", Toast.LENGTH_SHORT).show();
}
}
//授权结果分发下去
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
//拒绝授权
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
Log.i(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size)
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
//打开系统设置,手动授权
AppSettingsDialog.Builder(this).build().show()
}
}
//同意授权
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
TODO("Not yet implemented")
Log.i(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size)
saveImage()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
//拒绝授权后,从系统设置了授权后,返回APP进行相应的操作
Log.i(TAG, "onPermissionsDenied:------>自定义设置授权后返回APP")
saveImage()
}
}
}
然后还有一个工具类:
class Utils {
fun getRootDirPath(context: Context):String{
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
val file=ContextCompat.getExternalFilesDirs(context.applicationContext,null)[0]
var uri= Uri.fromFile(file)
context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,uri))
return file.absolutePath
}else{
return context.applicationContext.filesDir.absolutePath
}
}
fun getProgressDisplayLine(currentBytes:Long,totalBytes:Long):String{
return getBytesToMBString(currentBytes)+"/"+getBytesToMBString(totalBytes)
}
fun getBytesToMBString(bytes:Long):String{
return String.format(Locale.ENGLISH,"%.2fMb",bytes/(1024.00*1024.00))
}
}
左乔治,右佩琦,法力无边,编写完成!!!希望这个可以帮助到大家的说啦
网友评论