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 8ed8c8bc..443106f6 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
@@ -210,6 +213,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)
+ }
}
override fun onResume() {
@@ -368,6 +377,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 @@
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
+ Random songs
+ Play random songs