Tweak SDK version check and start activity for result related code

This commit is contained in:
vfsfitvnm 2022-10-23 21:56:14 +02:00
parent 1bdc120430
commit 1221ddf424
10 changed files with 113 additions and 116 deletions

View file

@ -6,7 +6,6 @@ import android.content.Intent
import android.content.ServiceConnection import android.content.ServiceConnection
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Bitmap import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import android.widget.Toast import android.widget.Toast
@ -86,6 +85,8 @@ import it.vfsfitvnm.vimusic.utils.colorPaletteNameKey
import it.vfsfitvnm.vimusic.utils.forcePlay import it.vfsfitvnm.vimusic.utils.forcePlay
import it.vfsfitvnm.vimusic.utils.getEnum import it.vfsfitvnm.vimusic.utils.getEnum
import it.vfsfitvnm.vimusic.utils.intent import it.vfsfitvnm.vimusic.utils.intent
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid8
import it.vfsfitvnm.vimusic.utils.preferences import it.vfsfitvnm.vimusic.utils.preferences
import it.vfsfitvnm.vimusic.utils.thumbnailRoundnessKey import it.vfsfitvnm.vimusic.utils.thumbnailRoundnessKey
import it.vfsfitvnm.vimusic.utils.useSystemFontKey import it.vfsfitvnm.vimusic.utils.useSystemFontKey
@ -453,12 +454,12 @@ class MainActivity : ComponentActivity() {
isAppearanceLightNavigationBars = !isDark isAppearanceLightNavigationBars = !isDark
} }
if (Build.VERSION.SDK_INT < 23) { if (!isAtLeastAndroid6) {
window.statusBarColor = window.statusBarColor =
(if (isDark) Color.Transparent else Color.Black.copy(alpha = 0.2f)).toArgb() (if (isDark) Color.Transparent else Color.Black.copy(alpha = 0.2f)).toArgb()
} }
if (Build.VERSION.SDK_INT < 26) { if (!isAtLeastAndroid8) {
window.navigationBarColor = window.navigationBarColor =
(if (isDark) Color.Transparent else Color.Black.copy(alpha = 0.2f)).toArgb() (if (isDark) Color.Transparent else Color.Black.copy(alpha = 0.2f)).toArgb()
} }

View file

@ -24,7 +24,6 @@ import android.media.audiofx.AudioEffect
import android.media.session.MediaSession import android.media.session.MediaSession
import android.media.session.PlaybackState import android.media.session.PlaybackState
import android.net.Uri import android.net.Uri
import android.os.Build
import android.os.Handler import android.os.Handler
import android.text.format.DateUtils import android.text.format.DateUtils
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -93,6 +92,7 @@ import it.vfsfitvnm.vimusic.utils.getEnum
import it.vfsfitvnm.vimusic.utils.intent import it.vfsfitvnm.vimusic.utils.intent
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid13 import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid13
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6 import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid8
import it.vfsfitvnm.vimusic.utils.isInvincibilityEnabledKey import it.vfsfitvnm.vimusic.utils.isInvincibilityEnabledKey
import it.vfsfitvnm.vimusic.utils.isShowingThumbnailInLockscreenKey import it.vfsfitvnm.vimusic.utils.isShowingThumbnailInLockscreenKey
import it.vfsfitvnm.vimusic.utils.mediaItems import it.vfsfitvnm.vimusic.utils.mediaItems
@ -659,7 +659,7 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
val mediaMetadata = player.mediaMetadata val mediaMetadata = player.mediaMetadata
val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val builder = if (isAtLeastAndroid8) {
Notification.Builder(applicationContext, NotificationChannelId) Notification.Builder(applicationContext, NotificationChannelId)
} else { } else {
Notification.Builder(applicationContext) Notification.Builder(applicationContext)
@ -706,7 +706,7 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
private fun createNotificationChannel() { private fun createNotificationChannel() {
notificationManager = getSystemService() notificationManager = getSystemService()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return if (!isAtLeastAndroid8) return
notificationManager?.run { notificationManager?.run {
if (getNotificationChannel(NotificationChannelId) == null) { if (getNotificationChannel(NotificationChannelId) == null) {
@ -987,7 +987,7 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
this@Context, this@Context,
100, 100,
Intent(value).setPackage(packageName), Intent(value).setPackage(packageName),
PendingIntent.FLAG_UPDATE_CURRENT.or(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0) PendingIntent.FLAG_UPDATE_CURRENT.or(if (isAtLeastAndroid6) PendingIntent.FLAG_IMMUTABLE else 0)
) )
companion object { companion object {

View file

@ -1,8 +1,8 @@
package it.vfsfitvnm.vimusic.ui.screens.player package it.vfsfitvnm.vimusic.ui.screens.player
import android.app.SearchManager import android.app.SearchManager
import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
@ -45,6 +45,9 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.media3.common.C import androidx.media3.common.C
import androidx.media3.common.MediaMetadata import androidx.media3.common.MediaMetadata
import it.vfsfitvnm.innertube.Innertube
import it.vfsfitvnm.innertube.models.bodies.NextBody
import it.vfsfitvnm.innertube.requests.lyrics
import it.vfsfitvnm.kugou.KuGou import it.vfsfitvnm.kugou.KuGou
import it.vfsfitvnm.vimusic.Database import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
@ -67,10 +70,8 @@ import it.vfsfitvnm.vimusic.utils.isShowingSynchronizedLyricsKey
import it.vfsfitvnm.vimusic.utils.medium import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.produceSaveableState import it.vfsfitvnm.vimusic.utils.produceSaveableState
import it.vfsfitvnm.vimusic.utils.rememberPreference import it.vfsfitvnm.vimusic.utils.rememberPreference
import it.vfsfitvnm.vimusic.utils.toast
import it.vfsfitvnm.vimusic.utils.verticalFadingEdge import it.vfsfitvnm.vimusic.utils.verticalFadingEdge
import it.vfsfitvnm.innertube.Innertube
import it.vfsfitvnm.innertube.models.bodies.NextBody
import it.vfsfitvnm.innertube.requests.lyrics
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@ -327,24 +328,17 @@ fun Lyrics(
menuState.hide() menuState.hide()
val mediaMetadata = mediaMetadataProvider() val mediaMetadata = mediaMetadataProvider()
val intent = try {
context.startActivity(
Intent(Intent.ACTION_WEB_SEARCH).apply { Intent(Intent.ACTION_WEB_SEARCH).apply {
putExtra( putExtra(
SearchManager.QUERY, SearchManager.QUERY,
"${mediaMetadata.title} ${mediaMetadata.artist} lyrics" "${mediaMetadata.title} ${mediaMetadata.artist} lyrics"
) )
} }
if (intent.resolveActivity(context.packageManager) != null) {
context.startActivity(intent)
} else {
Toast
.makeText(
context,
"No browser app found!",
Toast.LENGTH_SHORT
) )
.show() } catch (e: ActivityNotFoundException) {
context.toast("Couldn't find an application to browse the Internet")
} }
} }
) )

View file

@ -1,9 +1,9 @@
package it.vfsfitvnm.vimusic.ui.screens.player package it.vfsfitvnm.vimusic.ui.screens.player
import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.media.audiofx.AudioEffect import android.media.audiofx.AudioEffect
import android.widget.Toast import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.LocalActivityResultRegistryOwner
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
@ -70,6 +70,7 @@ import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.shouldBePlaying import it.vfsfitvnm.vimusic.utils.shouldBePlaying
import it.vfsfitvnm.vimusic.utils.thumbnail import it.vfsfitvnm.vimusic.utils.thumbnail
import it.vfsfitvnm.vimusic.utils.toast
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
@ExperimentalFoundationApi @ExperimentalFoundationApi
@ -382,7 +383,9 @@ private fun PlayerMenu(
onDismiss: () -> Unit onDismiss: () -> Unit
) { ) {
val context = LocalContext.current val context = LocalContext.current
val resultRegistryOwner = LocalActivityResultRegistryOwner.current
val activityResultLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { }
BaseMediaItemMenu( BaseMediaItemMenu(
mediaItem = mediaItem, mediaItem = mediaItem,
@ -392,19 +395,16 @@ private fun PlayerMenu(
binder.setupRadio(NavigationEndpoint.Endpoint.Watch(videoId = mediaItem.mediaId)) binder.setupRadio(NavigationEndpoint.Endpoint.Watch(videoId = mediaItem.mediaId))
}, },
onGoToEqualizer = { onGoToEqualizer = {
val intent = Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply { try {
activityResultLauncher.launch(
Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply {
putExtra(AudioEffect.EXTRA_AUDIO_SESSION, binder.player.audioSessionId) putExtra(AudioEffect.EXTRA_AUDIO_SESSION, binder.player.audioSessionId)
putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName) putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC) putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
} }
)
if (intent.resolveActivity(context.packageManager) != null) { } catch (e: ActivityNotFoundException) {
val contract = ActivityResultContracts.StartActivityForResult() context.toast("Couldn't find an application to equalize audio")
resultRegistryOwner?.activityResultRegistry
?.register("", contract) {}?.launch(intent)
} else {
Toast.makeText(context, "No equalizer app found!", Toast.LENGTH_SHORT).show()
} }
}, },
onShowSleepTimer = {}, onShowSleepTimer = {},

View file

@ -1,6 +1,7 @@
package it.vfsfitvnm.vimusic.ui.screens.settings package it.vfsfitvnm.vimusic.ui.screens.settings
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
@ -28,14 +29,15 @@ import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.intent import it.vfsfitvnm.vimusic.utils.intent
import it.vfsfitvnm.vimusic.utils.produceSaveableState import it.vfsfitvnm.vimusic.utils.produceSaveableState
import kotlinx.coroutines.Dispatchers import it.vfsfitvnm.vimusic.utils.toast
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import kotlin.system.exitProcess import kotlin.system.exitProcess
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
@ExperimentalAnimationApi @ExperimentalAnimationApi
@Composable @Composable
@ -124,7 +126,12 @@ fun DatabaseSettings() {
onClick = { onClick = {
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
val dateFormat = SimpleDateFormat("yyyyMMddHHmmss") val dateFormat = SimpleDateFormat("yyyyMMddHHmmss")
try {
backupLauncher.launch("vimusic_${dateFormat.format(Date())}.db") backupLauncher.launch("vimusic_${dateFormat.format(Date())}.db")
} catch (e: ActivityNotFoundException) {
context.toast("Couldn't find an application to create documents")
}
} }
) )
@ -138,13 +145,11 @@ fun DatabaseSettings() {
title = "Restore", title = "Restore",
text = "Import the database from the external storage", text = "Import the database from the external storage",
onClick = { onClick = {
restoreLauncher.launch( try {
arrayOf( restoreLauncher.launch(arrayOf("application/vnd.sqlite3"))
"application/x-sqlite3", } catch (e: ActivityNotFoundException) {
"application/vnd.sqlite3", context.toast("Couldn't find an application to open documents")
"application/octet-stream" }
)
)
} }
) )
} }

View file

@ -1,49 +1,52 @@
package it.vfsfitvnm.vimusic.ui.screens.settings package it.vfsfitvnm.vimusic.ui.screens.settings
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.ComponentName import android.content.ComponentName
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Build
import android.provider.Settings import android.provider.Settings
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.SnapshotMutationPolicy
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.autoSaver
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.only
import androidx.compose.runtime.SnapshotMutationPolicy
import androidx.compose.runtime.saveable.autoSaver
import it.vfsfitvnm.vimusic.Database import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import it.vfsfitvnm.vimusic.query import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.service.PlayerMediaBrowserService import it.vfsfitvnm.vimusic.service.PlayerMediaBrowserService
import it.vfsfitvnm.vimusic.ui.components.themed.Header import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid12
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6
import it.vfsfitvnm.vimusic.utils.isIgnoringBatteryOptimizations import it.vfsfitvnm.vimusic.utils.isIgnoringBatteryOptimizations
import it.vfsfitvnm.vimusic.utils.isInvincibilityEnabledKey import it.vfsfitvnm.vimusic.utils.isInvincibilityEnabledKey
import it.vfsfitvnm.vimusic.utils.pauseSearchHistoryKey import it.vfsfitvnm.vimusic.utils.pauseSearchHistoryKey
import it.vfsfitvnm.vimusic.utils.produceSaveableState import it.vfsfitvnm.vimusic.utils.produceSaveableState
import it.vfsfitvnm.vimusic.utils.rememberPreference import it.vfsfitvnm.vimusic.utils.rememberPreference
import it.vfsfitvnm.vimusic.utils.toast
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
@SuppressLint("BatteryLife")
@ExperimentalAnimationApi @ExperimentalAnimationApi
@Composable @Composable
fun OtherSettings() { fun OtherSettings() {
@ -142,7 +145,7 @@ fun OtherSettings() {
ImportantSettingsDescription(text = "If battery optimizations are applied, the playback notification can suddenly disappear when paused.") ImportantSettingsDescription(text = "If battery optimizations are applied, the playback notification can suddenly disappear when paused.")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (isAtLeastAndroid12) {
SettingsDescription(text = "Since Android 12, disabling battery optimizations is required for the \"Invincible service\" option to take effect.") SettingsDescription(text = "Since Android 12, disabling battery optimizations is required for the \"Invincible service\" option to take effect.")
} }
@ -155,28 +158,21 @@ fun OtherSettings() {
"Disable background restrictions" "Disable background restrictions"
}, },
onClick = { onClick = {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return@SettingsEntry if (!isAtLeastAndroid6) return@SettingsEntry
@SuppressLint("BatteryLife") try {
val intent = activityResultLauncher.launch(
Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
data = Uri.parse("package:${context.packageName}") data = Uri.parse("package:${context.packageName}")
} }
)
if (intent.resolveActivity(context.packageManager) != null) { } catch (e: ActivityNotFoundException) {
activityResultLauncher.launch(intent) try {
} else { activityResultLauncher.launch(
val fallbackIntent =
Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)
)
if (fallbackIntent.resolveActivity(context.packageManager) != null) { } catch (e: ActivityNotFoundException) {
activityResultLauncher.launch(fallbackIntent) context.toast("Couldn't find battery optimization settings, please whitelist ViMusic manually")
} else {
Toast.makeText(
context,
"Couldn't find battery optimization settings, please whitelist ViMusic manually",
Toast.LENGTH_SHORT
).show()
} }
} }
} }

View file

@ -1,14 +1,17 @@
package it.vfsfitvnm.vimusic.ui.screens.settings package it.vfsfitvnm.vimusic.ui.screens.settings
import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.media.audiofx.AudioEffect import android.media.audiofx.AudioEffect
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@ -18,18 +21,15 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets import it.vfsfitvnm.vimusic.LocalPlayerAwareWindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.only
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.ui.components.themed.Header import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid13
import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6 import it.vfsfitvnm.vimusic.utils.isAtLeastAndroid6
import it.vfsfitvnm.vimusic.utils.persistentQueueKey import it.vfsfitvnm.vimusic.utils.persistentQueueKey
import it.vfsfitvnm.vimusic.utils.rememberPreference import it.vfsfitvnm.vimusic.utils.rememberPreference
import it.vfsfitvnm.vimusic.utils.resumePlaybackWhenDeviceConnectedKey import it.vfsfitvnm.vimusic.utils.resumePlaybackWhenDeviceConnectedKey
import it.vfsfitvnm.vimusic.utils.skipSilenceKey import it.vfsfitvnm.vimusic.utils.skipSilenceKey
import it.vfsfitvnm.vimusic.utils.toast
import it.vfsfitvnm.vimusic.utils.volumeNormalizationKey import it.vfsfitvnm.vimusic.utils.volumeNormalizationKey
@ExperimentalAnimationApi @ExperimentalAnimationApi
@ -40,13 +40,15 @@ fun PlayerSettings() {
val binder = LocalPlayerServiceBinder.current val binder = LocalPlayerServiceBinder.current
var persistentQueue by rememberPreference(persistentQueueKey, false) var persistentQueue by rememberPreference(persistentQueueKey, false)
var resumePlaybackWhenDeviceConnected by rememberPreference(resumePlaybackWhenDeviceConnectedKey, false) var resumePlaybackWhenDeviceConnected by rememberPreference(
resumePlaybackWhenDeviceConnectedKey,
false
)
var skipSilence by rememberPreference(skipSilenceKey, false) var skipSilence by rememberPreference(skipSilenceKey, false)
var volumeNormalization by rememberPreference(volumeNormalizationKey, false) var volumeNormalization by rememberPreference(volumeNormalizationKey, false)
val activityResultLauncher = val activityResultLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { }
}
Column( Column(
modifier = Modifier modifier = Modifier
@ -109,24 +111,16 @@ fun PlayerSettings() {
title = "Equalizer", title = "Equalizer",
text = "Interact with the system equalizer", text = "Interact with the system equalizer",
onClick = { onClick = {
val intent = val intent = Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply {
Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply { putExtra(AudioEffect.EXTRA_AUDIO_SESSION, binder?.player?.audioSessionId)
putExtra(
AudioEffect.EXTRA_AUDIO_SESSION,
binder?.player?.audioSessionId
)
putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName) putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
putExtra( putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
AudioEffect.EXTRA_CONTENT_TYPE,
AudioEffect.CONTENT_TYPE_MUSIC
)
} }
if (intent.resolveActivity(context.packageManager) != null) { try {
activityResultLauncher.launch(intent) activityResultLauncher.launch(intent)
} else { } catch (e: ActivityNotFoundException) {
Toast.makeText(context, "No equalizer app found!", Toast.LENGTH_SHORT) context.toast("Couldn't find an application to equalize audio")
.show()
} }
} }
) )

View file

@ -5,8 +5,8 @@ import android.app.PendingIntent
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import android.os.PowerManager import android.os.PowerManager
import android.widget.Toast
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
inline fun <reified T> Context.intent(): Intent = inline fun <reified T> Context.intent(): Intent =
@ -14,7 +14,7 @@ inline fun <reified T> Context.intent(): Intent =
inline fun <reified T : BroadcastReceiver> Context.broadCastPendingIntent( inline fun <reified T : BroadcastReceiver> Context.broadCastPendingIntent(
requestCode: Int = 0, requestCode: Int = 0,
flags: Int = if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0, flags: Int = if (isAtLeastAndroid6) PendingIntent.FLAG_IMMUTABLE else 0,
): PendingIntent = ): PendingIntent =
PendingIntent.getBroadcast(this, requestCode, intent<T>(), flags) PendingIntent.getBroadcast(this, requestCode, intent<T>(), flags)
@ -27,12 +27,14 @@ inline fun <reified T : Activity> Context.activityPendingIntent(
this, this,
requestCode, requestCode,
intent<T>().apply(block), intent<T>().apply(block),
(if (Build.VERSION.SDK_INT >= 23) PendingIntent.FLAG_IMMUTABLE else 0) or flags (if (isAtLeastAndroid6) PendingIntent.FLAG_IMMUTABLE else 0) or flags
) )
val Context.isIgnoringBatteryOptimizations: Boolean val Context.isIgnoringBatteryOptimizations: Boolean
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { get() = if (isAtLeastAndroid6) {
getSystemService<PowerManager>()?.isIgnoringBatteryOptimizations(packageName) ?: true getSystemService<PowerManager>()?.isIgnoringBatteryOptimizations(packageName) ?: true
} else { } else {
true true
} }
fun Context.toast(message: String) = Toast.makeText(this, message, Toast.LENGTH_SHORT).show()

View file

@ -7,7 +7,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.os.Binder import android.os.Binder
import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
@ -28,7 +27,7 @@ abstract class InvincibleService : Service() {
private var invincibility: Invincibility? = null private var invincibility: Invincibility? = null
private val isAllowedToStartForegroundServices: Boolean private val isAllowedToStartForegroundServices: Boolean
get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.S || isIgnoringBatteryOptimizations get() = !isAtLeastAndroid12 || isIgnoringBatteryOptimizations
override fun onBind(intent: Intent?): Binder? { override fun onBind(intent: Intent?): Binder? {
invincibility?.stop() invincibility?.stop()

View file

@ -116,5 +116,11 @@ suspend fun Result<Innertube.PlaylistOrAlbumPage>.completed(): Result<Innertube.
inline val isAtLeastAndroid6 inline val isAtLeastAndroid6
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
inline val isAtLeastAndroid8
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
inline val isAtLeastAndroid12
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
inline val isAtLeastAndroid13 inline val isAtLeastAndroid13
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU