mirror of
https://github.com/fumiama/copymanga.git
synced 2026-06-10 02:00:25 +08:00
v1.3
1. 增加长按检查zip错误功能 2. 增加阅读zip跳转到下一话功能 3. 文件按话数升序排列
This commit is contained in:
@@ -11,8 +11,8 @@ android {
|
||||
applicationId "top.fumiama.copymanga"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 30
|
||||
versionCode 7
|
||||
versionName '1.2.1'
|
||||
versionCode 8
|
||||
versionName '1.3'
|
||||
resConfigs "zh", "zh-rCN"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.animation.ObjectAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.os.Looper
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
@@ -40,7 +41,7 @@ class DlActivity : Activity() {
|
||||
private lateinit var ltbtn: View
|
||||
var tbtnlist: List<ToggleButton> = arrayListOf()
|
||||
var tbtnUrlList = arrayListOf<String>()
|
||||
private val handler = DlHandler(this)
|
||||
private val handler = DlHandler(this, Looper.myLooper()!!)
|
||||
private var btnw = 0
|
||||
private var cdwnWidth = 0
|
||||
private var canDl = false
|
||||
@@ -87,7 +88,7 @@ class DlActivity : Activity() {
|
||||
}
|
||||
|
||||
private fun dlThead(dlMethod: (i: ToggleButton) -> Unit) {
|
||||
sleep(2333)
|
||||
sleep(100000)
|
||||
for (i in tbtnlist.listIterator()) {
|
||||
if (i.isChecked) dlMethod(i)
|
||||
if (!canDl) {
|
||||
@@ -133,14 +134,14 @@ class DlActivity : Activity() {
|
||||
haveDlStarted = true
|
||||
canDl = true
|
||||
handler.sendEmptyMessage(9) //set dl card color to red
|
||||
Toast.makeText(this, "准备下载...", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, "十秒后开始下载...", Toast.LENGTH_SHORT).show()
|
||||
fillChapters()
|
||||
Thread { dlThead { downloadChapterPages(it) } }.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
cdwn.setOnLongClickListener {
|
||||
Thread { handler.sendEmptyMessage(4) }.start()
|
||||
handler.sendEmptyMessage(4)
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
isearch.setOnClickListener { showMultiSelectInfo() }
|
||||
@@ -250,9 +251,7 @@ class DlActivity : Activity() {
|
||||
it.tbtn.isChecked = true
|
||||
tdwn.text = "$dldChapter/${++checkedChapter}"
|
||||
}
|
||||
Thread {
|
||||
handler.sendEmptyMessage(7)
|
||||
}.start()
|
||||
handler.sendEmptyMessage(7)
|
||||
})
|
||||
}
|
||||
true
|
||||
|
||||
@@ -2,25 +2,41 @@ package top.fumiama.copymanga.activity
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Toast
|
||||
import kotlinx.android.synthetic.main.activity_dlist.*
|
||||
import kotlinx.android.synthetic.main.widget_titlebar.*
|
||||
import top.fumiama.copymanga.R
|
||||
import top.fumiama.copymanga.handler.DlLHandler
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
import java.util.zip.ZipInputStream
|
||||
|
||||
class DlListActivity:Activity() {
|
||||
var nullZipDirStr = emptyArray<String>()
|
||||
var handler: DlLHandler? = null
|
||||
var loadingDialog: Dialog? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_dlist)
|
||||
ttitle.text = intent.getStringExtra("title")
|
||||
scanFile(currentDir)
|
||||
loadingDialog = Dialog(this)
|
||||
loadingDialog?.setContentView(R.layout.dialog_loading)
|
||||
handler = DlLHandler(Looper.myLooper()!!, this)
|
||||
handler?.obtainMessage(3, currentDir)?.sendToTarget() //call scanFile
|
||||
}
|
||||
|
||||
private fun scanFile(cd: File?){
|
||||
cd?.list()?.sortedArray()?.let {
|
||||
fun scanFile(cd: File?){
|
||||
cd?.list()?.sortedArrayWith { o1, o2 ->
|
||||
if(o1.endsWith(".zip") && o2.endsWith(".zip")) (10000*getFloat(o1) - 10000*getFloat(o2) + 0.5).toInt()
|
||||
else o1[0] - o2[0]
|
||||
}?.let {
|
||||
mylv.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, it)
|
||||
mylv.setOnItemClickListener { _, _, position, _ ->
|
||||
val chosenFile = File(cd, it[position])
|
||||
@@ -38,23 +54,28 @@ class DlListActivity:Activity() {
|
||||
Toast.makeText(this, "加载中...", Toast.LENGTH_SHORT).show()
|
||||
ViewMangaActivity.zipFile = chosenFile
|
||||
ViewMangaActivity.titleText = it[position]
|
||||
ViewMangaActivity.zipPosition = position
|
||||
ViewMangaActivity.zipList = it
|
||||
ViewMangaActivity.cd = cd
|
||||
startActivity(Intent(this, ViewMangaActivity::class.java))
|
||||
}
|
||||
}
|
||||
mylv.setOnItemLongClickListener { _, _, position, _ ->
|
||||
val chosenFile = File(cd, it[position])
|
||||
AlertDialog.Builder(this)
|
||||
.setIcon(R.drawable.ic_launcher_foreground).setMessage("是否删除?")
|
||||
.setTitle("提示").setPositiveButton("确定"){ _, _ ->
|
||||
if(chosenFile.exists()) rmrf(chosenFile)
|
||||
scanFile(cd)
|
||||
}.setNegativeButton("取消"){_, _ ->}.show()
|
||||
.setIcon(R.drawable.ic_launcher_foreground).setMessage("是否在此执行删除/查错?")
|
||||
.setTitle("提示").setPositiveButton(android.R.string.ok){ _, _ ->
|
||||
if(chosenFile.exists()) handler?.obtainMessage(2, chosenFile)?.sendToTarget() //call rmrf
|
||||
handler?.obtainMessage(3, cd)?.sendToTarget() //call scanFile
|
||||
}.setNegativeButton(android.R.string.cancel){_, _ ->}
|
||||
.setNeutralButton("查错"){_, _ -> handler?.obtainMessage(1, chosenFile)?.sendToTarget()} //call checkDir
|
||||
.show()
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun rmrf(f: File) {
|
||||
fun rmrf(f: File) {
|
||||
if (f.isDirectory) f.listFiles()?.let {
|
||||
for (i in it)
|
||||
if (i.isDirectory) rmrf(i)
|
||||
@@ -63,6 +84,81 @@ class DlListActivity:Activity() {
|
||||
f.delete()
|
||||
}
|
||||
|
||||
fun checkDir(f: File){
|
||||
nullZipDirStr = emptyArray()
|
||||
findNullWebpZipFileInDir(f)
|
||||
if(nullZipDirStr.isNotEmpty()) showErrorZip(nullZipDirStr.joinToString("\n"))
|
||||
else Toast.makeText(this, "未发现错误", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
fun showLoading() = loadingDialog?.show()
|
||||
|
||||
fun hideLoading() = loadingDialog?.hide()
|
||||
|
||||
private fun findNullWebpZipFileInDir(f: File){
|
||||
if (f.isDirectory) f.listFiles()?.let {
|
||||
for (i in it)
|
||||
if (i.isDirectory) findNullWebpZipFileInDir(i)
|
||||
else if(!checkZip(i)) nullZipDirStr += i.path.substringAfterLast(getExternalFilesDir("").toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkZip(f: File): Boolean{
|
||||
return try {
|
||||
val exist = f.exists()
|
||||
if (!exist) true
|
||||
else {
|
||||
var re = true
|
||||
val zip = ZipInputStream(f.inputStream().buffered())
|
||||
var entry = zip.nextEntry
|
||||
while (entry != null) {
|
||||
if (!entry.isDirectory){
|
||||
if(zip.read() == -1 && entry.size == 0L){
|
||||
re = false
|
||||
break
|
||||
}
|
||||
}
|
||||
entry = zip.nextEntry
|
||||
}
|
||||
zip.closeEntry()
|
||||
zip.close()
|
||||
re
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(this, "读取${f.name}错误!", Toast.LENGTH_SHORT).show()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private fun showErrorZip(msg: CharSequence) = AlertDialog.Builder(this)
|
||||
.setIcon(R.drawable.ic_launcher_foreground)
|
||||
.setTitle("找到以下错误文件,是否删除?")
|
||||
.setMessage(msg)
|
||||
.setPositiveButton(android.R.string.ok){_, _ -> deleteErrorZip()}
|
||||
.setNegativeButton(android.R.string.cancel){_, _ ->}
|
||||
.show()
|
||||
|
||||
private fun deleteErrorZip(){
|
||||
val exf = getExternalFilesDir("")
|
||||
for(i in nullZipDirStr){
|
||||
val f = File(exf, i)
|
||||
if(f.exists()) f.delete()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFloat(oldString: String): Float {
|
||||
val newString = StringBuffer()
|
||||
var matcher = Pattern.compile("\\d+.+\\d+").matcher(oldString)
|
||||
while (matcher.find()) newString.append(matcher.group())
|
||||
//Log.d("MyDLL1", newString.toString())
|
||||
if(newString.isEmpty()){
|
||||
matcher = Pattern.compile("\\d").matcher(oldString)
|
||||
while (matcher.find()) newString.append(matcher.group())
|
||||
}
|
||||
//Log.d("MyDLL2", newString.toString().toFloat().toString())
|
||||
return newString.toString().toFloat()
|
||||
}
|
||||
|
||||
companion object{
|
||||
var currentDir: File? = null
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class ViewMangaActivity : Activity() {
|
||||
lateinit var toolsBox: ToolsBox
|
||||
private lateinit var p: PropertiesTools
|
||||
private var mangaZip = zipFile
|
||||
private val dlZip2View = mangaZip != null
|
||||
val dlZip2View = mangaZip != null
|
||||
var pageNum = 1
|
||||
get() {
|
||||
field = getPageNumber()
|
||||
@@ -424,5 +424,8 @@ class ViewMangaActivity : Activity() {
|
||||
var titleText = "Null"
|
||||
var nextChapterUrl: String? = null
|
||||
var previousChapterUrl: String? = null
|
||||
var zipPosition = 0
|
||||
var zipList: Array<out String>? = null
|
||||
var cd: File? = null
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package top.fumiama.copymanga.handler
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.widget.Toast
|
||||
import android.widget.ToggleButton
|
||||
@@ -11,9 +12,10 @@ import top.fumiama.copymanga.activity.DlActivity
|
||||
import top.fumiama.copymanga.tool.MangaDlTools.Companion.wmdlt
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class DlHandler(activity: DlActivity) : Handler() {
|
||||
class DlHandler(activity: DlActivity, looper: Looper) : Handler(looper) {
|
||||
private val da = WeakReference(activity)
|
||||
private val d = da.get()
|
||||
private val d
|
||||
get() = da.get()
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
@SuppressLint("SetTextI18n")
|
||||
@@ -26,31 +28,31 @@ class DlHandler(activity: DlActivity) : Handler() {
|
||||
d?.tbtnlist?.get(msg.arg1)?.isChecked = false
|
||||
d?.updateProgressBar()
|
||||
if (d?.haveDlStarted == false) {
|
||||
d.dldChapter = 0
|
||||
d.checkedChapter = 0
|
||||
d?.dldChapter = 0
|
||||
d?.checkedChapter = 0
|
||||
this.postDelayed({
|
||||
d.setProgress2(0, 233)
|
||||
d.tdwn?.text = "0/0"
|
||||
d?.setProgress2(0, 233)
|
||||
d?.tdwn?.text = "0/0"
|
||||
}, 400)
|
||||
}
|
||||
}
|
||||
-1 -> {
|
||||
d?.tbtnlist?.get(msg.arg1)?.setBackgroundResource(R.drawable.rndbg_error)
|
||||
d!!.dldChapter--
|
||||
Toast.makeText(d, "下载${d.tbtnlist[msg.arg1].textOn}失败", Toast.LENGTH_SHORT).show()
|
||||
d.updateProgressBar()
|
||||
Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}失败", Toast.LENGTH_SHORT).show()
|
||||
d?.updateProgressBar()
|
||||
}
|
||||
4 -> {
|
||||
d?.pdwn?.progress = 0
|
||||
val selectDownloaded = d?.multiSelect?:false
|
||||
if (d?.haveSElectAll == true) {
|
||||
for (i in d.tbtnlist.listIterator()) {
|
||||
d?.tbtnlist?.listIterator()?.forEach { i ->
|
||||
if(i.freezesText) i.setBackgroundResource(R.drawable.rndbg_checked) else i.setBackgroundResource(R.drawable.toggle_button)
|
||||
i.isChecked = false
|
||||
}
|
||||
d.haveSElectAll = false
|
||||
d.checkedChapter = 0
|
||||
d.dldChapter = 0
|
||||
d?.haveSElectAll = false
|
||||
d?.checkedChapter = 0
|
||||
d?.dldChapter = 0
|
||||
} else {
|
||||
d?.let {
|
||||
val checkBtn = { i: ToggleButton, it: DlActivity ->
|
||||
@@ -79,8 +81,8 @@ class DlHandler(activity: DlActivity) : Handler() {
|
||||
}
|
||||
6 -> d?.tdwn?.text = "${d?.dldChapter}/${d?.checkedChapter}"
|
||||
7 -> d?.deleteChapters()
|
||||
8 -> d?.cdwn?.setCardBackgroundColor(d.resources.getColor(R.color.colorBlue))
|
||||
9 -> d?.cdwn?.setCardBackgroundColor(d.resources.getColor(R.color.colorRed))
|
||||
8 -> d?.resources?.getColor(R.color.colorBlue)?.let { d?.cdwn?.setCardBackgroundColor(it) }
|
||||
9 -> d?.resources?.getColor(R.color.colorRed)?.let { d?.cdwn?.setCardBackgroundColor(it) }
|
||||
10 -> Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败,尝试重新下载...", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package top.fumiama.copymanga.handler
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import top.fumiama.copymanga.activity.DlListActivity
|
||||
import java.io.File
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
|
||||
class DlLHandler(looper: Looper, activity: DlListActivity): Handler(looper) {
|
||||
private val dll = WeakReference(activity)
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
when(msg.what){
|
||||
1 -> load { dll.get()?.checkDir(msg.obj as File) }
|
||||
2 -> load { dll.get()?.rmrf(msg.obj as File) }
|
||||
3 -> load { dll.get()?.scanFile(msg.obj as File) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun load(func:()->Unit){
|
||||
dll.get()?.showLoading()
|
||||
func()
|
||||
dll.get()?.hideLoading()
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package top.fumiama.copymanga.tool
|
||||
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import top.fumiama.copymanga.activity.MainActivity.Companion.wm
|
||||
import top.fumiama.copymanga.activity.ViewMangaActivity
|
||||
import java.io.File
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class PagesManager(w: WeakReference<ViewMangaActivity>) {
|
||||
@@ -11,18 +13,15 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
|
||||
private var isEndL = false
|
||||
private var isEndR = false
|
||||
@ExperimentalStdlibApi
|
||||
fun toPreviousPage(){
|
||||
toPage(v?.r2l==true)
|
||||
}
|
||||
fun toPreviousPage(){ toPage(v?.r2l==true) }
|
||||
@ExperimentalStdlibApi
|
||||
fun toNextPage(){
|
||||
toPage(v?.r2l!=true)
|
||||
}
|
||||
fun toNextPage(){ toPage(v?.r2l!=true) }
|
||||
private fun judgePrevious() = v?.pageNum?:0 > 1
|
||||
private fun judgeNext() = v?.pageNum?:0 < v?.count?:0
|
||||
@ExperimentalStdlibApi
|
||||
private fun toPage(goNext:Boolean){
|
||||
val chapterUrl = if(goNext) ViewMangaActivity.nextChapterUrl else ViewMangaActivity.previousChapterUrl
|
||||
val newZipPosition = ViewMangaActivity.zipPosition + (if(goNext) 1 else -1)
|
||||
val hint = if(goNext) "下" else "上"
|
||||
if (v?.clicked == false) {
|
||||
if (if(goNext)judgeNext() else judgePrevious()) {
|
||||
@@ -38,16 +37,18 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
|
||||
wm?.get()?.w?.loadUrl("javascript:invoke.clickClass(\"comicControlBottomTopClick\",${if(goNext)1 else 0});")
|
||||
v.tt.canDo = false
|
||||
v.finish()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
v.applicationContext,
|
||||
"再次按下加载${hint}一章",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
if(goNext) isEndR = true
|
||||
else isEndL = true
|
||||
}
|
||||
} else Toast.makeText(
|
||||
} else doubleTapToast(hint, goNext)
|
||||
} else if(v.dlZip2View && newZipPosition >= 0 && newZipPosition < ViewMangaActivity.zipList?.size?:0){
|
||||
if (if(goNext)isEndR else isEndL){
|
||||
ViewMangaActivity.zipPosition = newZipPosition
|
||||
ViewMangaActivity.titleText = ViewMangaActivity.zipList?.get(newZipPosition) ?: "null"
|
||||
ViewMangaActivity.zipFile = ViewMangaActivity.zipList?.let { File(ViewMangaActivity.cd, ViewMangaActivity.titleText) }
|
||||
v.startActivity(Intent(v, ViewMangaActivity::class.java))
|
||||
v.tt.canDo = false
|
||||
v.finish()
|
||||
}else doubleTapToast(hint, goNext)
|
||||
}
|
||||
else Toast.makeText(
|
||||
v.applicationContext,
|
||||
"已经到头了~",
|
||||
Toast.LENGTH_SHORT
|
||||
@@ -57,4 +58,13 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
|
||||
fun manageInfo(){
|
||||
if (v?.clicked == false) v.showObjs() else v?.hideObjs()
|
||||
}
|
||||
private fun doubleTapToast(hint: String, goNext: Boolean){
|
||||
Toast.makeText(
|
||||
v?.applicationContext,
|
||||
"再次按下加载${hint}一章",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
if(goNext) isEndR = true
|
||||
else isEndL = true
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,12 @@ import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import top.fumiama.copymanga.R
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class ToolsBox(w: WeakReference<Any>) {
|
||||
|
||||
28
app/src/main/res/layout/dialog_loading.xml
Normal file
28
app/src/main/res/layout/dialog_loading.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/punz"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tunz"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tunz"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="准备中..."
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/punz" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Reference in New Issue
Block a user