Browse Source

Merge pull request #7340 from nextcloud/foregroundServiceCrash

Directly start foreground service
Andy Scherzinger 4 years ago
parent
commit
9a80066f9f

+ 37 - 5
src/main/java/com/nextcloud/client/media/PlayerService.kt

@@ -35,7 +35,7 @@ import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.ui.notifications.NotificationUtils
 import com.owncloud.android.ui.notifications.NotificationUtils
 import com.owncloud.android.utils.ThemeUtils
 import com.owncloud.android.utils.ThemeUtils
 import dagger.android.AndroidInjection
 import dagger.android.AndroidInjection
-import java.lang.IllegalArgumentException
+import java.util.Locale
 import javax.inject.Inject
 import javax.inject.Inject
 
 
 class PlayerService : Service() {
 class PlayerService : Service() {
@@ -47,6 +47,7 @@ class PlayerService : Service() {
         const val EXTRA_START_POSITION_MS = "START_POSITION_MS"
         const val EXTRA_START_POSITION_MS = "START_POSITION_MS"
         const val ACTION_PLAY = "PLAY"
         const val ACTION_PLAY = "PLAY"
         const val ACTION_STOP = "STOP"
         const val ACTION_STOP = "STOP"
+        const val ACTION_TOGGLE = "TOGGLE"
         const val ACTION_STOP_FILE = "STOP_FILE"
         const val ACTION_STOP_FILE = "STOP_FILE"
     }
     }
 
 
@@ -74,7 +75,7 @@ class PlayerService : Service() {
         }
         }
 
 
         override fun onStop() {
         override fun onStop() {
-            stopForeground(true)
+            stopServiceAndRemoveNotification(null)
         }
         }
 
 
         override fun onError(error: PlayerError) {
         override fun onError(error: PlayerError) {
@@ -97,10 +98,20 @@ class PlayerService : Service() {
         player = Player(applicationContext, clientFactory, playerListener, audioManager)
         player = Player(applicationContext, clientFactory, playerListener, audioManager)
         notificationBuilder = NotificationCompat.Builder(this)
         notificationBuilder = NotificationCompat.Builder(this)
         notificationBuilder.color = ThemeUtils.primaryColor(this)
         notificationBuilder.color = ThemeUtils.primaryColor(this)
+
         val stop = Intent(this, PlayerService::class.java)
         val stop = Intent(this, PlayerService::class.java)
         stop.action = ACTION_STOP
         stop.action = ACTION_STOP
         val pendingStop = PendingIntent.getService(this, 0, stop, 0)
         val pendingStop = PendingIntent.getService(this, 0, stop, 0)
-        notificationBuilder.addAction(0, "STOP", pendingStop)
+        notificationBuilder.addAction(0, getString(R.string.player_stop).toUpperCase(Locale.getDefault()), pendingStop)
+
+        val toggle = Intent(this, PlayerService::class.java)
+        toggle.action = ACTION_TOGGLE
+        val pendingToggle = PendingIntent.getService(this, 0, toggle, 0)
+        notificationBuilder.addAction(
+            0,
+            getString(R.string.player_toggle).toUpperCase(Locale.getDefault()),
+            pendingToggle
+        )
     }
     }
 
 
     override fun onBind(intent: Intent?): IBinder? {
     override fun onBind(intent: Intent?): IBinder? {
@@ -112,10 +123,19 @@ class PlayerService : Service() {
             ACTION_PLAY -> onActionPlay(intent)
             ACTION_PLAY -> onActionPlay(intent)
             ACTION_STOP -> onActionStop()
             ACTION_STOP -> onActionStop()
             ACTION_STOP_FILE -> onActionStopFile(intent.extras)
             ACTION_STOP_FILE -> onActionStopFile(intent.extras)
+            ACTION_TOGGLE -> onActionToggle()
         }
         }
         return START_NOT_STICKY
         return START_NOT_STICKY
     }
     }
 
 
+    private fun onActionToggle() {
+        if (player.isPlaying) {
+            player.pause()
+        } else {
+            player.start()
+        }
+    }
+
     private fun onActionPlay(intent: Intent) {
     private fun onActionPlay(intent: Intent) {
         val user: User = intent.getParcelableExtra(EXTRA_USER) as User
         val user: User = intent.getParcelableExtra(EXTRA_USER) as User
         val file: OCFile = intent.getParcelableExtra(EXTRA_FILE) as OCFile
         val file: OCFile = intent.getParcelableExtra(EXTRA_FILE) as OCFile
@@ -126,12 +146,13 @@ class PlayerService : Service() {
     }
     }
 
 
     private fun onActionStop() {
     private fun onActionStop() {
-        player.stop()
+        stopServiceAndRemoveNotification(null)
     }
     }
 
 
     private fun onActionStopFile(args: Bundle?) {
     private fun onActionStopFile(args: Bundle?) {
         val file: OCFile = args?.getParcelable(EXTRA_FILE) ?: throw IllegalArgumentException("Missing file argument")
         val file: OCFile = args?.getParcelable(EXTRA_FILE) ?: throw IllegalArgumentException("Missing file argument")
-        player.stop(file)
+
+        stopServiceAndRemoveNotification(file)
     }
     }
 
 
     private fun startForeground(currentFile: OCFile) {
     private fun startForeground(currentFile: OCFile) {
@@ -149,4 +170,15 @@ class PlayerService : Service() {
 
 
         startForeground(R.string.media_notif_ticker, notificationBuilder.build())
         startForeground(R.string.media_notif_ticker, notificationBuilder.build())
     }
     }
+
+    private fun stopServiceAndRemoveNotification(file: OCFile?) {
+        if (file == null) {
+            player.stop()
+        } else {
+            player.stop(file)
+        }
+
+        stopSelf()
+        stopForeground(true)
+    }
 }
 }

+ 7 - 2
src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.java

@@ -317,14 +317,19 @@ public class PreviewMediaFragment extends FileFragment implements OnTouchListene
         Log_OC.v(TAG, "onStart");
         Log_OC.v(TAG, "onStart");
         OCFile file = getFile();
         OCFile file = getFile();
         if (file != null) {
         if (file != null) {
+            // bind to any existing player
+            mMediaPlayerServiceConnection.bind();
+
             if (MimeTypeUtil.isAudio(file)) {
             if (MimeTypeUtil.isAudio(file)) {
                 mMediaController.setMediaPlayer(mMediaPlayerServiceConnection);
                 mMediaController.setMediaPlayer(mMediaPlayerServiceConnection);
-                mMediaPlayerServiceConnection.bind();
                 mMediaPlayerServiceConnection.start(user, file, mAutoplay, mSavedPlaybackPosition);
                 mMediaPlayerServiceConnection.start(user, file, mAutoplay, mSavedPlaybackPosition);
                 mMultiListContainer.setVisibility(View.GONE);
                 mMultiListContainer.setVisibility(View.GONE);
                 mPreviewContainer.setVisibility(View.VISIBLE);
                 mPreviewContainer.setVisibility(View.VISIBLE);
             } else if (MimeTypeUtil.isVideo(file)) {
             } else if (MimeTypeUtil.isVideo(file)) {
-                stopAudio();
+                if (mMediaPlayerServiceConnection.isConnected()) {
+                    // always stop player
+                    stopAudio();
+                }
                 playVideo();
                 playVideo();
             }
             }
         }
         }

+ 2 - 0
src/main/res/values/strings.xml

@@ -945,4 +945,6 @@
     <string name="fourHours">4 hours</string>
     <string name="fourHours">4 hours</string>
     <string name="thisWeek">This week</string>
     <string name="thisWeek">This week</string>
     <string name="drawer_item_gallery">Media</string>
     <string name="drawer_item_gallery">Media</string>
+    <string name="player_stop">stop</string>
+    <string name="player_toggle">toggle</string>
 </resources>
 </resources>