Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
B
Browser White
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanglei
Browser White
Commits
f1eb821d
Commit
f1eb821d
authored
Aug 25, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
3b960565
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
320 additions
and
244 deletions
+320
-244
build.gradle.kts
app/build.gradle.kts
+1
-0
MyApplication.kt
app/src/main/java/com/base/browserwhite/MyApplication.kt
+14
-6
DownloadBean.kt
app/src/main/java/com/base/browserwhite/bean/DownloadBean.kt
+2
-4
WebViewFragment.kt
...se/browserwhite/ui/activity/webbrowser/WebViewFragment.kt
+64
-17
DownloadAdapter.kt
.../java/com/base/browserwhite/ui/adapter/DownloadAdapter.kt
+97
-37
DialogViews.kt
...c/main/java/com/base/browserwhite/ui/views/DialogViews.kt
+0
-109
DownloadDialog.kt
...ain/java/com/base/browserwhite/ui/views/DownloadDialog.kt
+134
-0
VideoDownloader.kt
.../main/java/com/base/browserwhite/utils/VideoDownloader.kt
+6
-71
libs.versions.toml
gradle/libs.versions.toml
+2
-0
No files found.
app/build.gradle.kts
View file @
f1eb821d
...
@@ -72,6 +72,7 @@ dependencies {
...
@@ -72,6 +72,7 @@ dependencies {
implementation
(
libs
.
material
)
implementation
(
libs
.
material
)
implementation
(
libs
.
androidx
.
activity
)
implementation
(
libs
.
androidx
.
activity
)
implementation
(
libs
.
androidx
.
constraintlayout
)
implementation
(
libs
.
androidx
.
constraintlayout
)
implementation
(
libs
.
core
)
testImplementation
(
libs
.
junit
)
testImplementation
(
libs
.
junit
)
androidTestImplementation
(
libs
.
androidx
.
junit
)
androidTestImplementation
(
libs
.
androidx
.
junit
)
androidTestImplementation
(
libs
.
androidx
.
espresso
.
core
)
androidTestImplementation
(
libs
.
androidx
.
espresso
.
core
)
...
...
app/src/main/java/com/base/browserwhite/MyApplication.kt
View file @
f1eb821d
...
@@ -7,6 +7,9 @@ import com.base.browserwhite.utils.ActivityManagerUtils
...
@@ -7,6 +7,9 @@ import com.base.browserwhite.utils.ActivityManagerUtils
import
com.downloader.PRDownloader
import
com.downloader.PRDownloader
import
com.downloader.PRDownloaderConfig
import
com.downloader.PRDownloaderConfig
import
com.facebook.FacebookSdk
import
com.facebook.FacebookSdk
import
com.google.ar.core.Config
import
com.liulishuo.filedownloader.FileDownloader
import
com.liulishuo.filedownloader.connection.FileDownloadConnection
class
MyApplication
:
Application
()
{
class
MyApplication
:
Application
()
{
...
@@ -103,11 +106,16 @@ class MyApplication : Application() {
...
@@ -103,11 +106,16 @@ class MyApplication : Application() {
}
}
private
fun
initPRDownloader
()
{
private
fun
initPRDownloader
()
{
val
config
=
PRDownloaderConfig
.
newBuilder
()
.
setReadTimeout
(
30000
)
// 创建 FileDownloader 的配置对象
.
setConnectTimeout
(
30000
)
// val config = FileDownloader.Config.Builder()
.
setDatabaseEnabled
(
true
)
// .setConnectionComponent(FileDownloadConnection.Impl.create(this).setRetryOnGone(true))
.
build
()
// .setMinIntervalMillisCallbackProcess(1000) // 设置回调间隔时间
PRDownloader
.
initialize
(
applicationContext
,
config
)
// .setPath("path/to/your/download/directory", true) // 设置下载文件的存储路径
// // 其他配置...
// .build()
// 初始化 FileDownloader
FileDownloader
.
setupOnApplicationOnCreate
(
this
)
}
}
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/bean/DownloadBean.kt
View file @
f1eb821d
package
com.base.browserwhite.bean
package
com.base.browserwhite.bean
import
com.downloader.Status
data class
DownloadBean
(
data class
DownloadBean
(
var
downloadId
:
Int
=
-
1
,
var
downloadId
:
Int
=
-
1
,
var
path
:
String
=
""
,
var
path
:
String
=
""
,
val
ur
i
:
String
=
""
,
val
ur
l
:
String
=
""
,
var
time
:
String
=
""
,
var
time
:
String
=
""
,
)
{
)
{
var
state
:
Status
=
Status
.
UNKNOWN
var
progress
:
Int
=
-
1
var
progress
:
Int
=
-
1
var
name
:
String
=
""
var
name
:
String
=
""
var
isTime
:
Boolean
=
false
var
isTime
:
Boolean
=
false
var
uiType
:
Int
=
1
var
uiType
:
Int
=
1
var
size
:
Long
=
-
1
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/ui/activity/webbrowser/WebViewFragment.kt
View file @
f1eb821d
...
@@ -20,18 +20,22 @@ import com.base.browserwhite.bean.DownloadBean
...
@@ -20,18 +20,22 @@ import com.base.browserwhite.bean.DownloadBean
import
com.base.browserwhite.databinding.FragmentWebViewBinding
import
com.base.browserwhite.databinding.FragmentWebViewBinding
import
com.base.browserwhite.ui.adapter.DownloadAdapter
import
com.base.browserwhite.ui.adapter.DownloadAdapter
import
com.base.browserwhite.ui.fragment.BaseFragment
import
com.base.browserwhite.ui.fragment.BaseFragment
import
com.base.browserwhite.ui.views.D
ialogViews
.showDownloadVideoDialog
import
com.base.browserwhite.ui.views.D
ownloadDialog
.showDownloadVideoDialog
import
com.base.browserwhite.utils.DownloadHelper.getDownloadJson
import
com.base.browserwhite.utils.DownloadHelper.getDownloadJson
import
com.base.browserwhite.utils.DownloadHelper.getNotFinishList
import
com.base.browserwhite.utils.DownloadHelper.getNotFinishList
import
com.base.browserwhite.utils.KotlinExt.toFormatTime
import
com.base.browserwhite.utils.KotlinExt.toFormatTime
import
com.base.browserwhite.utils.LogEx
import
com.base.browserwhite.utils.LogEx
import
com.downloader.PRDownloader
import
com.downloader.Status
import
com.google.gson.Gson
import
com.google.gson.Gson
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.delay
import
kotlinx.coroutines.delay
import
kotlinx.coroutines.launch
import
kotlinx.coroutines.launch
import
okhttp3.Call
import
okhttp3.Callback
import
okhttp3.OkHttpClient
import
okhttp3.Request
import
okhttp3.Response
import
org.json.JSONArray
import
org.json.JSONArray
import
java.io.IOException
import
kotlin.random.Random
import
kotlin.random.Random
...
@@ -75,6 +79,7 @@ class WebViewFragment : BaseFragment<FragmentWebViewBinding>() {
...
@@ -75,6 +79,7 @@ class WebViewFragment : BaseFragment<FragmentWebViewBinding>() {
}
}
reloadWebView
()
reloadWebView
()
}
}
binding
.
flDownload
.
setOnClickListener
{
binding
.
flDownload
.
setOnClickListener
{
if
(
downloadAdapter
==
null
)
{
if
(
downloadAdapter
==
null
)
{
downloadAdapter
=
DownloadAdapter
()
downloadAdapter
=
DownloadAdapter
()
...
@@ -97,15 +102,10 @@ class WebViewFragment : BaseFragment<FragmentWebViewBinding>() {
...
@@ -97,15 +102,10 @@ class WebViewFragment : BaseFragment<FragmentWebViewBinding>() {
val
recordFile
=
requireContext
().
getDownloadJson
()
val
recordFile
=
requireContext
().
getDownloadJson
()
val
gson
=
Gson
()
val
gson
=
Gson
()
val
list
=
downloadList
.
filter
{
val
list
=
downloadList
it
.
state
==
Status
.
PAUSED
||
it
.
state
==
Status
.
RUNNING
}
list
.
forEach
{
it
.
time
=
System
.
currentTimeMillis
().
toFormatTime
()
}
list
.
forEach
{
it
.
time
=
System
.
currentTimeMillis
().
toFormatTime
()
}
val
olderList
=
getNotFinishList
(
recordFile
,
gson
).
filter
{
old
->
val
olderList
=
getNotFinishList
(
recordFile
,
gson
).
filter
{
!
list
.
contains
(
it
)
}
val
status
=
PRDownloader
.
getStatus
(
old
.
downloadId
)
status
==
Status
.
PAUSED
||
status
==
Status
.
RUNNING
}.
filter
{
!
list
.
contains
(
it
)
}
val
arrayList
=
arrayListOf
<
DownloadBean
>()
val
arrayList
=
arrayListOf
<
DownloadBean
>()
arrayList
.
addAll
(
olderList
)
arrayList
.
addAll
(
olderList
)
...
@@ -283,20 +283,32 @@ class WebViewFragment : BaseFragment<FragmentWebViewBinding>() {
...
@@ -283,20 +283,32 @@ class WebViewFragment : BaseFragment<FragmentWebViewBinding>() {
LogEx
.
logDebug
(
TAG
,
"value=$value"
)
LogEx
.
logDebug
(
TAG
,
"value=$value"
)
// 将字符串转换为JSON数组,然后处理
// 将字符串转换为JSON数组,然后处理
val
jsonArray
=
JSONArray
(
value
)
val
jsonArray
=
JSONArray
(
value
)
if
(
jsonArray
.
length
()
!=
0
)
{
binding
.
flDownload
.
visibility
=
View
.
VISIBLE
binding
.
tvDownloadNumber
.
text
=
jsonArray
.
length
().
toString
()
}
val
recordFile
=
requireContext
().
getDownloadJson
()
val
recordFile
=
requireContext
().
getDownloadJson
()
val
olderList
=
getNotFinishList
(
recordFile
,
Gson
())
val
olderList
=
getNotFinishList
(
recordFile
,
Gson
())
val
set
=
hashSetOf
<
String
>()
for
(
i
in
0
until
jsonArray
.
length
())
{
for
(
i
in
0
until
jsonArray
.
length
())
{
val
videoUrl
=
jsonArray
.
optString
(
i
)
val
videoUrl
=
jsonArray
.
optString
(
i
)
LogEx
.
logDebug
(
TAG
,
videoUrl
)
set
.
add
(
videoUrl
)
val
olderBean
=
olderList
.
findLast
{
it
.
uri
==
videoUrl
}
}
if
(
set
.
size
!=
0
)
{
binding
.
flDownload
.
visibility
=
View
.
VISIBLE
binding
.
tvDownloadNumber
.
text
=
set
.
size
.
toString
()
}
set
.
forEach
{
url
->
LogEx
.
logDebug
(
TAG
,
url
)
val
olderBean
=
olderList
.
findLast
{
it
.
url
==
url
}
if
(
olderBean
!=
null
)
{
if
(
olderBean
!=
null
)
{
LogEx
.
logDebug
(
TAG
,
"old path=${olderBean.path} ${olderBean.downloadId}"
)
downloadList
.
add
(
olderBean
)
downloadList
.
add
(
olderBean
)
}
else
{
}
else
{
downloadList
.
add
(
DownloadBean
(
uri
=
videoUrl
).
apply
{
uiType
=
2
})
downloadList
.
add
(
DownloadBean
(
url
=
url
).
apply
{
uiType
=
2
})
}
}
lifecycleScope
.
launch
(
Dispatchers
.
IO
)
{
downloadList
.
forEach
{
fastGetSize
(
it
)
}
}
}
}
isParsing
=
false
isParsing
=
false
...
@@ -339,4 +351,39 @@ class WebViewFragment : BaseFragment<FragmentWebViewBinding>() {
...
@@ -339,4 +351,39 @@ class WebViewFragment : BaseFragment<FragmentWebViewBinding>() {
}
}
}
}
private
fun
fastGetSize
(
bean
:
DownloadBean
)
{
if
(
bean
.
size
==
-
1L
)
{
val
client
=
OkHttpClient
()
val
request
=
Request
.
Builder
()
.
url
(
bean
.
url
)
.
head
()
// 发送 HEAD 请求
.
build
()
try
{
client
.
newCall
(
request
).
enqueue
(
object
:
Callback
{
override
fun
onFailure
(
call
:
Call
,
e
:
IOException
)
{
// 处理请求失败的情况
LogEx
.
logDebug
(
TAG
,
"onFailure"
)
}
override
fun
onResponse
(
call
:
Call
,
response
:
Response
)
{
if
(
response
.
isSuccessful
)
{
val
contentLength
=
response
.
header
(
"Content-Length"
)
// 获取内容长度
contentLength
?.
let
{
// 将内容长度转换为 Long 类型
val
videoSize
=
it
.
toLong
()
// 在这里使用视频大小,例如在主线程更新 UI 或存储到变量中
bean
.
size
=
videoSize
LogEx
.
logDebug
(
TAG
,
"videoSize=$videoSize"
)
}
}
}
})
}
catch
(
e
:
Exception
)
{
// 处理异常情况
}
}
}
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/ui/adapter/DownloadAdapter.kt
View file @
f1eb821d
...
@@ -11,16 +11,24 @@ import com.base.browserwhite.bean.DownloadBean
...
@@ -11,16 +11,24 @@ import com.base.browserwhite.bean.DownloadBean
import
com.base.browserwhite.databinding.ItemDownloadBinding
import
com.base.browserwhite.databinding.ItemDownloadBinding
import
com.base.browserwhite.databinding.ItemDownloadCardBinding
import
com.base.browserwhite.databinding.ItemDownloadCardBinding
import
com.base.browserwhite.databinding.ItemDownloadTimeBinding
import
com.base.browserwhite.databinding.ItemDownloadTimeBinding
import
com.base.browserwhite.ui.views.DownloadDialog.showDownloadConfirmDialog
import
com.base.browserwhite.utils.KotlinExt.toFormatSize
import
com.base.browserwhite.utils.KotlinExt.toFormatSize
import
com.base.browserwhite.utils.LogEx
import
com.base.browserwhite.utils.LogEx
import
com.base.browserwhite.utils.VideoDownloader
import
com.base.browserwhite.utils.VideoDownloader
.getDownloadPath
import
com.base.browserwhite.utils.XmlEx.inflate
import
com.base.browserwhite.utils.XmlEx.inflate
import
com.bumptech.glide.Glide
import
com.bumptech.glide.Glide
import
com.chad.library.adapter4.BaseQuickAdapter
import
com.chad.library.adapter4.BaseQuickAdapter
import
com.downloader.PRDownloader
import
com.liulishuo.filedownloader.BaseDownloadTask
import
com.downloader.Status
import
com.liulishuo.filedownloader.FileDownloadListener
import
com.downloader.internal.DownloadRequestQueue
import
com.liulishuo.filedownloader.FileDownloader
import
com.liulishuo.filedownloader.model.FileDownloadStatus
import
okhttp3.Call
import
okhttp3.Callback
import
okhttp3.OkHttpClient
import
okhttp3.Request
import
okhttp3.Response
import
java.io.File
import
java.io.File
import
java.io.IOException
class
DownloadAdapter
:
BaseQuickAdapter
<
DownloadBean
,
DownloadAdapter
.
DownloadViewHolder
>()
{
class
DownloadAdapter
:
BaseQuickAdapter
<
DownloadBean
,
DownloadAdapter
.
DownloadViewHolder
>()
{
...
@@ -29,7 +37,7 @@ class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadV
...
@@ -29,7 +37,7 @@ class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadV
inner
class
DownloadViewHolder
(
view
:
View
)
:
ViewHolder
(
view
)
inner
class
DownloadViewHolder
(
view
:
View
)
:
ViewHolder
(
view
)
var
downloadAction
:
((
item
:
DownloadBean
)
->
Unit
)?
=
null
var
downloadAction
:
(()
->
Unit
)?
=
null
override
fun
onBindViewHolder
(
holder
:
DownloadViewHolder
,
position
:
Int
,
item
:
DownloadBean
?)
{
override
fun
onBindViewHolder
(
holder
:
DownloadViewHolder
,
position
:
Int
,
item
:
DownloadBean
?)
{
if
(
item
==
null
)
return
if
(
item
==
null
)
return
...
@@ -47,25 +55,30 @@ class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadV
...
@@ -47,25 +55,30 @@ class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadV
}
else
if
(
item
.
uiType
==
2
)
{
}
else
if
(
item
.
uiType
==
2
)
{
val
binding
=
ItemDownloadCardBinding
.
bind
(
holder
.
itemView
)
val
binding
=
ItemDownloadCardBinding
.
bind
(
holder
.
itemView
)
Glide
.
with
(
context
).
load
(
item
.
uri
).
centerCrop
().
into
(
binding
.
iv
)
Glide
.
with
(
context
).
load
(
item
.
url
).
centerCrop
().
into
(
binding
.
iv
)
binding
.
tvName
.
text
=
if
(
item
.
name
.
isNotEmpty
())
item
.
name
else
item
.
uri
.
split
(
"/"
).
last
()
binding
.
tvName
.
text
=
if
(
item
.
name
.
isNotEmpty
())
item
.
name
else
item
.
url
.
split
(
"/"
).
last
()
binding
.
tvSize
.
text
=
item
.
size
.
toFormatSize
()
binding
.
ivDownload
.
isVisible
=
item
.
downloadId
==
-
1
val
status
=
FileDownloader
.
getImpl
().
getStatus
(
item
.
url
,
item
.
path
)
binding
.
flDownload
.
isVisible
=
item
.
state
!=
Status
.
UNKNOWN
LogEx
.
logDebug
(
TAG
,
"status=${status} item.path=${item.path}"
)
binding
.
ivDownload
.
isVisible
=
status
==
FileDownloadStatus
.
INVALID_STATUS
binding
.
flDownload
.
isVisible
=
!
binding
.
ivDownload
.
isVisible
binding
.
ivFinish
.
isVisible
=
false
binding
.
ivFinish
.
isVisible
=
false
when
(
item
.
state
)
{
when
(
status
)
{
Status
.
PAUSED
->
{
FileDownloadStatus
.
paused
->
{
binding
.
ivXiazaiZantin
.
setImageResource
(
R
.
mipmap
.
zanting_download
)
binding
.
ivXiazaiZantin
.
setImageResource
(
R
.
mipmap
.
zanting_download
)
binding
.
circularProgressBar
.
progress
=
item
.
progress
.
toFloat
()
binding
.
circularProgressBar
.
progress
=
item
.
progress
.
toFloat
()
}
}
Status
.
RUNNING
->
{
FileDownloadStatus
.
progress
->
{
binding
.
ivXiazaiZantin
.
setImageResource
(
R
.
mipmap
.
xiazhaiz_download
)
binding
.
ivXiazaiZantin
.
setImageResource
(
R
.
mipmap
.
xiazhaiz_download
)
binding
.
circularProgressBar
.
progress
=
item
.
progress
.
toFloat
()
binding
.
circularProgressBar
.
progress
=
item
.
progress
.
toFloat
()
replaceListener
(
item
)
}
}
Status
.
COMPLETED
->
{
FileDownloadStatus
.
completed
->
{
binding
.
flDownload
.
isVisible
=
false
binding
.
flDownload
.
isVisible
=
false
binding
.
ivFinish
.
isVisible
=
true
binding
.
ivFinish
.
isVisible
=
true
}
}
...
@@ -76,16 +89,12 @@ class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadV
...
@@ -76,16 +89,12 @@ class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadV
}
}
binding
.
ivDownload
.
setOnClickListener
{
binding
.
ivDownload
.
setOnClickListener
{
downloadAction
?.
invoke
(
item
)
downloadAction
?.
invoke
()
context
.
showDownloadConfirmDialog
(
item
)
{
downloadItem
(
context
,
item
)
}
}
}
binding
.
flDownload
.
setOnClickListener
{
binding
.
flDownload
.
setOnClickListener
{
val
status
:
Status
=
PRDownloader
.
getStatus
(
item
.
downloadId
)
if
(
status
==
Status
.
PAUSED
)
{
PRDownloader
.
resume
(
item
.
downloadId
)
}
if
(
status
==
Status
.
RUNNING
)
{
PRDownloader
.
pause
(
item
.
downloadId
)
}
}
}
}
}
...
@@ -108,25 +117,76 @@ class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadV
...
@@ -108,25 +117,76 @@ class DownloadAdapter : BaseQuickAdapter<DownloadBean, DownloadAdapter.DownloadV
}
}
@SuppressLint
(
"NotifyDataSetChanged"
)
@SuppressLint
(
"NotifyDataSetChanged"
)
fun
downloadItem
(
bean
:
DownloadBean
)
{
fun
downloadItem
(
context
:
Context
,
bean
:
DownloadBean
)
{
val
pair
=
VideoDownloader
.
downloadVideo2
(
context
,
bean
.
uri
,
bean
.
name
,
bean
.
path
=
context
.
getDownloadPath
(
bean
.
url
,
bean
.
name
)
progressAction
=
{
progress
->
LogEx
.
logDebug
(
TAG
,
"progress=$progress"
)
val
downloadTask
=
FileDownloader
.
getImpl
().
create
(
bean
.
url
)
bean
.
progress
=
progress
.
setPath
(
bean
.
path
)
val
status
:
Status
=
PRDownloader
.
getStatus
(
bean
.
downloadId
)
.
setCallbackProgressMinInterval
(
500
)
bean
.
state
=
status
.
setListener
(
object
:
FileDownloadListener
()
{
override
fun
pending
(
task
:
BaseDownloadTask
?,
soFarBytes
:
Int
,
totalBytes
:
Int
)
{
}
override
fun
progress
(
task
:
BaseDownloadTask
?,
soFarBytes
:
Int
,
totalBytes
:
Int
)
{
val
percent
=
soFarBytes
*
100
/
totalBytes
bean
.
progress
=
percent
notifyDataSetChanged
()
}
override
fun
connected
(
task
:
BaseDownloadTask
?,
etag
:
String
?,
isContinue
:
Boolean
,
soFarBytes
:
Int
,
totalBytes
:
Int
)
{
super
.
connected
(
task
,
etag
,
isContinue
,
soFarBytes
,
totalBytes
)
if
(
isContinue
)
{
// 如果是继续之前的下载
}
}
override
fun
completed
(
task
:
BaseDownloadTask
?)
{
notifyDataSetChanged
()
}
override
fun
paused
(
task
:
BaseDownloadTask
?,
soFarBytes
:
Int
,
totalBytes
:
Int
)
{
}
override
fun
error
(
task
:
BaseDownloadTask
?,
e
:
Throwable
?)
{
}
override
fun
warn
(
task
:
BaseDownloadTask
?)
{
}
})
downloadTask
.
start
()
}
private
fun
replaceListener
(
item
:
DownloadBean
)
{
FileDownloader
.
getImpl
().
replaceListener
(
item
.
downloadId
,
object
:
FileDownloadListener
()
{
override
fun
pending
(
task
:
BaseDownloadTask
?,
soFarBytes
:
Int
,
totalBytes
:
Int
)
{
}
@SuppressLint
(
"NotifyDataSetChanged"
)
override
fun
progress
(
task
:
BaseDownloadTask
?,
soFarBytes
:
Int
,
totalBytes
:
Int
)
{
val
percent
=
soFarBytes
*
100
/
totalBytes
item
.
progress
=
percent
notifyDataSetChanged
()
notifyDataSetChanged
()
},
}
finishAction
=
{
val
status
:
Status
=
PRDownloader
.
getStatus
(
bean
.
downloadId
)
@SuppressLint
(
"NotifyDataSetChanged"
)
bean
.
state
=
status
override
fun
completed
(
task
:
BaseDownloadTask
?)
{
LogEx
.
logDebug
(
TAG
,
"status=$status"
)
notifyDataSetChanged
()
notifyDataSetChanged
()
}
}
)
bean
.
downloadId
=
pair
.
first
override
fun
paused
(
task
:
BaseDownloadTask
?,
soFarBytes
:
Int
,
totalBytes
:
Int
)
{
bean
.
path
=
pair
.
second
.
absolutePath
}
override
fun
error
(
task
:
BaseDownloadTask
?,
e
:
Throwable
?)
{
}
override
fun
warn
(
task
:
BaseDownloadTask
?)
{
}
})
}
}
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/ui/views/DialogViews.kt
View file @
f1eb821d
...
@@ -234,114 +234,5 @@ object DialogViews {
...
@@ -234,114 +234,5 @@ object DialogViews {
}
}
}
}
fun
Context
.
showDownloadVideoDialog
(
adapter
:
DownloadAdapter
,
list
:
List
<
DownloadBean
>,
dismissAction
:
()
->
Unit
):
DownloadAdapter
{
val
TAG
=
"DownloadVideoDialog"
val
dialog
=
BottomSheetDialog
(
this
)
val
binding
=
DialogDownloadVideoBinding
.
inflate
(
LayoutInflater
.
from
(
this
))
dialog
.
setContentView
(
binding
.
root
)
dialog
.
setCanceledOnTouchOutside
(
false
)
dialog
.
show
()
val
itemHeight
=
resources
.
getDimensionPixelOffset
(
R
.
dimen
.
dp_97
)
LogEx
.
logDebug
(
TAG
,
"itemHeight=$itemHeight"
)
if
(
list
.
size
>
3
)
{
val
recyclerViewHeight
:
Int
=
3
*
itemHeight
binding
.
rv
.
layoutParams
.
height
=
recyclerViewHeight
binding
.
rv
.
requestLayout
()
}
val
parentView
=
binding
.
root
.
parent
as
View
val
behavior
=
BottomSheetBehavior
.
from
(
parentView
)
//展开
behavior
.
state
=
BottomSheetBehavior
.
STATE_EXPANDED
adapter
.
downloadAction
=
{
item
:
DownloadBean
->
dialog
.
dismiss
()
showDownloadConfirmDialog
(
item
)
{
adapter
.
downloadItem
(
item
)
}
}
binding
.
rv
.
adapter
=
adapter
adapter
.
submitList
(
list
)
dialog
.
setOnDismissListener
{
dismissAction
.
invoke
()
}
binding
.
tvDownloadDir
.
setOnClickListener
{
dialog
.
dismiss
()
startActivity
(
Intent
(
this
,
WebDownloadManagerActivity
::
class
.
java
))
}
return
adapter
}
private
fun
Context
.
showDownloadConfirmDialog
(
item
:
DownloadBean
,
download
:
()
->
Unit
)
{
val
dialog
=
BottomSheetDialog
(
this
)
val
binding
=
DialogDownloadConfirmBinding
.
inflate
(
LayoutInflater
.
from
(
this
))
dialog
.
setContentView
(
binding
.
root
)
dialog
.
setCanceledOnTouchOutside
(
false
)
dialog
.
show
()
val
parentView
=
binding
.
root
.
parent
as
View
val
behavior
=
BottomSheetBehavior
.
from
(
parentView
)
//展开
behavior
.
state
=
BottomSheetBehavior
.
STATE_EXPANDED
Glide
.
with
(
this
).
load
(
item
.
uri
).
centerCrop
().
into
(
binding
.
iv
)
binding
.
editName
.
setText
(
item
.
uri
.
split
(
"/"
).
last
())
binding
.
ivEdit
.
setOnClickListener
{
binding
.
editName
.
isEnabled
=
true
binding
.
editName
.
setBackgroundResource
(
android
.
R
.
drawable
.
edit_text
)
binding
.
editName
.
requestFocus
()
}
binding
.
editName
.
setOnFocusChangeListener
{
v
,
hasFocus
->
if
(
hasFocus
)
{
val
imm
=
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
)
as
InputMethodManager
?
imm
?.
showSoftInput
(
v
,
InputMethodManager
.
SHOW_IMPLICIT
)
}
}
binding
.
editName
.
setOnEditorActionListener
(
object
:
OnEditorActionListener
{
override
fun
onEditorAction
(
v
:
TextView
?,
actionId
:
Int
,
event
:
KeyEvent
?):
Boolean
{
if
(
actionId
==
EditorInfo
.
IME_ACTION_DONE
)
{
binding
.
editName
.
isEnabled
=
false
binding
.
editName
.
background
=
null
return
true
}
return
false
}
})
binding
.
tvCancel
.
setOnClickListener
{
dialog
.
dismiss
()
}
binding
.
tvConfirm
.
setOnClickListener
{
if
(
binding
.
editName
.
text
.
isNullOrEmpty
())
{
Toast
.
makeText
(
this
,
"name is empty"
,
Toast
.
LENGTH_SHORT
).
show
()
return
@setOnClickListener
}
item
.
name
=
binding
.
editName
.
text
.
toString
()
dialog
.
dismiss
()
download
.
invoke
()
}
}
fun
Context
.
showDownloadFinishDialog
()
{
val
binding
=
DialogDownloadFinishBinding
.
inflate
(
LayoutInflater
.
from
(
this
))
val
dialog
=
AlertDialog
.
Builder
(
this
).
create
()
dialog
.
setView
(
binding
.
root
)
dialog
.
show
()
val
params
=
dialog
.
window
?.
attributes
params
?.
width
=
resources
.
getDimensionPixelOffset
(
R
.
dimen
.
dp_335
)
dialog
.
window
?.
attributes
=
params
dialog
.
window
?.
setBackgroundDrawableResource
(
android
.
R
.
color
.
transparent
)
}
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/ui/views/DownloadDialog.kt
0 → 100644
View file @
f1eb821d
package
com.base.browserwhite.ui.views
import
android.app.AlertDialog
import
android.content.Context
import
android.content.Intent
import
android.view.KeyEvent
import
android.view.LayoutInflater
import
android.view.View
import
android.view.inputmethod.EditorInfo
import
android.view.inputmethod.InputMethodManager
import
android.widget.TextView
import
android.widget.TextView.OnEditorActionListener
import
android.widget.Toast
import
com.base.browserwhite.R
import
com.base.browserwhite.bean.DownloadBean
import
com.base.browserwhite.databinding.DialogDownloadConfirmBinding
import
com.base.browserwhite.databinding.DialogDownloadFinishBinding
import
com.base.browserwhite.databinding.DialogDownloadVideoBinding
import
com.base.browserwhite.ui.activity.download.WebDownloadManagerActivity
import
com.base.browserwhite.ui.adapter.DownloadAdapter
import
com.base.browserwhite.utils.LogEx
import
com.bumptech.glide.Glide
import
com.google.android.material.bottomsheet.BottomSheetBehavior
import
com.google.android.material.bottomsheet.BottomSheetDialog
object
DownloadDialog
{
fun
Context
.
showDownloadVideoDialog
(
adapter
:
DownloadAdapter
,
list
:
List
<
DownloadBean
>,
dismissAction
:
()
->
Unit
)
{
val
TAG
=
"DownloadVideoDialog"
val
dialog
=
BottomSheetDialog
(
this
)
val
binding
=
DialogDownloadVideoBinding
.
inflate
(
LayoutInflater
.
from
(
this
))
dialog
.
setContentView
(
binding
.
root
)
dialog
.
setCanceledOnTouchOutside
(
false
)
dialog
.
show
()
val
itemHeight
=
resources
.
getDimensionPixelOffset
(
R
.
dimen
.
dp_97
)
LogEx
.
logDebug
(
TAG
,
"itemHeight=$itemHeight"
)
if
(
list
.
size
>
3
)
{
val
recyclerViewHeight
:
Int
=
3
*
itemHeight
binding
.
rv
.
layoutParams
.
height
=
recyclerViewHeight
binding
.
rv
.
requestLayout
()
}
val
parentView
=
binding
.
root
.
parent
as
View
val
behavior
=
BottomSheetBehavior
.
from
(
parentView
)
//展开
behavior
.
state
=
BottomSheetBehavior
.
STATE_EXPANDED
adapter
.
downloadAction
=
{
dialog
.
dismiss
()
}
binding
.
rv
.
adapter
=
adapter
adapter
.
submitList
(
list
)
dialog
.
setOnDismissListener
{
dismissAction
.
invoke
()
}
binding
.
tvDownloadDir
.
setOnClickListener
{
dialog
.
dismiss
()
startActivity
(
Intent
(
this
,
WebDownloadManagerActivity
::
class
.
java
))
}
}
fun
Context
.
showDownloadConfirmDialog
(
item
:
DownloadBean
,
download
:
()
->
Unit
)
{
val
dialog
=
BottomSheetDialog
(
this
)
val
binding
=
DialogDownloadConfirmBinding
.
inflate
(
LayoutInflater
.
from
(
this
))
dialog
.
setContentView
(
binding
.
root
)
dialog
.
setCanceledOnTouchOutside
(
false
)
dialog
.
show
()
val
parentView
=
binding
.
root
.
parent
as
View
val
behavior
=
BottomSheetBehavior
.
from
(
parentView
)
//展开
behavior
.
state
=
BottomSheetBehavior
.
STATE_EXPANDED
Glide
.
with
(
this
).
load
(
item
.
url
).
centerCrop
().
into
(
binding
.
iv
)
binding
.
editName
.
setText
(
item
.
url
.
split
(
"/"
).
last
())
binding
.
ivEdit
.
setOnClickListener
{
binding
.
editName
.
isEnabled
=
true
binding
.
editName
.
setBackgroundResource
(
android
.
R
.
drawable
.
edit_text
)
binding
.
editName
.
requestFocus
()
}
binding
.
editName
.
setOnFocusChangeListener
{
v
,
hasFocus
->
if
(
hasFocus
)
{
val
imm
=
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
)
as
InputMethodManager
?
imm
?.
showSoftInput
(
v
,
InputMethodManager
.
SHOW_IMPLICIT
)
}
}
binding
.
editName
.
setOnEditorActionListener
(
object
:
OnEditorActionListener
{
override
fun
onEditorAction
(
v
:
TextView
?,
actionId
:
Int
,
event
:
KeyEvent
?):
Boolean
{
if
(
actionId
==
EditorInfo
.
IME_ACTION_DONE
)
{
binding
.
editName
.
isEnabled
=
false
binding
.
editName
.
background
=
null
return
true
}
return
false
}
})
binding
.
tvCancel
.
setOnClickListener
{
dialog
.
dismiss
()
}
binding
.
tvConfirm
.
setOnClickListener
{
if
(
binding
.
editName
.
text
.
isNullOrEmpty
())
{
Toast
.
makeText
(
this
,
"name is empty"
,
Toast
.
LENGTH_SHORT
).
show
()
return
@setOnClickListener
}
item
.
name
=
binding
.
editName
.
text
.
toString
()
dialog
.
dismiss
()
download
.
invoke
()
}
}
fun
Context
.
showDownloadFinishDialog
()
{
val
binding
=
DialogDownloadFinishBinding
.
inflate
(
LayoutInflater
.
from
(
this
))
val
dialog
=
AlertDialog
.
Builder
(
this
).
create
()
dialog
.
setView
(
binding
.
root
)
dialog
.
show
()
val
params
=
dialog
.
window
?.
attributes
params
?.
width
=
resources
.
getDimensionPixelOffset
(
R
.
dimen
.
dp_335
)
dialog
.
window
?.
attributes
=
params
dialog
.
window
?.
setBackgroundDrawableResource
(
android
.
R
.
color
.
transparent
)
}
}
\ No newline at end of file
app/src/main/java/com/base/browserwhite/utils/VideoDownloader.kt
View file @
f1eb821d
package
com.base.browserwhite.utils
package
com.base.browserwhite.utils
import
android.app.DownloadManager
import
android.app.DownloadManager.Request.NETWORK_WIFI
import
android.content.Context
import
android.content.Context
import
android.net.Uri
import
android.os.Environment
import
android.os.Environment
import
com.base.browserwhite.R
import
com.base.browserwhite.R
import
com.downloader.Error
import
com.downloader.OnDownloadListener
import
com.downloader.PRDownloader
import
com.downloader.internal.DownloadTask
import
java.io.File
import
java.io.File
object
VideoDownloader
{
object
VideoDownloader
{
//https://assets.mixkit.co/videos/4702/4702-720.mp4
fun
Context
.
getDownloadPath
(
fun
downloadVideo
(
context
:
Context
,
uri
:
String
,
name
:
String
):
Pair
<
Long
,
File
>
{
val
downloadManager
=
context
.
getSystemService
(
Context
.
DOWNLOAD_SERVICE
)
as
DownloadManager
var
fileName
=
uri
.
split
(
"/"
).
last
()
if
(
name
.
isNotEmpty
())
{
fileName
=
name
}
// 创建一个DownloadManager.Request对象
val
request
=
DownloadManager
.
Request
(
Uri
.
parse
(
uri
))
// 设置下载的标题和描述
request
.
setTitle
(
fileName
)
request
.
setDescription
(
"Downloading $fileName"
)
request
.
setAllowedNetworkTypes
(
NETWORK_WIFI
)
// 设置通知栏的可见性
request
.
setNotificationVisibility
(
DownloadManager
.
Request
.
VISIBILITY_VISIBLE
)
// 设置下载的文件类型
request
.
setMimeType
(
"video/mp4"
)
// 设置下载文件的存储位置
val
subPath
=
context
.
resources
.
getString
(
R
.
string
.
app_name
)
+
"/$fileName"
request
.
setDestinationInExternalPublicDir
(
Environment
.
DIRECTORY_DOWNLOADS
,
subPath
)
// 设置是否允许漫游
request
.
setAllowedOverRoaming
(
false
)
// 将下载请求加入下载队列
val
downloadId
=
downloadManager
.
enqueue
(
request
)
val
filePath
=
File
(
Environment
.
getExternalStoragePublicDirectory
(
Environment
.
DIRECTORY_DOWNLOADS
),
subPath
)
return
Pair
(
downloadId
,
filePath
)
}
fun
downloadVideo2
(
context
:
Context
,
url
:
String
,
url
:
String
,
name
:
String
,
name
:
String
,
progressAction
:
(
progress
:
Int
)
->
Unit
,
):
String
{
finishAction
:
()
->
Unit
):
Pair
<
Int
,
File
>
{
var
fileName
=
url
.
split
(
"/"
).
last
()
var
fileName
=
url
.
split
(
"/"
).
last
()
if
(
name
.
isNotEmpty
())
{
if
(
name
.
isNotEmpty
())
{
fileName
=
name
fileName
=
name
}
}
// 设置下载文件的存储位置
// 设置下载文件的存储位置
val
dirPath
=
File
(
val
dirPath
=
File
(
Environment
.
getExternalStoragePublicDirectory
(
Environment
.
DIRECTORY_DOWNLOADS
),
Environment
.
getExternalStoragePublicDirectory
(
Environment
.
DIRECTORY_DOWNLOADS
),
resources
.
getString
(
R
.
string
.
app_name
)
context
.
resources
.
getString
(
R
.
string
.
app_name
)
).
absolutePath
).
absolutePath
val
downloadId
=
PRDownloader
.
download
(
url
,
dirPath
,
fileName
)
val
path
=
"$dirPath/$fileName"
.
build
()
.
setOnStartOrResumeListener
{
}
.
setOnPauseListener
{
}
.
setOnCancelListener
{
}
.
setOnProgressListener
{
val
percent
=
it
.
currentBytes
*
100
/
it
.
totalBytes
progressAction
.
invoke
(
percent
.
toInt
())
}.
start
(
object
:
OnDownloadListener
{
override
fun
onDownloadComplete
()
{
finishAction
.
invoke
()
}
override
fun
onError
(
p0
:
Error
?)
{
return
path
finishAction
.
invoke
()
}
})
val
filePath
=
File
(
dirPath
,
fileName
)
return
Pair
(
downloadId
,
filePath
)
}
}
}
}
\ No newline at end of file
gradle/libs.versions.toml
View file @
f1eb821d
...
@@ -14,6 +14,7 @@ navigationUiKtx = "2.6.0"
...
@@ -14,6 +14,7 @@ navigationUiKtx = "2.6.0"
viewbinding
=
"8.5.1"
viewbinding
=
"8.5.1"
navigationFragmentKtxVersion
=
"2.6.0"
navigationFragmentKtxVersion
=
"2.6.0"
navigationUiKtxVersion
=
"2.6.0"
navigationUiKtxVersion
=
"2.6.0"
core
=
"1.45.0"
[libraries]
[libraries]
androidx-core-ktx
=
{
group
=
"androidx.core"
,
name
=
"core-ktx"
,
version.ref
=
"coreKtx"
}
androidx-core-ktx
=
{
group
=
"androidx.core"
,
name
=
"core-ktx"
,
version.ref
=
"coreKtx"
}
...
@@ -26,6 +27,7 @@ androidx-activity = { group = "androidx.activity", name = "activity", version.re
...
@@ -26,6 +27,7 @@ androidx-activity = { group = "androidx.activity", name = "activity", version.re
androidx-constraintlayout
=
{
group
=
"androidx.constraintlayout"
,
name
=
"constraintlayout"
,
version.ref
=
"constraintlayout"
}
androidx-constraintlayout
=
{
group
=
"androidx.constraintlayout"
,
name
=
"constraintlayout"
,
version.ref
=
"constraintlayout"
}
androidx-navigation-fragment-ktx
=
{
group
=
"androidx.navigation"
,
name
=
"navigation-fragment-ktx"
,
version.ref
=
"navigationFragmentKtxVersion"
}
androidx-navigation-fragment-ktx
=
{
group
=
"androidx.navigation"
,
name
=
"navigation-fragment-ktx"
,
version.ref
=
"navigationFragmentKtxVersion"
}
androidx-navigation-ui-ktx
=
{
group
=
"androidx.navigation"
,
name
=
"navigation-ui-ktx"
,
version.ref
=
"navigationUiKtxVersion"
}
androidx-navigation-ui-ktx
=
{
group
=
"androidx.navigation"
,
name
=
"navigation-ui-ktx"
,
version.ref
=
"navigationUiKtxVersion"
}
core
=
{
group
=
"com.google.ar"
,
name
=
"core"
,
version.ref
=
"core"
}
[plugins]
[plugins]
androidApplication
=
{
id
=
"com.android.application"
,
version.ref
=
"agp"
}
androidApplication
=
{
id
=
"com.android.application"
,
version.ref
=
"agp"
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment