Make the app Android 8+
| @@ -3,7 +3,7 @@ | ||||
| | [](https://github.com/tachiyomiorg/tachiyomi/actions/workflows/build_push.yml) | [](https://github.com/tachiyomiorg/tachiyomi/releases) | [](https://github.com/tachiyomiorg/tachiyomi-preview/releases) | [](https://hosted.weblate.org/engage/tachiyomi/?utm_source=widget) | [](https://discord.gg/mihon) | | ||||
|  | ||||
| # Mihon | ||||
| Mihon is a free and open source manga reader for Android 6.0 and above. | ||||
| Mihon is a free and open source manga reader for Android 8.0 and above. | ||||
|  | ||||
| ## Features | ||||
|  | ||||
|   | ||||
| Before Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 4.1 KiB | 
| Before Width: | Height: | Size: 1.5 KiB | 
| Before Width: | Height: | Size: 2.3 KiB | 
| Before Width: | Height: | Size: 2.9 KiB | 
| Before Width: | Height: | Size: 5.3 KiB | 
| Before Width: | Height: | Size: 5.5 KiB | 
| Before Width: | Height: | Size: 10 KiB | 
| Before Width: | Height: | Size: 6.4 KiB | 
| Before Width: | Height: | Size: 13 KiB | 
| @@ -1,6 +1,5 @@ | ||||
| package eu.kanade.domain.ui | ||||
|  | ||||
| import android.os.Build | ||||
| import eu.kanade.domain.ui.model.AppTheme | ||||
| import eu.kanade.domain.ui.model.TabletUiMode | ||||
| import eu.kanade.domain.ui.model.ThemeMode | ||||
| @@ -16,10 +15,7 @@ class UiPreferences( | ||||
|     private val preferenceStore: PreferenceStore, | ||||
| ) { | ||||
|  | ||||
|     fun themeMode() = preferenceStore.getEnum( | ||||
|         "pref_theme_mode_key", | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { ThemeMode.SYSTEM } else { ThemeMode.LIGHT }, | ||||
|     ) | ||||
|     fun themeMode() = preferenceStore.getEnum("pref_theme_mode_key", ThemeMode.SYSTEM) | ||||
|  | ||||
|     fun appTheme() = preferenceStore.getEnum( | ||||
|         "pref_app_theme", | ||||
|   | ||||
| @@ -2,7 +2,6 @@ package eu.kanade.presentation.manga.components | ||||
|  | ||||
| import android.graphics.Bitmap | ||||
| import android.graphics.drawable.BitmapDrawable | ||||
| import android.os.Build | ||||
| import androidx.compose.foundation.background | ||||
| import androidx.compose.foundation.layout.Box | ||||
| import androidx.compose.foundation.layout.Row | ||||
| @@ -173,14 +172,9 @@ fun MangaCoverDialog( | ||||
|                                 // Copy bitmap in case it came from memory cache | ||||
|                                 // Because SSIV needs to thoroughly read the image | ||||
|                                 val copy = (drawable as? BitmapDrawable)?.let { | ||||
|                                     val config = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|                                         Bitmap.Config.HARDWARE | ||||
|                                     } else { | ||||
|                                         Bitmap.Config.ARGB_8888 | ||||
|                                     } | ||||
|                                     BitmapDrawable( | ||||
|                                         view.context.resources, | ||||
|                                         it.bitmap.copy(config, false), | ||||
|                                         it.bitmap.copy(Bitmap.Config.HARDWARE, false), | ||||
|                                     ) | ||||
|                                 } ?: drawable | ||||
|                                 view.setImage(copy, ReaderPageImageView.Config(zoomDuration = 500)) | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package eu.kanade.presentation.more.settings.screen | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.ActivityNotFoundException | ||||
| import android.content.Intent | ||||
| import android.os.Build | ||||
| import android.provider.Settings | ||||
| import android.webkit.WebStorage | ||||
| import android.webkit.WebView | ||||
| @@ -84,60 +83,48 @@ object SettingsAdvancedScreen : SearchableSettings { | ||||
|         val basePreferences = remember { Injekt.get<BasePreferences>() } | ||||
|         val networkPreferences = remember { Injekt.get<NetworkPreferences>() } | ||||
|  | ||||
|         return buildList { | ||||
|             addAll( | ||||
|                 listOf( | ||||
|                     Preference.PreferenceItem.TextPreference( | ||||
|                         title = stringResource(MR.strings.pref_dump_crash_logs), | ||||
|                         subtitle = stringResource(MR.strings.pref_dump_crash_logs_summary), | ||||
|                         onClick = { | ||||
|                             scope.launch { | ||||
|                                 CrashLogUtil(context).dumpLogs() | ||||
|                             } | ||||
|                         }, | ||||
|                     ), | ||||
|                     Preference.PreferenceItem.SwitchPreference( | ||||
|                         pref = networkPreferences.verboseLogging(), | ||||
|                         title = stringResource(MR.strings.pref_verbose_logging), | ||||
|                         subtitle = stringResource(MR.strings.pref_verbose_logging_summary), | ||||
|                         onValueChanged = { | ||||
|                             context.toast(MR.strings.requires_app_restart) | ||||
|                             true | ||||
|                         }, | ||||
|                     ), | ||||
|                     Preference.PreferenceItem.TextPreference( | ||||
|                         title = stringResource(MR.strings.pref_debug_info), | ||||
|                         onClick = { navigator.push(DebugInfoScreen()) }, | ||||
|                     ), | ||||
|                     Preference.PreferenceItem.TextPreference( | ||||
|                         title = stringResource(MR.strings.pref_onboarding_guide), | ||||
|                         onClick = { navigator.push(OnboardingScreen()) }, | ||||
|                     ), | ||||
|                 ), | ||||
|             ) | ||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|                 add( | ||||
|                     Preference.PreferenceItem.TextPreference( | ||||
|                         title = stringResource(MR.strings.pref_manage_notifications), | ||||
|                         onClick = { | ||||
|                             val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply { | ||||
|                                 putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName) | ||||
|                             } | ||||
|                             context.startActivity(intent) | ||||
|                         }, | ||||
|                     ), | ||||
|                 ) | ||||
|             } | ||||
|             addAll( | ||||
|                 listOf( | ||||
|                     getBackgroundActivityGroup(), | ||||
|                     getDataGroup(), | ||||
|                     getNetworkGroup(networkPreferences = networkPreferences), | ||||
|                     getLibraryGroup(), | ||||
|                     getExtensionsGroup(basePreferences = basePreferences), | ||||
|                 ), | ||||
|             ) | ||||
|         } | ||||
|         return listOf( | ||||
|             Preference.PreferenceItem.TextPreference( | ||||
|                 title = stringResource(MR.strings.pref_dump_crash_logs), | ||||
|                 subtitle = stringResource(MR.strings.pref_dump_crash_logs_summary), | ||||
|                 onClick = { | ||||
|                     scope.launch { | ||||
|                         CrashLogUtil(context).dumpLogs() | ||||
|                     } | ||||
|                 }, | ||||
|             ), | ||||
|             Preference.PreferenceItem.SwitchPreference( | ||||
|                 pref = networkPreferences.verboseLogging(), | ||||
|                 title = stringResource(MR.strings.pref_verbose_logging), | ||||
|                 subtitle = stringResource(MR.strings.pref_verbose_logging_summary), | ||||
|                 onValueChanged = { | ||||
|                     context.toast(MR.strings.requires_app_restart) | ||||
|                     true | ||||
|                 }, | ||||
|             ), | ||||
|             Preference.PreferenceItem.TextPreference( | ||||
|                 title = stringResource(MR.strings.pref_debug_info), | ||||
|                 onClick = { navigator.push(DebugInfoScreen()) }, | ||||
|             ), | ||||
|             Preference.PreferenceItem.TextPreference( | ||||
|                 title = stringResource(MR.strings.pref_onboarding_guide), | ||||
|                 onClick = { navigator.push(OnboardingScreen()) }, | ||||
|             ), | ||||
|             Preference.PreferenceItem.TextPreference( | ||||
|                 title = stringResource(MR.strings.pref_manage_notifications), | ||||
|                 onClick = { | ||||
|                     val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply { | ||||
|                         putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName) | ||||
|                     } | ||||
|                     context.startActivity(intent) | ||||
|                 }, | ||||
|             ), | ||||
|             getBackgroundActivityGroup(), | ||||
|             getDataGroup(), | ||||
|             getNetworkGroup(networkPreferences = networkPreferences), | ||||
|             getLibraryGroup(), | ||||
|             getExtensionsGroup(basePreferences = basePreferences), | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|   | ||||
| @@ -60,7 +60,6 @@ object SettingsReaderScreen : SearchableSettings { | ||||
|                 pref = readerPref.trueColor(), | ||||
|                 title = stringResource(MR.strings.pref_true_color), | ||||
|                 subtitle = stringResource(MR.strings.pref_true_color_summary), | ||||
|                 enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O, | ||||
|             ), | ||||
|             Preference.PreferenceItem.SwitchPreference( | ||||
|                 pref = readerPref.pageTransitions(), | ||||
|   | ||||
| @@ -13,18 +13,11 @@ import eu.kanade.domain.ui.model.ThemeMode | ||||
| import tachiyomi.i18n.MR | ||||
| import tachiyomi.presentation.core.i18n.stringResource | ||||
|  | ||||
| private val options = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|     mapOf( | ||||
|         ThemeMode.SYSTEM to MR.strings.theme_system, | ||||
|         ThemeMode.LIGHT to MR.strings.theme_light, | ||||
|         ThemeMode.DARK to MR.strings.theme_dark, | ||||
|     ) | ||||
| } else { | ||||
|     mapOf( | ||||
|         ThemeMode.LIGHT to MR.strings.theme_light, | ||||
|         ThemeMode.DARK to MR.strings.theme_dark, | ||||
|     ) | ||||
| } | ||||
| private val options = mapOf( | ||||
|     ThemeMode.SYSTEM to MR.strings.theme_system, | ||||
|     ThemeMode.LIGHT to MR.strings.theme_light, | ||||
|     ThemeMode.DARK to MR.strings.theme_dark, | ||||
| ) | ||||
|  | ||||
| @Composable | ||||
| internal fun AppThemeModePreferenceWidget( | ||||
|   | ||||
| @@ -23,12 +23,7 @@ fun rememberRequestPackageInstallsPermissionState(initialValue: Boolean = false) | ||||
|     DisposableEffect(lifecycleOwner.lifecycle) { | ||||
|         val observer = object : DefaultLifecycleObserver { | ||||
|             override fun onResume(owner: LifecycleOwner) { | ||||
|                 installGranted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|                     context.packageManager.canRequestPackageInstalls() | ||||
|                 } else { | ||||
|                     @Suppress("DEPRECATION") | ||||
|                     Settings.Secure.getInt(context.contentResolver, Settings.Secure.INSTALL_NON_MARKET_APPS) != 0 | ||||
|                 } | ||||
|                 installGranted = context.packageManager.canRequestPackageInstalls() | ||||
|             } | ||||
|         } | ||||
|         lifecycleOwner.lifecycle.addObserver(observer) | ||||
|   | ||||
| @@ -169,22 +169,19 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory { | ||||
|     } | ||||
|  | ||||
|     override fun getPackageName(): String { | ||||
|         // This causes freezes in Android 6/7 for some reason | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             try { | ||||
|                 // Override the value passed as X-Requested-With in WebView requests | ||||
|                 val stackTrace = Looper.getMainLooper().thread.stackTrace | ||||
|                 val chromiumElement = stackTrace.find { | ||||
|                     it.className.equals( | ||||
|                         "org.chromium.base.BuildInfo", | ||||
|                         ignoreCase = true, | ||||
|                     ) | ||||
|                 } | ||||
|                 if (chromiumElement?.methodName.equals("getAll", ignoreCase = true)) { | ||||
|                     return WebViewUtil.SPOOF_PACKAGE_NAME | ||||
|                 } | ||||
|             } catch (_: Exception) { | ||||
|         try { | ||||
|             // Override the value passed as X-Requested-With in WebView requests | ||||
|             val stackTrace = Looper.getMainLooper().thread.stackTrace | ||||
|             val chromiumElement = stackTrace.find { | ||||
|                 it.className.equals( | ||||
|                     "org.chromium.base.BuildInfo", | ||||
|                     ignoreCase = true, | ||||
|                 ) | ||||
|             } | ||||
|             if (chromiumElement?.methodName.equals("getAll", ignoreCase = true)) { | ||||
|                 return WebViewUtil.SPOOF_PACKAGE_NAME | ||||
|             } | ||||
|         } catch (_: Exception) { | ||||
|         } | ||||
|         return super.getPackageName() | ||||
|     } | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.data.coil | ||||
|  | ||||
| import android.os.Build | ||||
| import androidx.core.graphics.drawable.toDrawable | ||||
| import coil.ImageLoader | ||||
| import coil.decode.DecodeResult | ||||
| @@ -48,8 +47,7 @@ class TachiyomiImageDecoder(private val resources: ImageSource, private val opti | ||||
|                 ImageUtil.findImageType(it) | ||||
|             } | ||||
|             return when (type) { | ||||
|                 ImageUtil.ImageType.AVIF, ImageUtil.ImageType.JXL -> true | ||||
|                 ImageUtil.ImageType.HEIF -> Build.VERSION.SDK_INT < Build.VERSION_CODES.O | ||||
|                 ImageUtil.ImageType.AVIF, ImageUtil.ImageType.JXL, ImageUtil.ImageType.HEIF -> true | ||||
|                 else -> false | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import android.content.BroadcastReceiver | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.net.Uri | ||||
| import android.os.Build | ||||
| import androidx.core.net.toUri | ||||
| import eu.kanade.tachiyomi.data.backup.restore.BackupRestoreJob | ||||
| import eu.kanade.tachiyomi.data.download.DownloadManager | ||||
| @@ -354,20 +353,18 @@ class NotificationReceiver : BroadcastReceiver() { | ||||
|  | ||||
|             When programmatically dismissing this notification, the group notification is not automatically dismissed. | ||||
|              */ | ||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||
|                 val groupKey = context.notificationManager.activeNotifications.find { | ||||
|                     it.id == notificationId | ||||
|                 }?.groupKey | ||||
|             val groupKey = context.notificationManager.activeNotifications.find { | ||||
|                 it.id == notificationId | ||||
|             }?.groupKey | ||||
|  | ||||
|                 if (groupId != null && groupId != 0 && !groupKey.isNullOrEmpty()) { | ||||
|                     val notifications = context.notificationManager.activeNotifications.filter { | ||||
|                         it.groupKey == groupKey | ||||
|                     } | ||||
|             if (groupId != null && groupId != 0 && !groupKey.isNullOrEmpty()) { | ||||
|                 val notifications = context.notificationManager.activeNotifications.filter { | ||||
|                     it.groupKey == groupKey | ||||
|                 } | ||||
|  | ||||
|                     if (notifications.size == 2) { | ||||
|                         context.cancelNotification(groupId) | ||||
|                         return | ||||
|                     } | ||||
|                 if (notifications.size == 2) { | ||||
|                     context.cancelNotification(groupId) | ||||
|                     return | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.extension.installer | ||||
|  | ||||
| import android.app.Service | ||||
| import android.content.pm.PackageManager | ||||
| import android.os.Build | ||||
| import eu.kanade.tachiyomi.extension.model.InstallStep | ||||
| import eu.kanade.tachiyomi.util.system.getUriSize | ||||
| import eu.kanade.tachiyomi.util.system.toast | ||||
| @@ -50,11 +49,7 @@ class ShizukuInstaller(private val service: Service) : Installer(service) { | ||||
|             try { | ||||
|                 val size = service.getUriSize(entry.uri) ?: throw IllegalStateException() | ||||
|                 service.contentResolver.openInputStream(entry.uri)!!.use { | ||||
|                     val createCommand = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||
|                         "pm install-create --user current -r -i ${service.packageName} -S $size" | ||||
|                     } else { | ||||
|                         "pm install-create -r -i ${service.packageName} -S $size" | ||||
|                     } | ||||
|                     val createCommand = "pm install-create --user current -r -i ${service.packageName} -S $size" | ||||
|                     val createResult = exec(createCommand) | ||||
|                     sessionId = SESSION_ID_REGEX.find(createResult.out)?.value | ||||
|                         ?: throw RuntimeException("Failed to create install session") | ||||
|   | ||||
| @@ -14,11 +14,7 @@ import java.util.zip.ZipFile | ||||
|  */ | ||||
| internal class ZipPageLoader(file: File) : PageLoader() { | ||||
|  | ||||
|     private val zip = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||
|         ZipFile(file, StandardCharsets.ISO_8859_1) | ||||
|     } else { | ||||
|         ZipFile(file) | ||||
|     } | ||||
|     private val zip = ZipFile(file, StandardCharsets.ISO_8859_1) | ||||
|  | ||||
|     override var isLocal: Boolean = true | ||||
|  | ||||
|   | ||||
| @@ -2,9 +2,7 @@ package eu.kanade.tachiyomi.util.storage | ||||
|  | ||||
| import android.content.Context | ||||
| import android.net.Uri | ||||
| import android.os.Build | ||||
| import androidx.core.content.FileProvider | ||||
| import androidx.core.net.toUri | ||||
| import eu.kanade.tachiyomi.BuildConfig | ||||
| import java.io.File | ||||
|  | ||||
| @@ -17,11 +15,7 @@ val Context.cacheImageDir: File | ||||
|  * @param context context of application | ||||
|  */ | ||||
| fun File.getUriCompat(context: Context): Uri { | ||||
|     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||
|         FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", this) | ||||
|     } else { | ||||
|         this.toUri() | ||||
|     } | ||||
|     return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", this) | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -170,12 +170,8 @@ fun Context.isInstalledFromFDroid(): Boolean { | ||||
| } | ||||
|  | ||||
| fun Context.launchRequestPackageInstallsPermission() { | ||||
|     val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|         Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply { | ||||
|             data = Uri.parse("package:$packageName") | ||||
|         } | ||||
|     } else { | ||||
|         Intent(Settings.ACTION_SECURITY_SETTINGS) | ||||
|     Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply { | ||||
|         data = Uri.parse("package:$packageName") | ||||
|         startActivity(this) | ||||
|     } | ||||
|     startActivity(intent) | ||||
| } | ||||
|   | ||||
| @@ -18,8 +18,7 @@ fun Context.isOnline(): Boolean { | ||||
|     val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false | ||||
|     val maxTransport = when { | ||||
|         Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1 -> NetworkCapabilities.TRANSPORT_LOWPAN | ||||
|         Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> NetworkCapabilities.TRANSPORT_WIFI_AWARE | ||||
|         else -> NetworkCapabilities.TRANSPORT_VPN | ||||
|         else -> NetworkCapabilities.TRANSPORT_WIFI_AWARE | ||||
|     } | ||||
|     return (NetworkCapabilities.TRANSPORT_CELLULAR..maxTransport).any(networkCapabilities::hasTransport) | ||||
| } | ||||
|   | ||||
| @@ -17,11 +17,7 @@ data class NetworkState( | ||||
|     val isValidated: Boolean, | ||||
|     val isWifi: Boolean, | ||||
| ) { | ||||
|     val isOnline = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|         isConnected && isValidated | ||||
|     } else { | ||||
|         isConnected | ||||
|     } | ||||
|     val isOnline = isConnected && isValidated | ||||
| } | ||||
|  | ||||
| @Suppress("DEPRECATION") | ||||
| @@ -34,34 +30,18 @@ fun Context.activeNetworkState(): NetworkState { | ||||
|     ) | ||||
| } | ||||
|  | ||||
| @Suppress("DEPRECATION") | ||||
| fun Context.networkStateFlow() = callbackFlow { | ||||
|     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||
|         val networkCallback = object : NetworkCallback() { | ||||
|             override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { | ||||
|                 trySend(activeNetworkState()) | ||||
|             } | ||||
|             override fun onLost(network: Network) { | ||||
|                 trySend(activeNetworkState()) | ||||
|             } | ||||
|     val networkCallback = object : NetworkCallback() { | ||||
|         override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { | ||||
|             trySend(activeNetworkState()) | ||||
|         } | ||||
|  | ||||
|         connectivityManager.registerDefaultNetworkCallback(networkCallback) | ||||
|         awaitClose { | ||||
|             connectivityManager.unregisterNetworkCallback(networkCallback) | ||||
|         } | ||||
|     } else { | ||||
|         val receiver = object : BroadcastReceiver() { | ||||
|             override fun onReceive(context: Context, intent: Intent) { | ||||
|                 if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) { | ||||
|                     trySend(activeNetworkState()) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         registerReceiver(receiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)) | ||||
|         awaitClose { | ||||
|             unregisterReceiver(receiver) | ||||
|         override fun onLost(network: Network) { | ||||
|             trySend(activeNetworkState()) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     connectivityManager.registerDefaultNetworkCallback(networkCallback) | ||||
|     awaitClose { | ||||
|         connectivityManager.unregisterNetworkCallback(networkCallback) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,24 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     tools:keep="@drawable/sc_collections_bookmark_48dp"> | ||||
| <background android:drawable="@color/accent_blue"/> | ||||
| <foreground> | ||||
|     <vector | ||||
|         android:width="120dp" | ||||
|         android:height="120dp" | ||||
|         android:viewportWidth="56.0" | ||||
|         android:viewportHeight="56.0"> | ||||
|         <group | ||||
|             android:translateX="16" | ||||
|             android:translateY="16"> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6z"/> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,12l-2.5,-1.5L15,12L15,4h5v8z"/> | ||||
|         </group> | ||||
|     </vector> | ||||
| </foreground> | ||||
| </adaptive-icon> | ||||
| @@ -1,21 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     tools:keep="@drawable/sc_explore_48dp"> | ||||
| <background android:drawable="@color/accent_blue"/> | ||||
| <foreground> | ||||
|     <vector | ||||
|         android:width="120dp" | ||||
|         android:height="120dp" | ||||
|         android:viewportWidth="56.0" | ||||
|         android:viewportHeight="56.0"> | ||||
|         <group | ||||
|             android:translateX="16" | ||||
|             android:translateY="16"> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M12,10.9c-0.61,0 -1.1,0.49 -1.1,1.1s0.49,1.1 1.1,1.1c0.61,0 1.1,-0.49 1.1,-1.1s-0.49,-1.1 -1.1,-1.1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM14.19,14.19L6,18l3.81,-8.19L18,6l-3.81,8.19z" /> | ||||
|         </group> | ||||
|     </vector> | ||||
| </foreground> | ||||
| </adaptive-icon> | ||||
| @@ -1,21 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     tools:keep="@drawable/sc_history_48dp"> | ||||
| <background android:drawable="@color/accent_blue"/> | ||||
| <foreground> | ||||
|     <vector | ||||
|         android:width="120dp" | ||||
|         android:height="120dp" | ||||
|         android:viewportWidth="56.0" | ||||
|         android:viewportHeight="56.0"> | ||||
|         <group | ||||
|             android:translateX="16" | ||||
|             android:translateY="16"> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" /> | ||||
|         </group> | ||||
|     </vector> | ||||
| </foreground> | ||||
| </adaptive-icon> | ||||
| @@ -1,21 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     tools:keep="@drawable/sc_new_releases_48dp"> | ||||
| <background android:drawable="@color/accent_blue"/> | ||||
| <foreground> | ||||
|     <vector | ||||
|         android:width="120dp" | ||||
|         android:height="120dp" | ||||
|         android:viewportWidth="56.0" | ||||
|         android:viewportHeight="56.0"> | ||||
|         <group | ||||
|             android:translateX="16" | ||||
|             android:translateY="16"> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z" /> | ||||
|         </group> | ||||
|     </vector> | ||||
| </foreground> | ||||
| </adaptive-icon> | ||||
| @@ -1,24 +1,24 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     tools:keep="@drawable/sc_collections_bookmark_48dp" | ||||
|     android:width="48dp" | ||||
|     android:height="48dp" | ||||
|     android:viewportWidth="48" | ||||
|     android:viewportHeight="48"> | ||||
|  | ||||
|     <path | ||||
|         android:fillColor="@color/accent_blue" | ||||
|         android:pathData="M24,24m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0" /> | ||||
|  | ||||
|     <group | ||||
|         android:translateX="12" | ||||
|         android:translateY="12"> | ||||
|         <path | ||||
|             android:fillColor="#FFF" | ||||
|             android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6z" /> | ||||
|         <path | ||||
|             android:fillColor="#FFF" | ||||
|             android:pathData="M20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,12l-2.5,-1.5L15,12L15,4h5v8z" /> | ||||
|     </group> | ||||
| </vector> | ||||
|     tools:keep="@drawable/sc_collections_bookmark_48dp"> | ||||
| <background android:drawable="@color/accent_blue"/> | ||||
| <foreground> | ||||
|     <vector | ||||
|         android:width="120dp" | ||||
|         android:height="120dp" | ||||
|         android:viewportWidth="56.0" | ||||
|         android:viewportHeight="56.0"> | ||||
|         <group | ||||
|             android:translateX="16" | ||||
|             android:translateY="16"> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6z"/> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,12l-2.5,-1.5L15,12L15,4h5v8z"/> | ||||
|         </group> | ||||
|     </vector> | ||||
| </foreground> | ||||
| </adaptive-icon> | ||||
|   | ||||
| @@ -1,21 +1,21 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     tools:keep="@drawable/sc_explore_48dp" | ||||
|     android:width="48dp" | ||||
|     android:height="48dp" | ||||
|     android:viewportWidth="48" | ||||
|     android:viewportHeight="48"> | ||||
|  | ||||
|     <path | ||||
|         android:fillColor="@color/accent_blue" | ||||
|         android:pathData="M24,24m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0" /> | ||||
|  | ||||
|     <group | ||||
|         android:translateX="12" | ||||
|         android:translateY="12"> | ||||
|         <path | ||||
|             android:fillColor="#FFF" | ||||
|             android:pathData="M12,10.9c-0.61,0 -1.1,0.49 -1.1,1.1s0.49,1.1 1.1,1.1c0.61,0 1.1,-0.49 1.1,-1.1s-0.49,-1.1 -1.1,-1.1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM14.19,14.19L6,18l3.81,-8.19L18,6l-3.81,8.19z" /> | ||||
|     </group> | ||||
| </vector> | ||||
|     tools:keep="@drawable/sc_explore_48dp"> | ||||
| <background android:drawable="@color/accent_blue"/> | ||||
| <foreground> | ||||
|     <vector | ||||
|         android:width="120dp" | ||||
|         android:height="120dp" | ||||
|         android:viewportWidth="56.0" | ||||
|         android:viewportHeight="56.0"> | ||||
|         <group | ||||
|             android:translateX="16" | ||||
|             android:translateY="16"> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M12,10.9c-0.61,0 -1.1,0.49 -1.1,1.1s0.49,1.1 1.1,1.1c0.61,0 1.1,-0.49 1.1,-1.1s-0.49,-1.1 -1.1,-1.1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM14.19,14.19L6,18l3.81,-8.19L18,6l-3.81,8.19z" /> | ||||
|         </group> | ||||
|     </vector> | ||||
| </foreground> | ||||
| </adaptive-icon> | ||||
|   | ||||
| @@ -1,21 +1,21 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     tools:keep="@drawable/sc_history_48dp" | ||||
|     android:width="48dp" | ||||
|     android:height="48dp" | ||||
|     android:viewportWidth="48" | ||||
|     android:viewportHeight="48"> | ||||
|  | ||||
|     <path | ||||
|         android:fillColor="@color/accent_blue" | ||||
|         android:pathData="M24,24m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0" /> | ||||
|  | ||||
|     <group | ||||
|         android:translateX="12" | ||||
|         android:translateY="12"> | ||||
|         <path | ||||
|             android:fillColor="#FFF" | ||||
|             android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" /> | ||||
|     </group> | ||||
| </vector> | ||||
|     tools:keep="@drawable/sc_history_48dp"> | ||||
| <background android:drawable="@color/accent_blue"/> | ||||
| <foreground> | ||||
|     <vector | ||||
|         android:width="120dp" | ||||
|         android:height="120dp" | ||||
|         android:viewportWidth="56.0" | ||||
|         android:viewportHeight="56.0"> | ||||
|         <group | ||||
|             android:translateX="16" | ||||
|             android:translateY="16"> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" /> | ||||
|         </group> | ||||
|     </vector> | ||||
| </foreground> | ||||
| </adaptive-icon> | ||||
|   | ||||
| @@ -1,21 +1,21 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     tools:keep="@drawable/sc_new_releases_48dp" | ||||
|     android:width="48dp" | ||||
|     android:height="48dp" | ||||
|     android:viewportWidth="48" | ||||
|     android:viewportHeight="48"> | ||||
|  | ||||
|     <path | ||||
|         android:fillColor="@color/accent_blue" | ||||
|         android:pathData="M24,24m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0" /> | ||||
|  | ||||
|     <group | ||||
|         android:translateX="12" | ||||
|         android:translateY="12"> | ||||
|         <path | ||||
|             android:fillColor="#FFF" | ||||
|             android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z" /> | ||||
|     </group> | ||||
| </vector> | ||||
|     tools:keep="@drawable/sc_new_releases_48dp"> | ||||
| <background android:drawable="@color/accent_blue"/> | ||||
| <foreground> | ||||
|     <vector | ||||
|         android:width="120dp" | ||||
|         android:height="120dp" | ||||
|         android:viewportWidth="56.0" | ||||
|         android:viewportHeight="56.0"> | ||||
|         <group | ||||
|             android:translateX="16" | ||||
|             android:translateY="16"> | ||||
|             <path | ||||
|                 android:fillColor="#FFF" | ||||
|                 android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z" /> | ||||
|         </group> | ||||
|     </vector> | ||||
| </foreground> | ||||
| </adaptive-icon> | ||||
|   | ||||
| Before Width: | Height: | Size: 2.5 KiB | 
| Before Width: | Height: | Size: 4.3 KiB | 
| Before Width: | Height: | Size: 1.5 KiB | 
| Before Width: | Height: | Size: 2.4 KiB | 
| Before Width: | Height: | Size: 2.9 KiB | 
| Before Width: | Height: | Size: 5.4 KiB | 
| Before Width: | Height: | Size: 5.8 KiB | 
| Before Width: | Height: | Size: 11 KiB | 
| Before Width: | Height: | Size: 6.9 KiB | 
| Before Width: | Height: | Size: 14 KiB | 
| @@ -1,6 +1,6 @@ | ||||
| object AndroidConfig { | ||||
|     const val compileSdk = 34 | ||||
|     const val minSdk = 23 | ||||
|     const val minSdk = 26 | ||||
|     const val targetSdk = 34 | ||||
|     const val ndk = "26.1.10909125" | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.util.system | ||||
|  | ||||
| import android.annotation.TargetApi | ||||
| import android.os.Build | ||||
| import android.webkit.WebResourceError | ||||
| import android.webkit.WebResourceRequest | ||||
| import android.webkit.WebResourceResponse | ||||
| @@ -28,7 +26,6 @@ abstract class WebViewClientCompat : WebViewClient() { | ||||
|     ) { | ||||
|     } | ||||
|  | ||||
|     @TargetApi(Build.VERSION_CODES.N) | ||||
|     final override fun shouldOverrideUrlLoading( | ||||
|         view: WebView, | ||||
|         request: WebResourceRequest, | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.util.system | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.Context | ||||
| import android.content.pm.PackageManager | ||||
| import android.os.Build | ||||
| import android.webkit.CookieManager | ||||
| import android.webkit.WebSettings | ||||
| import android.webkit.WebView | ||||
| @@ -35,15 +34,11 @@ object WebViewUtil { | ||||
|     } | ||||
|  | ||||
|     fun getVersion(context: Context): String { | ||||
|         return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             val webView = WebView.getCurrentWebViewPackage() ?: return "how did you get here?" | ||||
|             val pm = context.packageManager | ||||
|             val label = webView.applicationInfo.loadLabel(pm) | ||||
|             val version = webView.versionName | ||||
|             "$label $version" | ||||
|         } else { | ||||
|             "Unknown" | ||||
|         } | ||||
|         val webView = WebView.getCurrentWebViewPackage() ?: return "how did you get here?" | ||||
|         val pm = context.packageManager | ||||
|         val label = webView.applicationInfo.loadLabel(pm) | ||||
|         val version = webView.versionName | ||||
|         return "$label $version" | ||||
|     } | ||||
|  | ||||
|     fun supportsWebView(context: Context): Boolean { | ||||
|   | ||||