1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-29 07:10:27 +08:00
1. 增加长按检查zip错误功能
2. 增加阅读zip跳转到下一话功能
3. 文件按话数升序排列
This commit is contained in:
fumiama
2020-12-20 13:47:17 +08:00
parent 4d54a7bcaf
commit 91b997973f
9 changed files with 216 additions and 49 deletions

View File

@@ -11,8 +11,8 @@ android {
applicationId "top.fumiama.copymanga" applicationId "top.fumiama.copymanga"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 30 targetSdkVersion 30
versionCode 7 versionCode 8
versionName '1.2.1' versionName '1.3'
resConfigs "zh", "zh-rCN" resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -4,6 +4,7 @@ import android.animation.ObjectAnimator
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.os.Bundle import android.os.Bundle
import android.os.Looper
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
@@ -40,7 +41,7 @@ class DlActivity : Activity() {
private lateinit var ltbtn: View private lateinit var ltbtn: View
var tbtnlist: List<ToggleButton> = arrayListOf() var tbtnlist: List<ToggleButton> = arrayListOf()
var tbtnUrlList = arrayListOf<String>() var tbtnUrlList = arrayListOf<String>()
private val handler = DlHandler(this) private val handler = DlHandler(this, Looper.myLooper()!!)
private var btnw = 0 private var btnw = 0
private var cdwnWidth = 0 private var cdwnWidth = 0
private var canDl = false private var canDl = false
@@ -87,7 +88,7 @@ class DlActivity : Activity() {
} }
private fun dlThead(dlMethod: (i: ToggleButton) -> Unit) { private fun dlThead(dlMethod: (i: ToggleButton) -> Unit) {
sleep(2333) sleep(100000)
for (i in tbtnlist.listIterator()) { for (i in tbtnlist.listIterator()) {
if (i.isChecked) dlMethod(i) if (i.isChecked) dlMethod(i)
if (!canDl) { if (!canDl) {
@@ -133,14 +134,14 @@ class DlActivity : Activity() {
haveDlStarted = true haveDlStarted = true
canDl = true canDl = true
handler.sendEmptyMessage(9) //set dl card color to red handler.sendEmptyMessage(9) //set dl card color to red
Toast.makeText(this, "准备下载...", Toast.LENGTH_SHORT).show() Toast.makeText(this, "十秒后开始下载...", Toast.LENGTH_SHORT).show()
fillChapters() fillChapters()
Thread { dlThead { downloadChapterPages(it) } }.start() Thread { dlThead { downloadChapterPages(it) } }.start()
} }
} }
} }
cdwn.setOnLongClickListener { cdwn.setOnLongClickListener {
Thread { handler.sendEmptyMessage(4) }.start() handler.sendEmptyMessage(4)
return@setOnLongClickListener true return@setOnLongClickListener true
} }
isearch.setOnClickListener { showMultiSelectInfo() } isearch.setOnClickListener { showMultiSelectInfo() }
@@ -250,9 +251,7 @@ class DlActivity : Activity() {
it.tbtn.isChecked = true it.tbtn.isChecked = true
tdwn.text = "$dldChapter/${++checkedChapter}" tdwn.text = "$dldChapter/${++checkedChapter}"
} }
Thread { handler.sendEmptyMessage(7)
handler.sendEmptyMessage(7)
}.start()
}) })
} }
true true

View File

@@ -2,25 +2,41 @@ package top.fumiama.copymanga.activity
import android.app.Activity import android.app.Activity
import android.app.AlertDialog import android.app.AlertDialog
import android.app.Dialog
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.os.Looper
import android.util.Log
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_dlist.* import kotlinx.android.synthetic.main.activity_dlist.*
import kotlinx.android.synthetic.main.widget_titlebar.* import kotlinx.android.synthetic.main.widget_titlebar.*
import top.fumiama.copymanga.R import top.fumiama.copymanga.R
import top.fumiama.copymanga.handler.DlLHandler
import java.io.File import java.io.File
import java.util.regex.Pattern
import java.util.zip.ZipInputStream
class DlListActivity:Activity() { class DlListActivity:Activity() {
var nullZipDirStr = emptyArray<String>()
var handler: DlLHandler? = null
var loadingDialog: Dialog? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dlist) setContentView(R.layout.activity_dlist)
ttitle.text = intent.getStringExtra("title") 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?){ fun scanFile(cd: File?){
cd?.list()?.sortedArray()?.let { 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.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, it)
mylv.setOnItemClickListener { _, _, position, _ -> mylv.setOnItemClickListener { _, _, position, _ ->
val chosenFile = File(cd, it[position]) val chosenFile = File(cd, it[position])
@@ -38,23 +54,28 @@ class DlListActivity:Activity() {
Toast.makeText(this, "加载中...", Toast.LENGTH_SHORT).show() Toast.makeText(this, "加载中...", Toast.LENGTH_SHORT).show()
ViewMangaActivity.zipFile = chosenFile ViewMangaActivity.zipFile = chosenFile
ViewMangaActivity.titleText = it[position] ViewMangaActivity.titleText = it[position]
ViewMangaActivity.zipPosition = position
ViewMangaActivity.zipList = it
ViewMangaActivity.cd = cd
startActivity(Intent(this, ViewMangaActivity::class.java)) startActivity(Intent(this, ViewMangaActivity::class.java))
} }
} }
mylv.setOnItemLongClickListener { _, _, position, _ -> mylv.setOnItemLongClickListener { _, _, position, _ ->
val chosenFile = File(cd, it[position]) val chosenFile = File(cd, it[position])
AlertDialog.Builder(this) AlertDialog.Builder(this)
.setIcon(R.drawable.ic_launcher_foreground).setMessage("是否删除?") .setIcon(R.drawable.ic_launcher_foreground).setMessage("是否在此执行删除/查错?")
.setTitle("提示").setPositiveButton("确定"){ _, _ -> .setTitle("提示").setPositiveButton(android.R.string.ok){ _, _ ->
if(chosenFile.exists()) rmrf(chosenFile) if(chosenFile.exists()) handler?.obtainMessage(2, chosenFile)?.sendToTarget() //call rmrf
scanFile(cd) handler?.obtainMessage(3, cd)?.sendToTarget() //call scanFile
}.setNegativeButton("取消"){_, _ ->}.show() }.setNegativeButton(android.R.string.cancel){_, _ ->}
.setNeutralButton("查错"){_, _ -> handler?.obtainMessage(1, chosenFile)?.sendToTarget()} //call checkDir
.show()
true true
} }
} }
} }
private fun rmrf(f: File) { fun rmrf(f: File) {
if (f.isDirectory) f.listFiles()?.let { if (f.isDirectory) f.listFiles()?.let {
for (i in it) for (i in it)
if (i.isDirectory) rmrf(i) if (i.isDirectory) rmrf(i)
@@ -63,6 +84,81 @@ class DlListActivity:Activity() {
f.delete() 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{ companion object{
var currentDir: File? = null var currentDir: File? = null
} }

View File

@@ -54,7 +54,7 @@ class ViewMangaActivity : Activity() {
lateinit var toolsBox: ToolsBox lateinit var toolsBox: ToolsBox
private lateinit var p: PropertiesTools private lateinit var p: PropertiesTools
private var mangaZip = zipFile private var mangaZip = zipFile
private val dlZip2View = mangaZip != null val dlZip2View = mangaZip != null
var pageNum = 1 var pageNum = 1
get() { get() {
field = getPageNumber() field = getPageNumber()
@@ -424,5 +424,8 @@ class ViewMangaActivity : Activity() {
var titleText = "Null" var titleText = "Null"
var nextChapterUrl: String? = null var nextChapterUrl: String? = null
var previousChapterUrl: String? = null var previousChapterUrl: String? = null
var zipPosition = 0
var zipList: Array<out String>? = null
var cd: File? = null
} }
} }

View File

@@ -2,6 +2,7 @@ package top.fumiama.copymanga.handler
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Handler import android.os.Handler
import android.os.Looper
import android.os.Message import android.os.Message
import android.widget.Toast import android.widget.Toast
import android.widget.ToggleButton import android.widget.ToggleButton
@@ -11,9 +12,10 @@ import top.fumiama.copymanga.activity.DlActivity
import top.fumiama.copymanga.tool.MangaDlTools.Companion.wmdlt import top.fumiama.copymanga.tool.MangaDlTools.Companion.wmdlt
import java.lang.ref.WeakReference 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 da = WeakReference(activity)
private val d = da.get() private val d
get() = da.get()
@ExperimentalStdlibApi @ExperimentalStdlibApi
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@@ -26,31 +28,31 @@ class DlHandler(activity: DlActivity) : Handler() {
d?.tbtnlist?.get(msg.arg1)?.isChecked = false d?.tbtnlist?.get(msg.arg1)?.isChecked = false
d?.updateProgressBar() d?.updateProgressBar()
if (d?.haveDlStarted == false) { if (d?.haveDlStarted == false) {
d.dldChapter = 0 d?.dldChapter = 0
d.checkedChapter = 0 d?.checkedChapter = 0
this.postDelayed({ this.postDelayed({
d.setProgress2(0, 233) d?.setProgress2(0, 233)
d.tdwn?.text = "0/0" d?.tdwn?.text = "0/0"
}, 400) }, 400)
} }
} }
-1 -> { -1 -> {
d?.tbtnlist?.get(msg.arg1)?.setBackgroundResource(R.drawable.rndbg_error) d?.tbtnlist?.get(msg.arg1)?.setBackgroundResource(R.drawable.rndbg_error)
d!!.dldChapter-- d!!.dldChapter--
Toast.makeText(d, "下载${d.tbtnlist[msg.arg1].textOn}失败", Toast.LENGTH_SHORT).show() Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}失败", Toast.LENGTH_SHORT).show()
d.updateProgressBar() d?.updateProgressBar()
} }
4 -> { 4 -> {
d?.pdwn?.progress = 0 d?.pdwn?.progress = 0
val selectDownloaded = d?.multiSelect?:false val selectDownloaded = d?.multiSelect?:false
if (d?.haveSElectAll == true) { 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) if(i.freezesText) i.setBackgroundResource(R.drawable.rndbg_checked) else i.setBackgroundResource(R.drawable.toggle_button)
i.isChecked = false i.isChecked = false
} }
d.haveSElectAll = false d?.haveSElectAll = false
d.checkedChapter = 0 d?.checkedChapter = 0
d.dldChapter = 0 d?.dldChapter = 0
} else { } else {
d?.let { d?.let {
val checkBtn = { i: ToggleButton, it: DlActivity -> val checkBtn = { i: ToggleButton, it: DlActivity ->
@@ -79,8 +81,8 @@ class DlHandler(activity: DlActivity) : Handler() {
} }
6 -> d?.tdwn?.text = "${d?.dldChapter}/${d?.checkedChapter}" 6 -> d?.tdwn?.text = "${d?.dldChapter}/${d?.checkedChapter}"
7 -> d?.deleteChapters() 7 -> d?.deleteChapters()
8 -> d?.cdwn?.setCardBackgroundColor(d.resources.getColor(R.color.colorBlue)) 8 -> d?.resources?.getColor(R.color.colorBlue)?.let { d?.cdwn?.setCardBackgroundColor(it) }
9 -> d?.cdwn?.setCardBackgroundColor(d.resources.getColor(R.color.colorRed)) 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() 10 -> Toast.makeText(d, "下载${d?.tbtnlist?.get(msg.arg1)?.textOn}的第${msg.arg2}页失败,尝试重新下载...", Toast.LENGTH_SHORT).show()
} }
} }

View File

@@ -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()
}
}

View File

@@ -1,9 +1,11 @@
package top.fumiama.copymanga.tool package top.fumiama.copymanga.tool
import android.content.Intent
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import top.fumiama.copymanga.activity.MainActivity.Companion.wm import top.fumiama.copymanga.activity.MainActivity.Companion.wm
import top.fumiama.copymanga.activity.ViewMangaActivity import top.fumiama.copymanga.activity.ViewMangaActivity
import java.io.File
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
class PagesManager(w: WeakReference<ViewMangaActivity>) { class PagesManager(w: WeakReference<ViewMangaActivity>) {
@@ -11,18 +13,15 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
private var isEndL = false private var isEndL = false
private var isEndR = false private var isEndR = false
@ExperimentalStdlibApi @ExperimentalStdlibApi
fun toPreviousPage(){ fun toPreviousPage(){ toPage(v?.r2l==true) }
toPage(v?.r2l==true)
}
@ExperimentalStdlibApi @ExperimentalStdlibApi
fun toNextPage(){ fun toNextPage(){ toPage(v?.r2l!=true) }
toPage(v?.r2l!=true)
}
private fun judgePrevious() = v?.pageNum?:0 > 1 private fun judgePrevious() = v?.pageNum?:0 > 1
private fun judgeNext() = v?.pageNum?:0 < v?.count?:0 private fun judgeNext() = v?.pageNum?:0 < v?.count?:0
@ExperimentalStdlibApi @ExperimentalStdlibApi
private fun toPage(goNext:Boolean){ private fun toPage(goNext:Boolean){
val chapterUrl = if(goNext) ViewMangaActivity.nextChapterUrl else ViewMangaActivity.previousChapterUrl val chapterUrl = if(goNext) ViewMangaActivity.nextChapterUrl else ViewMangaActivity.previousChapterUrl
val newZipPosition = ViewMangaActivity.zipPosition + (if(goNext) 1 else -1)
val hint = if(goNext) "" else "" val hint = if(goNext) "" else ""
if (v?.clicked == false) { if (v?.clicked == false) {
if (if(goNext)judgeNext() else judgePrevious()) { 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});") wm?.get()?.w?.loadUrl("javascript:invoke.clickClass(\"comicControlBottomTopClick\",${if(goNext)1 else 0});")
v.tt.canDo = false v.tt.canDo = false
v.finish() v.finish()
} else { } else doubleTapToast(hint, goNext)
Toast.makeText( } else if(v.dlZip2View && newZipPosition >= 0 && newZipPosition < ViewMangaActivity.zipList?.size?:0){
v.applicationContext, if (if(goNext)isEndR else isEndL){
"再次按下加载${hint}一章", ViewMangaActivity.zipPosition = newZipPosition
Toast.LENGTH_SHORT ViewMangaActivity.titleText = ViewMangaActivity.zipList?.get(newZipPosition) ?: "null"
).show() ViewMangaActivity.zipFile = ViewMangaActivity.zipList?.let { File(ViewMangaActivity.cd, ViewMangaActivity.titleText) }
if(goNext) isEndR = true v.startActivity(Intent(v, ViewMangaActivity::class.java))
else isEndL = true v.tt.canDo = false
} v.finish()
} else Toast.makeText( }else doubleTapToast(hint, goNext)
}
else Toast.makeText(
v.applicationContext, v.applicationContext,
"已经到头了~", "已经到头了~",
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
@@ -57,4 +58,13 @@ class PagesManager(w: WeakReference<ViewMangaActivity>) {
fun manageInfo(){ fun manageInfo(){
if (v?.clicked == false) v.showObjs() else v?.hideObjs() 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
}
} }

View File

@@ -5,10 +5,12 @@ import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.util.Log
import android.widget.Toast import android.widget.Toast
import top.fumiama.copymanga.R import top.fumiama.copymanga.R
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.* import java.util.*
import java.util.regex.Pattern
import kotlin.math.sqrt import kotlin.math.sqrt
class ToolsBox(w: WeakReference<Any>) { class ToolsBox(w: WeakReference<Any>) {

View 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>