feat: Enhance chapter list and TTS functionality
Build Android APK / build-apk (push) Failing after 4m37s

- Introduced ChapterListQuery and ChapterListPage classes for better chapter management.
- Updated chapterListProvider to handle pagination and canonical ID resolution.
- Improved ReaderScreen with enhanced TTS features, including auto-scroll to active paragraph and better handling of TTS state.
- Added TtsPlayerWidget with compact mode and improved UI for TTS controls.
- Enhanced TtsService to manage speech segments and background mode for TTS.
- Implemented battery optimization checks for TTS background mode on Android.
- Updated main.dart to ensure proper error handling in a zoned environment.
This commit is contained in:
2026-04-07 18:49:29 +07:00
parent 1afff18f4d
commit 6946083aee
27 changed files with 1590 additions and 157 deletions
+2
View File
@@ -1,5 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<application
android:label="reader_app"
android:name="${applicationName}"
@@ -1,5 +1,83 @@
package com.example.reader_app
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel
class MainActivity : FlutterActivity()
class MainActivity : FlutterActivity() {
private val channelName = "reader_app/tts_background"
private var wakeLock: PowerManager.WakeLock? = null
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channelName)
.setMethodCallHandler { call, result ->
when (call.method) {
"setWakeLock" -> {
val enabled = call.argument<Boolean>("enabled") ?: false
setWakeLockEnabled(enabled)
result.success(null)
}
"isIgnoringBatteryOptimizations" -> {
result.success(isIgnoringBatteryOptimizations())
}
"requestIgnoreBatteryOptimizations" -> {
requestIgnoreBatteryOptimizations()
result.success(null)
}
else -> result.notImplemented()
}
}
}
private fun isIgnoringBatteryOptimizations(): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return true
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
return powerManager.isIgnoringBatteryOptimizations(packageName)
}
private fun requestIgnoreBatteryOptimizations() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return
if (isIgnoringBatteryOptimizations()) return
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
data = Uri.parse("package:$packageName")
}
startActivity(intent)
}
private fun setWakeLockEnabled(enabled: Boolean) {
if (enabled) {
if (wakeLock?.isHeld == true) return
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"reader_app:TtsWakeLock"
).apply {
setReferenceCounted(false)
acquire()
}
return
}
wakeLock?.let {
if (it.isHeld) {
it.release()
}
}
wakeLock = null
}
override fun onDestroy() {
setWakeLockEnabled(false)
super.onDestroy()
}
}