mirror of
https://github.com/gedoor/legado.git
synced 2024-07-06 23:47:49 +08:00
支持PDF格式
This commit is contained in:
parent
17a828cf40
commit
342a08400f
@ -16,7 +16,8 @@ def version = "3." + releaseTime()
|
|||||||
def gitCommits = Integer.parseInt('git rev-list HEAD --count'.execute().text.trim())
|
def gitCommits = Integer.parseInt('git rev-list HEAD --count'.execute().text.trim())
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdk 33
|
compileSdk = compile_sdk_version
|
||||||
|
buildToolsVersion = build_tool_version
|
||||||
namespace 'io.legado.app'
|
namespace 'io.legado.app'
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "11"
|
jvmTarget = "11"
|
||||||
|
@ -23,7 +23,7 @@ object AppPattern {
|
|||||||
val debugMessageSymbolRegex = Regex("[⇒◇┌└≡]")
|
val debugMessageSymbolRegex = Regex("[⇒◇┌└≡]")
|
||||||
|
|
||||||
//本地书籍支持类型
|
//本地书籍支持类型
|
||||||
val bookFileRegex = Regex(".*\\.(txt|epub|umd)", RegexOption.IGNORE_CASE)
|
val bookFileRegex = Regex(".*\\.(txt|epub|umd|pdf)", RegexOption.IGNORE_CASE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 所有标点
|
* 所有标点
|
||||||
|
@ -49,6 +49,10 @@ val Book.isUmd: Boolean
|
|||||||
get() {
|
get() {
|
||||||
return isLocal && originName.endsWith(".umd", true)
|
return isLocal && originName.endsWith(".umd", true)
|
||||||
}
|
}
|
||||||
|
val Book.isPdf: Boolean
|
||||||
|
get() {
|
||||||
|
return isLocal && originName.endsWith(".pdf", true)
|
||||||
|
}
|
||||||
|
|
||||||
val Book.isOnLineTxt: Boolean
|
val Book.isOnLineTxt: Boolean
|
||||||
get() {
|
get() {
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package io.legado.app.help.http.cronet
|
||||||
|
|
||||||
|
import okhttp3.RequestBody
|
||||||
|
import okio.Buffer
|
||||||
|
import org.chromium.net.UploadDataProvider
|
||||||
|
import org.chromium.net.UploadDataSink
|
||||||
|
import java.io.IOException
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
|
class BodyUploadProvider(body: RequestBody) : UploadDataProvider(), AutoCloseable {
|
||||||
|
private val body: RequestBody
|
||||||
|
private val buffer: Buffer?
|
||||||
|
|
||||||
|
init {
|
||||||
|
buffer = Buffer()
|
||||||
|
this.body = body
|
||||||
|
try {
|
||||||
|
body.writeTo(buffer)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun getLength(): Long {
|
||||||
|
return body.contentLength()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun read(uploadDataSink: UploadDataSink, byteBuffer: ByteBuffer) {
|
||||||
|
check(byteBuffer.hasRemaining()) { "Cronet passed a buffer with no bytes remaining" }
|
||||||
|
var read: Int
|
||||||
|
var bytesRead = 0
|
||||||
|
while (bytesRead == 0) {
|
||||||
|
read = buffer!!.read(byteBuffer)
|
||||||
|
bytesRead += read
|
||||||
|
}
|
||||||
|
uploadDataSink.onReadSucceeded(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun rewind(uploadDataSink: UploadDataSink) {
|
||||||
|
uploadDataSink.onRewindSucceeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun close() {
|
||||||
|
buffer?.close()
|
||||||
|
super.close()
|
||||||
|
}
|
||||||
|
}
|
@ -7,10 +7,8 @@ import io.legado.app.utils.DebugLog
|
|||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.MediaType
|
import okhttp3.MediaType
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okio.Buffer
|
|
||||||
import org.chromium.net.CronetEngine.Builder.HTTP_CACHE_DISK
|
import org.chromium.net.CronetEngine.Builder.HTTP_CACHE_DISK
|
||||||
import org.chromium.net.ExperimentalCronetEngine
|
import org.chromium.net.ExperimentalCronetEngine
|
||||||
import org.chromium.net.UploadDataProviders
|
|
||||||
import org.chromium.net.UrlRequest
|
import org.chromium.net.UrlRequest
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
@ -85,10 +83,8 @@ fun buildRequest(request: Request, callback: UrlRequest.Callback): UrlRequest? {
|
|||||||
} else {
|
} else {
|
||||||
addHeader("Content-Type", "text/plain")
|
addHeader("Content-Type", "text/plain")
|
||||||
}
|
}
|
||||||
val buffer = Buffer()
|
|
||||||
requestBody.writeTo(buffer)
|
|
||||||
setUploadDataProvider(
|
setUploadDataProvider(
|
||||||
UploadDataProviders.create(buffer.readByteArray()),
|
BodyUploadProvider(requestBody),
|
||||||
okHttpClient.dispatcher.executorService
|
okHttpClient.dispatcher.executorService
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -76,6 +76,9 @@ object LocalBook {
|
|||||||
book.isUmd -> {
|
book.isUmd -> {
|
||||||
UmdFile.getChapterList(book)
|
UmdFile.getChapterList(book)
|
||||||
}
|
}
|
||||||
|
book.isPdf -> {
|
||||||
|
PdfFile.getChapterList(book)
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
TextFile.getChapterList(book)
|
TextFile.getChapterList(book)
|
||||||
}
|
}
|
||||||
@ -100,6 +103,9 @@ object LocalBook {
|
|||||||
book.isUmd -> {
|
book.isUmd -> {
|
||||||
UmdFile.getContent(book, chapter)
|
UmdFile.getContent(book, chapter)
|
||||||
}
|
}
|
||||||
|
book.isPdf -> {
|
||||||
|
PdfFile.getContent(book, chapter)
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
TextFile.getContent(book, chapter)
|
TextFile.getContent(book, chapter)
|
||||||
}
|
}
|
||||||
@ -166,6 +172,7 @@ object LocalBook {
|
|||||||
)
|
)
|
||||||
if (book.isEpub) EpubFile.upBookInfo(book)
|
if (book.isEpub) EpubFile.upBookInfo(book)
|
||||||
if (book.isUmd) UmdFile.upBookInfo(book)
|
if (book.isUmd) UmdFile.upBookInfo(book)
|
||||||
|
if (book.isPdf) PdfFile.upBookInfo(book)
|
||||||
appDb.bookDao.insert(book)
|
appDb.bookDao.insert(book)
|
||||||
} else {
|
} else {
|
||||||
//已有书籍说明是更新,删除原有目录
|
//已有书籍说明是更新,删除原有目录
|
||||||
|
225
app/src/main/java/io/legado/app/model/localBook/PdfFile.kt
Normal file
225
app/src/main/java/io/legado/app/model/localBook/PdfFile.kt
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
package io.legado.app.model.localBook
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.pdf.PdfRenderer
|
||||||
|
import android.os.ParcelFileDescriptor
|
||||||
|
import io.legado.app.constant.AppLog
|
||||||
|
import io.legado.app.data.entities.Book
|
||||||
|
import io.legado.app.data.entities.BookChapter
|
||||||
|
import io.legado.app.help.book.getLocalUri
|
||||||
|
import io.legado.app.utils.*
|
||||||
|
import splitties.init.appCtx
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.InputStream
|
||||||
|
import kotlin.math.ceil
|
||||||
|
|
||||||
|
|
||||||
|
class PdfFile(var book: Book) {
|
||||||
|
companion object : BaseLocalBookParse {
|
||||||
|
private var pFile: PdfFile? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdf分页尺寸
|
||||||
|
*/
|
||||||
|
const val PAGE_SIZE = 10
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private fun getPFile(book: Book): PdfFile {
|
||||||
|
if (pFile == null || pFile?.book?.bookUrl != book.bookUrl) {
|
||||||
|
pFile = PdfFile(book)
|
||||||
|
return pFile!!
|
||||||
|
}
|
||||||
|
pFile?.book = book
|
||||||
|
return pFile!!
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun upBookInfo(book: Book) {
|
||||||
|
getPFile(book).upBookInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun getChapterList(book: Book): ArrayList<BookChapter> {
|
||||||
|
return getPFile(book).getChapterList()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun getContent(book: Book, chapter: BookChapter): String? {
|
||||||
|
return getPFile(book).getContent(chapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun getImage(book: Book, href: String): InputStream? {
|
||||||
|
return getPFile(book).getImage(href)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private var fileDescriptor: ParcelFileDescriptor? = null
|
||||||
|
private var pdfRenderer: PdfRenderer? = null
|
||||||
|
get() {
|
||||||
|
if (field != null) {
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
field = readPdf()
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
try {
|
||||||
|
pdfRenderer?.let { renderer ->
|
||||||
|
if (book.coverUrl.isNullOrEmpty()) {
|
||||||
|
book.coverUrl = FileUtils.getPath(
|
||||||
|
appCtx.externalFiles,
|
||||||
|
"covers",
|
||||||
|
"${MD5Utils.md5Encode16(book.bookUrl)}.jpg"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (!File(book.coverUrl!!).exists()) {
|
||||||
|
|
||||||
|
FileOutputStream(FileUtils.createFileIfNotExist(book.coverUrl!!)).use { out ->
|
||||||
|
openPdfPage(renderer, 0)?.let { cover ->
|
||||||
|
cover.compress(Bitmap.CompressFormat.JPEG, 90, out)
|
||||||
|
}
|
||||||
|
out.flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
AppLog.put("加载书籍封面失败\n${e.localizedMessage}", e)
|
||||||
|
e.printOnDebug()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取PDF文件
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private fun readPdf(): PdfRenderer? {
|
||||||
|
val uri = book.getLocalUri()
|
||||||
|
if (uri.isContentScheme()) {
|
||||||
|
fileDescriptor = appCtx.contentResolver.openFileDescriptor(uri, "r")?.also {
|
||||||
|
pdfRenderer = PdfRenderer(it)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fileDescriptor =
|
||||||
|
ParcelFileDescriptor.open(File(uri.path), ParcelFileDescriptor.MODE_READ_ONLY)
|
||||||
|
?.also {
|
||||||
|
pdfRenderer = PdfRenderer(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pdfRenderer
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭pdf文件
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private fun closePdf() {
|
||||||
|
pdfRenderer?.close()
|
||||||
|
fileDescriptor?.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染PDF页面
|
||||||
|
* 根据index打开pdf页面,并渲染到Bitmap
|
||||||
|
*
|
||||||
|
* @param renderer
|
||||||
|
* @param index
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private fun openPdfPage(renderer: PdfRenderer, index: Int): Bitmap? {
|
||||||
|
if (index >= renderer.pageCount) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return renderer.openPage(index)?.use { page ->
|
||||||
|
Bitmap.createBitmap(
|
||||||
|
SystemUtils.screenWidthPx,
|
||||||
|
(SystemUtils.screenWidthPx.toDouble() * page.height / page.width).toInt(),
|
||||||
|
Bitmap.Config.ARGB_8888
|
||||||
|
)
|
||||||
|
.apply {
|
||||||
|
page.render(this, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getContent(chapter: BookChapter): String? =
|
||||||
|
if (pdfRenderer == null) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
pdfRenderer?.let { renderer ->
|
||||||
|
|
||||||
|
buildString {
|
||||||
|
val start = chapter.index * PAGE_SIZE
|
||||||
|
val end = Math.min((chapter.index + 1) * PAGE_SIZE, renderer.pageCount)
|
||||||
|
(start until end).forEach {
|
||||||
|
append("<img src=").append('"').append(it).append('"').append(" >")
|
||||||
|
.append('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getImage(href: String): InputStream? {
|
||||||
|
if (pdfRenderer == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return try {
|
||||||
|
val index = href.toInt()
|
||||||
|
val bitmap = openPdfPage(pdfRenderer!!, index)
|
||||||
|
if (bitmap != null) {
|
||||||
|
BitmapUtils.toInputStream(bitmap).also { bitmap.recycle() }
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getChapterList(): ArrayList<BookChapter> {
|
||||||
|
val chapterList = ArrayList<BookChapter>()
|
||||||
|
|
||||||
|
pdfRenderer?.let { renderer ->
|
||||||
|
if (renderer.pageCount > 0) {
|
||||||
|
val chapterCount = ceil((renderer.pageCount.toDouble() / PAGE_SIZE)).toInt()
|
||||||
|
(0 until chapterCount).forEach {
|
||||||
|
val chapter = BookChapter()
|
||||||
|
chapter.index = it
|
||||||
|
chapter.bookUrl = book.bookUrl
|
||||||
|
chapter.title = "分段_${it}"
|
||||||
|
chapter.url = "pdf_${it}"
|
||||||
|
chapterList.add(chapter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chapterList
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun upBookInfo() {
|
||||||
|
if (pdfRenderer == null) {
|
||||||
|
pFile = null
|
||||||
|
book.intro = "书籍导入异常"
|
||||||
|
} else {
|
||||||
|
if (book.name.isEmpty()) {
|
||||||
|
book.name = book.originName.replace(".pdf", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun finalize() {
|
||||||
|
closePdf()
|
||||||
|
}
|
||||||
|
}
|
@ -4,4 +4,5 @@
|
|||||||
* LocalBook.kt 导入解析总入口
|
* LocalBook.kt 导入解析总入口
|
||||||
* TextFile.kt 解析txt
|
* TextFile.kt 解析txt
|
||||||
* EpubFile.kt 解析epub
|
* EpubFile.kt 解析epub
|
||||||
|
* PdfFile.kt 解析pdf 纯图片形式
|
||||||
* UmdFile.kt 解析umd
|
* UmdFile.kt 解析umd
|
@ -140,7 +140,10 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application)
|
|||||||
if (docItem.isDir) {
|
if (docItem.isDir) {
|
||||||
scanDoc(docItem, false, scope)
|
scanDoc(docItem, false, scope)
|
||||||
} else if (docItem.name.endsWith(".txt", true)
|
} else if (docItem.name.endsWith(".txt", true)
|
||||||
|| docItem.name.endsWith(".epub", true)
|
|| docItem.name.endsWith(".epub", true) || docItem.name.endsWith(
|
||||||
|
".pdf",
|
||||||
|
true
|
||||||
|
) || docItem.name.endsWith(".umd", true)
|
||||||
) {
|
) {
|
||||||
list.add(docItem)
|
list.add(docItem)
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,15 @@ import io.legado.app.data.entities.BookSource
|
|||||||
import io.legado.app.exception.NoStackTraceException
|
import io.legado.app.exception.NoStackTraceException
|
||||||
import io.legado.app.help.book.BookHelp
|
import io.legado.app.help.book.BookHelp
|
||||||
import io.legado.app.help.book.isEpub
|
import io.legado.app.help.book.isEpub
|
||||||
|
import io.legado.app.help.book.isPdf
|
||||||
import io.legado.app.help.config.AppConfig
|
import io.legado.app.help.config.AppConfig
|
||||||
import io.legado.app.help.coroutine.Coroutine
|
import io.legado.app.help.coroutine.Coroutine
|
||||||
import io.legado.app.model.ReadBook
|
import io.legado.app.model.ReadBook
|
||||||
import io.legado.app.model.localBook.EpubFile
|
import io.legado.app.model.localBook.EpubFile
|
||||||
|
import io.legado.app.model.localBook.PdfFile
|
||||||
import io.legado.app.utils.BitmapUtils
|
import io.legado.app.utils.BitmapUtils
|
||||||
import io.legado.app.utils.SvgUtils
|
|
||||||
import io.legado.app.utils.FileUtils
|
import io.legado.app.utils.FileUtils
|
||||||
|
import io.legado.app.utils.SvgUtils
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
@ -81,6 +83,14 @@ object ImageProvider {
|
|||||||
input.copyTo(output)
|
input.copyTo(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (book.isPdf) {
|
||||||
|
PdfFile.getImage(book, src)?.use { input ->
|
||||||
|
val newFile = FileUtils.createFileIfNotExist(vFile.absolutePath)
|
||||||
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
|
FileOutputStream(newFile).use { output ->
|
||||||
|
input.copyTo(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
BookHelp.saveImage(bookSource, book, src)
|
BookHelp.saveImage(bookSource, book, src)
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,7 @@ import android.graphics.Bitmap.Config
|
|||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import com.google.android.renderscript.Toolkit
|
import com.google.android.renderscript.Toolkit
|
||||||
import java.io.FileInputStream
|
import java.io.*
|
||||||
import java.io.IOException
|
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
|
|
||||||
@ -207,6 +206,18 @@ object BitmapUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将Bitmap转换成InputStream
|
||||||
|
*
|
||||||
|
* @param bitmap
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
fun toInputStream(bitmap: Bitmap): InputStream {
|
||||||
|
val bos = ByteArrayOutputStream()
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos)
|
||||||
|
return ByteArrayInputStream(bos.toByteArray()).also { bos.close() }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,4 +266,5 @@ fun Bitmap.getMeanColor(): Int {
|
|||||||
averagePixelGreen + 3,
|
averagePixelGreen + 3,
|
||||||
averagePixelBlue + 3
|
averagePixelBlue + 3
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ object ConvertUtils {
|
|||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val Int.hexString: String
|
val Int.hexString: String
|
||||||
|
@ -6,6 +6,7 @@ import android.content.Intent
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.view.Display
|
import android.view.Display
|
||||||
|
import splitties.init.appCtx
|
||||||
import splitties.systemservices.displayManager
|
import splitties.systemservices.displayManager
|
||||||
import splitties.systemservices.powerManager
|
import splitties.systemservices.powerManager
|
||||||
|
|
||||||
@ -35,4 +36,18 @@ object SystemUtils {
|
|||||||
it.state != Display.STATE_OFF
|
it.state != Display.STATE_OFF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 屏幕像素宽度
|
||||||
|
*/
|
||||||
|
val screenWidthPx by lazy {
|
||||||
|
appCtx.resources.displayMetrics.widthPixels
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 屏幕像素高度
|
||||||
|
*/
|
||||||
|
val screenHeightPx by lazy {
|
||||||
|
appCtx.resources.displayMetrics.heightPixels
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ buildscript {
|
|||||||
exoplayer_version = '2.18.2'
|
exoplayer_version = '2.18.2'
|
||||||
splitties_version = '3.0.0'
|
splitties_version = '3.0.0'
|
||||||
room_version = '2.4.3'
|
room_version = '2.4.3'
|
||||||
|
compile_sdk_version = 33
|
||||||
|
build_tool_version = '33.0.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdk 33
|
compileSdk = compile_sdk_version
|
||||||
|
buildToolsVersion = build_tool_version
|
||||||
namespace 'me.ag2s.epublib'
|
namespace 'me.ag2s.epublib'
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk 21
|
minSdk 21
|
||||||
@ -21,8 +22,8 @@ android {
|
|||||||
|
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
lint {
|
lint {
|
||||||
checkDependencies true
|
checkDependencies true
|
||||||
|
Loading…
Reference in New Issue
Block a user