diff --git a/app/build.gradle b/app/build.gradle
index b6c002771..6edad7fb7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,15 +8,14 @@ plugins {
}
android {
- compileSdk = 33
-// compileSdkExtension = 4
+ compileSdk = 34
buildToolsVersion = '34.0.0'
namespace = 'org.koitharu.kotatsu'
defaultConfig {
applicationId 'org.koitharu.kotatsu'
minSdkVersion 21
- targetSdkVersion 33
+ targetSdkVersion 34
versionCode 570
versionName '6.0-a1'
generatedDensities = []
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bc598d4b7..ead6c4c9c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,6 +18,7 @@
+
@@ -185,7 +186,13 @@
-
+
+
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Android.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Android.kt
index 42cfcaab0..271e3a1a5 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Android.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Android.kt
@@ -83,7 +83,7 @@ fun ActivityResultLauncher.tryLaunch(
e.printStackTraceDebug()
}.isSuccess
-fun SharedPreferences.observe() = callbackFlow {
+fun SharedPreferences.observe() = callbackFlow {
val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
trySendBlocking(key)
}
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt
index fa22c000c..ca024aeae 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt
@@ -98,11 +98,11 @@ class DownloadsActivity : BaseActivity(),
}
override fun onPauseClick(item: DownloadItemModel) {
- sendBroadcast(PausingReceiver.getPauseIntent(item.id))
+ sendBroadcast(PausingReceiver.getPauseIntent(this, item.id))
}
override fun onResumeClick(item: DownloadItemModel) {
- sendBroadcast(PausingReceiver.getResumeIntent(item.id))
+ sendBroadcast(PausingReceiver.getResumeIntent(this, item.id))
}
override fun onSelectionChanged(controller: ListSelectionController, count: Int) {
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt
index 7bba51708..131abe9a5 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt
@@ -2,6 +2,8 @@ package org.koitharu.kotatsu.download.ui.worker
import android.app.NotificationManager
import android.content.Context
+import android.content.pm.ServiceInfo
+import android.os.Build
import android.webkit.MimeTypeMap
import androidx.core.content.ContextCompat
import androidx.hilt.work.HiltWorker
@@ -130,10 +132,18 @@ class DownloadWorker @AssistedInject constructor(
}
}
- override suspend fun getForegroundInfo() = ForegroundInfo(
- id.hashCode(),
- notificationFactory.create(lastPublishedState),
- )
+ override suspend fun getForegroundInfo() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ ForegroundInfo(
+ id.hashCode(),
+ notificationFactory.create(lastPublishedState),
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC,
+ )
+ } else {
+ ForegroundInfo(
+ id.hashCode(),
+ notificationFactory.create(lastPublishedState),
+ )
+ }
private suspend fun downloadMangaImpl(
includedIds: LongArray?,
@@ -389,12 +399,12 @@ class DownloadWorker @AssistedInject constructor(
}
fun pause(id: UUID) {
- val intent = PausingReceiver.getPauseIntent(id)
+ val intent = PausingReceiver.getPauseIntent(context, id)
context.sendBroadcast(intent)
}
fun resume(id: UUID) {
- val intent = PausingReceiver.getResumeIntent(id)
+ val intent = PausingReceiver.getResumeIntent(context, id)
context.sendBroadcast(intent)
}
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/PausingReceiver.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/PausingReceiver.kt
index 71dc7aa4c..8bf4298d0 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/PausingReceiver.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/PausingReceiver.kt
@@ -40,18 +40,20 @@ class PausingReceiver(
addDataPath(id.toString(), PatternMatcher.PATTERN_SIMPLE_GLOB)
}
- fun getPauseIntent(id: UUID) = Intent(ACTION_PAUSE)
+ fun getPauseIntent(context: Context, id: UUID) = Intent(ACTION_PAUSE)
.setData(Uri.parse("$SCHEME://$id"))
+ .setPackage(context.packageName)
.putExtra(EXTRA_UUID, id.toString())
- fun getResumeIntent(id: UUID) = Intent(ACTION_RESUME)
+ fun getResumeIntent(context: Context, id: UUID) = Intent(ACTION_RESUME)
.setData(Uri.parse("$SCHEME://$id"))
+ .setPackage(context.packageName)
.putExtra(EXTRA_UUID, id.toString())
fun createPausePendingIntent(context: Context, id: UUID) = PendingIntentCompat.getBroadcast(
context,
0,
- getPauseIntent(id),
+ getPauseIntent(context, id),
0,
false,
)
@@ -59,7 +61,7 @@ class PausingReceiver(
fun createResumePendingIntent(context: Context, id: UUID) = PendingIntentCompat.getBroadcast(
context,
0,
- getResumeIntent(id),
+ getResumeIntent(context, id),
0,
false,
)
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/ImportWorker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/ImportWorker.kt
index 5a4d600c3..e1e912caa 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/ImportWorker.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/ImportWorker.kt
@@ -3,7 +3,9 @@ package org.koitharu.kotatsu.local.ui
import android.app.Notification
import android.app.PendingIntent
import android.content.Context
+import android.content.pm.ServiceInfo
import android.net.Uri
+import android.os.Build
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
@@ -22,6 +24,7 @@ import coil.request.ImageRequest
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import org.koitharu.kotatsu.R
+import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission
import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
import org.koitharu.kotatsu.core.util.ext.toBitmapOrNull
import org.koitharu.kotatsu.core.util.ext.toUriOrNull
@@ -46,7 +49,7 @@ class ImportWorker @AssistedInject constructor(
val result = runCatchingCancellable {
importer.import(uri).manga
}
- if (notificationManager.areNotificationsEnabled()) {
+ if (applicationContext.checkNotificationPermission()) {
val notification = buildNotification(result)
notificationManager.notify(uri.hashCode(), notification)
}
@@ -76,7 +79,11 @@ class ImportWorker @AssistedInject constructor(
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
.build()
- return ForegroundInfo(FOREGROUND_NOTIFICATION_ID, notification)
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ ForegroundInfo(FOREGROUND_NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
+ } else {
+ ForegroundInfo(FOREGROUND_NOTIFICATION_ID, notification)
+ }
}
private suspend fun buildNotification(result: kotlin.Result): Notification {
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderInfoBarView.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderInfoBarView.kt
index e0306c6fb..2f4e20047 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderInfoBarView.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderInfoBarView.kt
@@ -13,16 +13,17 @@ import android.util.AttributeSet
import android.view.View
import android.view.WindowInsets
import androidx.annotation.AttrRes
+import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.getThemeColor
import org.koitharu.kotatsu.core.util.ext.measureDimension
+import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.core.util.ext.resolveDp
import org.koitharu.kotatsu.parsers.util.format
import org.koitharu.kotatsu.reader.ui.pager.ReaderUiState
-import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import java.text.SimpleDateFormat
import java.util.Date
import com.google.android.material.R as materialR
@@ -111,7 +112,12 @@ class ReaderInfoBarView @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
- context.registerReceiver(timeReceiver, IntentFilter(Intent.ACTION_TIME_TICK))
+ ContextCompat.registerReceiver(
+ context,
+ timeReceiver,
+ IntentFilter(Intent.ACTION_TIME_TICK),
+ ContextCompat.RECEIVER_EXPORTED,
+ )
updateCutoutInsets(ViewCompat.getRootWindowInsets(this))
}
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt
index bd1fe0fd5..a347ac35c 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt
@@ -165,7 +165,8 @@ class WebtoonScalingFrame @JvmOverloads constructor(
private inner class GestureListener : GestureDetector.SimpleOnGestureListener(), Runnable {
- override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
+
+ override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
if (scale <= 1f) return false
transformMatrix.postTranslate(-distanceX, -distanceY)
invalidateTarget()
@@ -185,7 +186,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
return true
}
- override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
+ override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
if (scale <= 1) return false
overScroller.fling(
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/suggestions/ui/SuggestionsWorker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/suggestions/ui/SuggestionsWorker.kt
index dc37f78ca..4b0ca53a4 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/suggestions/ui/SuggestionsWorker.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/suggestions/ui/SuggestionsWorker.kt
@@ -2,6 +2,8 @@ package org.koitharu.kotatsu.suggestions.ui
import android.app.PendingIntent
import android.content.Context
+import android.content.pm.ServiceInfo
+import android.os.Build
import androidx.annotation.FloatRange
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationCompat
@@ -120,7 +122,11 @@ class SuggestionsWorker @AssistedInject constructor(
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_DEFERRED)
.build()
- return ForegroundInfo(WORKER_NOTIFICATION_ID, notification)
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ ForegroundInfo(WORKER_NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
+ } else {
+ ForegroundInfo(WORKER_NOTIFICATION_ID, notification)
+ }
}
private suspend fun doWorkImpl(): Int {
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt
index 50c6cf8be..06aa47101 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.tracker.work
import android.app.PendingIntent
import android.content.Context
+import android.content.pm.ServiceInfo
import android.os.Build
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationCompat
@@ -258,7 +259,11 @@ class TrackWorker @AssistedInject constructor(
.setSmallIcon(android.R.drawable.stat_notify_sync)
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_DEFERRED)
.build()
- return ForegroundInfo(WORKER_NOTIFICATION_ID, notification)
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ ForegroundInfo(WORKER_NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
+ } else {
+ ForegroundInfo(WORKER_NOTIFICATION_ID, notification)
+ }
}
private suspend fun setRetryIds(ids: Set) = runInterruptible(Dispatchers.IO) {