Tweak SDK version check and start activity for result related code
This commit is contained in:
parent
1bdc120430
commit
1221ddf424
10 changed files with 113 additions and 116 deletions
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
Intent(Intent.ACTION_WEB_SEARCH).apply {
|
context.startActivity(
|
||||||
putExtra(
|
Intent(Intent.ACTION_WEB_SEARCH).apply {
|
||||||
SearchManager.QUERY,
|
putExtra(
|
||||||
"${mediaMetadata.title} ${mediaMetadata.artist} lyrics"
|
SearchManager.QUERY,
|
||||||
)
|
"${mediaMetadata.title} ${mediaMetadata.artist} lyrics"
|
||||||
}
|
)
|
||||||
|
}
|
||||||
if (intent.resolveActivity(context.packageManager) != null) {
|
)
|
||||||
context.startActivity(intent)
|
} catch (e: ActivityNotFoundException) {
|
||||||
} else {
|
context.toast("Couldn't find an application to browse the Internet")
|
||||||
Toast
|
|
||||||
.makeText(
|
|
||||||
context,
|
|
||||||
"No browser app found!",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
)
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -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 {
|
||||||
putExtra(AudioEffect.EXTRA_AUDIO_SESSION, binder.player.audioSessionId)
|
activityResultLauncher.launch(
|
||||||
putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
|
Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply {
|
||||||
putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
|
putExtra(AudioEffect.EXTRA_AUDIO_SESSION, binder.player.audioSessionId)
|
||||||
}
|
putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
|
||||||
|
putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
|
||||||
if (intent.resolveActivity(context.packageManager) != null) {
|
}
|
||||||
val contract = ActivityResultContracts.StartActivityForResult()
|
)
|
||||||
|
} catch (e: ActivityNotFoundException) {
|
||||||
resultRegistryOwner?.activityResultRegistry
|
context.toast("Couldn't find an application to equalize audio")
|
||||||
?.register("", contract) {}?.launch(intent)
|
|
||||||
} else {
|
|
||||||
Toast.makeText(context, "No equalizer app found!", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShowSleepTimer = {},
|
onShowSleepTimer = {},
|
||||||
|
|
|
@ -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")
|
||||||
backupLauncher.launch("vimusic_${dateFormat.format(Date())}.db")
|
|
||||||
|
try {
|
||||||
|
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"
|
}
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
)
|
||||||
|
} catch (e: ActivityNotFoundException) {
|
||||||
if (fallbackIntent.resolveActivity(context.packageManager) != null) {
|
context.toast("Couldn't find battery optimization settings, please whitelist ViMusic manually")
|
||||||
activityResultLauncher.launch(fallbackIntent)
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
context,
|
|
||||||
"Couldn't find battery optimization settings, please whitelist ViMusic manually",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
|
||||||
AudioEffect.EXTRA_AUDIO_SESSION,
|
putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
|
||||||
binder?.player?.audioSessionId
|
}
|
||||||
)
|
|
||||||
putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
|
|
||||||
putExtra(
|
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue