diff --git a/gradle/versions.gradle b/gradle/versions.gradle index 799d9bc9..b147fc2b 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -1,5 +1,5 @@ ext.versions = [ - minSdk : 21, + minSdk : 26, targetSdk : 33, compileSdk : 35, ] diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt index b71e402a..3d3a339e 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt @@ -227,7 +227,7 @@ class NavigationActivity : ScopeActivity() { // Setup app shortcuts on supported devices, but not on first start, when the server // is not configured yet. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1 && !UApp.instance!!.isFirstRun) { + if (!UApp.instance!!.isFirstRun) { ShortcutUtil.registerShortcuts(this) } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/app/UApp.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/app/UApp.kt index 8f90d438..fa64f100 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/app/UApp.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/app/UApp.kt @@ -114,10 +114,8 @@ private fun VmPolicy.Builder.detectAllExceptSocket(): VmPolicy.Builder { detectLeakedClosableObjects() detectLeakedRegistrationObjects() detectFileUriExposure() + detectContentUriWithoutPermission() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - detectContentUriWithoutPermission() - } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { detectCredentialProtectedWhileLocked() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/CoverArtRequestHandler.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/CoverArtRequestHandler.kt index 379d79f9..23370b8f 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/CoverArtRequestHandler.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/CoverArtRequestHandler.kt @@ -85,12 +85,6 @@ class CoverArtRequestHandler(private val client: SubsonicAPIClient) : RequestHan BitmapFactory.decodeFile(path, opt) // Now set the remaining flags - @Suppress("DEPRECATION") - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - opt.inDither = true - opt.inPreferQualityOverSpeed = true - } - opt.inSampleSize = Util.calculateInSampleSize( opt, size, diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/provider/UltrasonicAppWidgetProvider.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/provider/UltrasonicAppWidgetProvider.kt index 18f889f8..8a941c2e 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/provider/UltrasonicAppWidgetProvider.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/provider/UltrasonicAppWidgetProvider.kt @@ -218,10 +218,8 @@ open class UltrasonicAppWidgetProvider : AppWidgetProvider() { intent.action = Intent.ACTION_MAIN intent.addCategory(Intent.CATEGORY_LAUNCHER) var flags = PendingIntent.FLAG_UPDATE_CURRENT - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // needed starting Android 12 (S = 31) - flags = flags or PendingIntent.FLAG_IMMUTABLE - } + // needed starting Android 12 (S = 31) + flags = flags or PendingIntent.FLAG_IMMUTABLE var pendingIntent = PendingIntent.getActivity(context, 10, intent, flags) views.setOnClickPendingIntent(R.id.appwidget_coverart, pendingIntent) @@ -235,10 +233,8 @@ open class UltrasonicAppWidgetProvider : AppWidgetProvider() { KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) ) flags = 0 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // needed starting Android 12 (S = 31) - flags = PendingIntent.FLAG_IMMUTABLE - } + // needed starting Android 12 (S = 31) + flags = PendingIntent.FLAG_IMMUTABLE pendingIntent = PendingIntent.getBroadcast(context, 11, intent, flags) views.setOnClickPendingIntent(R.id.control_play, pendingIntent) intent = Intent(Constants.CMD_PROCESS_KEYCODE) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadService.kt index e373884e..be8a89bb 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadService.kt @@ -509,11 +509,7 @@ class DownloadService : Service(), KoinComponent { try { val context = UApp.applicationContext() val intent = Intent(context, DownloadService::class.java) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.startForegroundService(intent) - } else { - context.startService(intent) - } + context.startForegroundService(intent) } catch (e: IllegalStateException) { Timber.w(e, "Failed to start download service: the app is in the background") } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaLibrarySessionCallback.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaLibrarySessionCallback.kt index fbe2b37c..844511b8 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaLibrarySessionCallback.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MediaLibrarySessionCallback.kt @@ -268,40 +268,36 @@ class MediaLibrarySessionCallback : } private fun configureRepeatMode(player: Player) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Timber.d("Car app library available, observing CarConnection") + Timber.d("Car app library available, observing CarConnection") - val originalRepeatMode = player.repeatMode + val originalRepeatMode = player.repeatMode - var lastCarConnectionType = -1 + var lastCarConnectionType = -1 - CarConnection(UApp.applicationContext()).type.observeForever { - if (lastCarConnectionType == it) { - return@observeForever - } - - lastCarConnectionType = it - - Timber.d("CarConnection type changed to %s", it) - - when (it) { - CarConnection.CONNECTION_TYPE_PROJECTION -> - if (!customRepeatModeSet) { - Timber.d("[CarConnection] Setting repeat mode to ALL") - player.repeatMode = Player.REPEAT_MODE_ALL - customRepeatModeSet = true - } - - CarConnection.CONNECTION_TYPE_NOT_CONNECTED -> - if (customRepeatModeSet) { - Timber.d("[CarConnection] Resetting repeat mode") - player.repeatMode = originalRepeatMode - customRepeatModeSet = false - } - } + CarConnection(UApp.applicationContext()).type.observeForever { + if (lastCarConnectionType == it) { + return@observeForever + } + + lastCarConnectionType = it + + Timber.d("CarConnection type changed to %s", it) + + when (it) { + CarConnection.CONNECTION_TYPE_PROJECTION -> + if (!customRepeatModeSet) { + Timber.d("[CarConnection] Setting repeat mode to ALL") + player.repeatMode = Player.REPEAT_MODE_ALL + customRepeatModeSet = true + } + + CarConnection.CONNECTION_TYPE_NOT_CONNECTED -> + if (customRepeatModeSet) { + Timber.d("[CarConnection] Resetting repeat mode") + player.repeatMode = originalRepeatMode + customRepeatModeSet = false + } } - } else { - Timber.d("Car app library not available") } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/PlaybackService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/PlaybackService.kt index 277184a5..0245b40f 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/PlaybackService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/PlaybackService.kt @@ -337,11 +337,7 @@ class PlaybackService : private fun getPendingIntentForContent(): PendingIntent { val intent = Intent(this, NavigationActivity::class.java) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) - var flags = FLAG_UPDATE_CURRENT - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // needed starting Android 12 (S = 31) - flags = flags or FLAG_IMMUTABLE - } + val flags = FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE intent.action = Intent.ACTION_MAIN intent.putExtra(Constants.INTENT_SHOW_PLAYER, true) return PendingIntent.getActivity(this, 0, intent, flags) @@ -382,12 +378,8 @@ class PlaybackService : TaskStackBuilder.create(this@PlaybackService).run { addNextIntent(Intent(this@PlaybackService, NavigationActivity::class.java)) - val immutableFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - FLAG_IMMUTABLE - } else { - 0 - } - getPendingIntent(0, immutableFlag or FLAG_UPDATE_CURRENT) + val immutableFlag = FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT + getPendingIntent(0, immutableFlag) } val builder = NotificationCompat.Builder(this@PlaybackService, NOTIFICATION_CHANNEL_ID) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt index 8f08ed03..913044f8 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt @@ -259,16 +259,7 @@ object FileUtil { get() { // Return cached if possible if (cachedUltrasonicDirectory != null) return cachedUltrasonicDirectory!! - - @Suppress("DEPRECATION") - cachedUltrasonicDirectory = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - File( - Environment.getExternalStorageDirectory(), - "Android/data/org.moire.ultrasonic" - ) - } else { - UApp.applicationContext().getExternalFilesDir(null)!! - } + cachedUltrasonicDirectory = UApp.applicationContext().getExternalFilesDir(null)!! return cachedUltrasonicDirectory!! } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LocaleHelper.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LocaleHelper.kt index 01bb3b74..697ddf85 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LocaleHelper.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LocaleHelper.kt @@ -25,11 +25,7 @@ class LocaleHelper(base: Context?) : ContextWrapper(base) { val config = context.resources.configuration val locale = Locale.forLanguageTag(language) Locale.setDefault(locale) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - setSystemLocale(config, locale) - } else { - setSystemLocaleLegacy(config, locale) - } + setSystemLocale(config, locale) config.setLayoutDirection(locale) context = context.createConfigurationContext(config) @@ -37,13 +33,7 @@ class LocaleHelper(base: Context?) : ContextWrapper(base) { return LocaleHelper(context) } - @Suppress("DEPRECATION") - private fun setSystemLocaleLegacy(config: Configuration, locale: Locale?) { - config.locale = locale - } - - @RequiresApi(Build.VERSION_CODES.N) - fun setSystemLocale(config: Configuration, locale: Locale?) { + private fun setSystemLocale(config: Configuration, locale: Locale?) { config.setLocale(locale) } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/SelectCacheActivityContract.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/SelectCacheActivityContract.kt index 88437aca..dc25245f 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/SelectCacheActivityContract.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/SelectCacheActivityContract.kt @@ -19,7 +19,7 @@ import org.moire.ultrasonic.fragment.SettingsFragment class SelectCacheActivityContract : ActivityResultContract() { override fun createIntent(context: Context, input: String?): Intent { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) - if (Settings.cacheLocationUri != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Settings.cacheLocationUri != "") { intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, input) } intent.addFlags(SettingsFragment.RW_FLAG) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ShortcutUtil.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ShortcutUtil.kt index 7034d75b..3c6a416a 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ShortcutUtil.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ShortcutUtil.kt @@ -18,7 +18,6 @@ import org.moire.ultrasonic.R import org.moire.ultrasonic.activity.NavigationActivity object ShortcutUtil { - @RequiresApi(Build.VERSION_CODES.N_MR1) fun registerShortcuts(activity: Activity) { val shortcutIntent = Intent(activity, NavigationActivity::class.java).apply { action = Constants.INTENT_PLAY_RANDOM_SONGS diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt index 227871b3..94ba5679 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt @@ -303,16 +303,14 @@ object Util { private fun isNetworkMetered(): Boolean { val connManager = connectivityManager - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val capabilities = connManager.getNetworkCapabilities( - connManager.activeNetwork - ) - if (capabilities != null && - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) - ) { - return false - } + val capabilities = connManager.getNetworkCapabilities( + connManager.activeNetwork + ) + if (capabilities != null && + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) + ) { + return false } return connManager.isActiveNetworkMetered } @@ -320,21 +318,13 @@ object Util { @Suppress("DEPRECATION") private fun isNetworkCellular(): Boolean { val connManager = connectivityManager - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val network = connManager.activeNetwork - ?: return false // Nothing connected - connManager.getNetworkInfo(network) - ?: return true // Better be safe than sorry - val capabilities = connManager.getNetworkCapabilities(network) - ?: return true // Better be safe than sorry - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) - } else { - // if the default network is a VPN, - // this method will return the NetworkInfo for one of its underlying networks - val info = connManager.activeNetworkInfo - ?: return false // Nothing connected - info.type == ConnectivityManager.TYPE_MOBILE - } + val network = connManager.activeNetwork + ?: return false // Nothing connected + connManager.getNetworkInfo(network) + ?: return true // Better be safe than sorry + val capabilities = connManager.getNetworkCapabilities(network) + ?: return true // Better be safe than sorry + return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) } @JvmStatic @@ -502,20 +492,18 @@ object Util { importance: Int? = null, notificationManager: NotificationManagerCompat ) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - // The suggested importance of a startForeground service notification is IMPORTANCE_LOW - val channel = NotificationChannel( - id, - name, - importance ?: NotificationManager.IMPORTANCE_DEFAULT - ) + // The suggested importance of a startForeground service notification is IMPORTANCE_LOW + val channel = NotificationChannel( + id, + name, + importance ?: NotificationManager.IMPORTANCE_DEFAULT + ) - channel.lightColor = android.R.color.holo_blue_dark - channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC - channel.setShowBadge(false) + channel.lightColor = android.R.color.holo_blue_dark + channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC + channel.setShowBadge(false) - notificationManager.createNotificationChannel(channel) - } + notificationManager.createNotificationChannel(channel) } fun ensurePermissionToPostNotification( @@ -773,10 +761,8 @@ object Util { val intent = Intent(context, NavigationActivity::class.java) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) var flags = PendingIntent.FLAG_UPDATE_CURRENT - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - // needed starting Android 12 (S = 31) - flags = flags or PendingIntent.FLAG_IMMUTABLE - } + // needed starting Android 12 (S = 31) + flags = flags or PendingIntent.FLAG_IMMUTABLE intent.putExtra(Constants.INTENT_SHOW_PLAYER, true) return PendingIntent.getActivity(context, 0, intent, flags) } @@ -809,12 +795,7 @@ object Util { } fun Service.stopForegroundRemoveNotification() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - stopForeground(STOP_FOREGROUND_REMOVE) - } else { - @Suppress("DEPRECATION") - stopForeground(true) - } + stopForeground(STOP_FOREGROUND_REMOVE) } fun dumpSettingsToLog() { diff --git a/ultrasonic/src/main/res/layout/chat.xml b/ultrasonic/src/main/res/layout/chat.xml index fc4f447f..bc77c5fa 100644 --- a/ultrasonic/src/main/res/layout/chat.xml +++ b/ultrasonic/src/main/res/layout/chat.xml @@ -32,6 +32,7 @@ a:gravity="bottom" > - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ultrasonic/src/main/res/menu/rating.xml b/ultrasonic/src/main/res/menu/rating.xml index 1a58492b..9efb8af0 100644 --- a/ultrasonic/src/main/res/menu/rating.xml +++ b/ultrasonic/src/main/res/menu/rating.xml @@ -10,31 +10,37 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/ultrasonic/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/ultrasonic/src/main/res/mipmap-anydpi/ic_launcher.xml similarity index 100% rename from ultrasonic/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to ultrasonic/src/main/res/mipmap-anydpi/ic_launcher.xml diff --git a/ultrasonic/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/ultrasonic/src/main/res/mipmap-anydpi/ic_launcher_round.xml similarity index 100% rename from ultrasonic/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to ultrasonic/src/main/res/mipmap-anydpi/ic_launcher_round.xml diff --git a/ultrasonic/src/main/res/mipmap-hdpi/ic_launcher.png b/ultrasonic/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index c5d13007..00000000 Binary files a/ultrasonic/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-hdpi/ic_launcher_round.png b/ultrasonic/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 14f0810c..00000000 Binary files a/ultrasonic/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-mdpi/ic_launcher.png b/ultrasonic/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 42a18c46..00000000 Binary files a/ultrasonic/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-mdpi/ic_launcher_round.png b/ultrasonic/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 1b04252e..00000000 Binary files a/ultrasonic/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-xhdpi/ic_launcher.png b/ultrasonic/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index dc8eb47a..00000000 Binary files a/ultrasonic/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/ultrasonic/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 5f663df0..00000000 Binary files a/ultrasonic/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-xxhdpi/ic_launcher.png b/ultrasonic/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 4d4230eb..00000000 Binary files a/ultrasonic/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/ultrasonic/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 6f0f94eb..00000000 Binary files a/ultrasonic/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/ultrasonic/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index cb11421e..00000000 Binary files a/ultrasonic/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/ultrasonic/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/ultrasonic/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 5af1f877..00000000 Binary files a/ultrasonic/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ