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 51c75e79..24d0d95a 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt @@ -56,13 +56,16 @@ import org.moire.ultrasonic.model.ServerSettingsModel import org.moire.ultrasonic.provider.SearchSuggestionProvider import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport import org.moire.ultrasonic.service.MediaPlayerManager +import org.moire.ultrasonic.service.MusicServiceFactory import org.moire.ultrasonic.service.RxBus import org.moire.ultrasonic.service.plusAssign +import org.moire.ultrasonic.subsonic.DownloadHandler import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.InfoDialog import org.moire.ultrasonic.util.LocaleHelper import org.moire.ultrasonic.util.ServerColor import org.moire.ultrasonic.util.Settings +import org.moire.ultrasonic.util.ShortcutUtil import org.moire.ultrasonic.util.Storage import org.moire.ultrasonic.util.UncaughtExceptionHandler import org.moire.ultrasonic.util.Util @@ -212,6 +215,12 @@ class NavigationActivity : AppCompatActivity() { cachedServerCount = count ?: 0 updateNavigationHeaderForServer() } + + // 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) { + ShortcutUtil.registerShortcuts(this) + } } private fun setupDrawerLayout(drawerLayout: DrawerLayout) { @@ -389,6 +398,23 @@ class NavigationActivity : AppCompatActivity() { super.onNewIntent(intent) if (intent == null) return + if (intent.action == Constants.INTENT_PLAY_RANDOM_SONGS) { + val currentFragment = host?.childFragmentManager?.fragments?.last() ?: return + val service = MusicServiceFactory.getMusicService() + val musicDirectory = service.getRandomSongs(Settings.maxSongs) + val downloadHandler: DownloadHandler by inject() + downloadHandler.addTracksToMediaController( + songs = musicDirectory.getTracks(), + append = false, + playNext = false, + autoPlay = true, + shuffle = false, + fragment = currentFragment, + playlistName = null + ) + return + } + if (intent.getBooleanExtra(Constants.INTENT_SHOW_PLAYER, false)) { findNavController(R.id.nav_host_fragment).navigate(R.id.playerFragment) return diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Constants.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Constants.kt index 351de91c..1db5cffe 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Constants.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Constants.kt @@ -25,6 +25,7 @@ object Constants { const val CMD_PREVIOUS = "org.moire.ultrasonic.CMD_PREVIOUS" const val CMD_NEXT = "org.moire.ultrasonic.CMD_NEXT" const val INTENT_SHOW_PLAYER = "org.moire.ultrasonic.SHOW_PLAYER" + const val INTENT_PLAY_RANDOM_SONGS = "org.moire.ultrasonic.CMD_RANDOM_SONGS" // Legacy Preferences keys // Warning: Don't add any new here! diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ShortcutUtil.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ShortcutUtil.kt new file mode 100644 index 00000000..7034d75b --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ShortcutUtil.kt @@ -0,0 +1,37 @@ +/* + * ShortcutUtil.kt + * Copyright (C) 2009-2023 Ultrasonic developers + * + * Distributed under terms of the GNU GPLv3 license. + */ + +package org.moire.ultrasonic.util + +import android.app.Activity +import android.content.Intent +import android.content.pm.ShortcutInfo +import android.content.pm.ShortcutManager +import android.graphics.drawable.Icon +import android.os.Build +import androidx.annotation.RequiresApi +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 + } + + val shortcut = ShortcutInfo.Builder(activity, "shortcut_play_random_songs") + .setShortLabel(activity.getString(R.string.shortcut_play_random_songs_short)) + .setLongLabel(activity.getString(R.string.shortcut_play_random_songs_long)) + .setIcon(Icon.createWithResource(activity, R.drawable.media_shuffle)) + .setIntent(shortcutIntent) + .build() + + val shortcutManager = activity.getSystemService(ShortcutManager::class.java) + shortcutManager?.dynamicShortcuts = listOf(shortcut) + } +} diff --git a/ultrasonic/src/main/res/values/strings.xml b/ultrasonic/src/main/res/values/strings.xml index 4f888cbb..73763394 100644 --- a/ultrasonic/src/main/res/values/strings.xml +++ b/ultrasonic/src/main/res/values/strings.xml @@ -456,6 +456,8 @@ <string name="foreground_exception_text">Press on the play button on the media notification if it is still present, otherwise please open the app to start the playback and re-connect the session to the controller</string> + <string name="shortcut_play_random_songs_short">Random songs</string> + <string name="shortcut_play_random_songs_long">Play random songs</string> </resources>