Skip to content

Commit a003a5c

Browse files
committed
fix(exo-player): crash
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent 1e805ed commit a003a5c

5 files changed

Lines changed: 101 additions & 51 deletions

File tree

app/src/main/java/com/nextcloud/client/media/BackgroundPlayerService.kt

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ import android.content.BroadcastReceiver
1313
import android.content.Context
1414
import android.content.Intent
1515
import android.content.IntentFilter
16+
import android.content.pm.ServiceInfo
17+
import android.os.Build
1618
import android.os.Bundle
1719
import androidx.annotation.OptIn
20+
import androidx.core.app.NotificationCompat
21+
import androidx.core.app.ServiceCompat
1822
import androidx.media3.common.Player
1923
import androidx.media3.common.Player.COMMAND_PLAY_PAUSE
2024
import androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT
@@ -45,6 +49,7 @@ import com.owncloud.android.MainApp
4549
import com.owncloud.android.R
4650
import com.owncloud.android.datamodel.ReceiverFlag
4751
import com.owncloud.android.lib.common.utils.Log_OC
52+
import com.owncloud.android.ui.notifications.NotificationUtils
4853
import kotlinx.coroutines.CoroutineScope
4954
import kotlinx.coroutines.Dispatchers
5055
import kotlinx.coroutines.SupervisorJob
@@ -81,6 +86,7 @@ class BackgroundPlayerService :
8186
override fun onReceive(context: Context?, intent: Intent?) {
8287
when (intent?.action) {
8388
RELEASE_MEDIA_SESSION_BROADCAST_ACTION -> release()
89+
8490
STOP_MEDIA_SESSION_BROADCAST_ACTION -> {
8591
if (isPlayerReady) {
8692
exoPlayer.stop()
@@ -92,6 +98,26 @@ class BackgroundPlayerService :
9298
}
9399
}
94100

101+
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
102+
val notification = NotificationCompat.Builder(this, NotificationUtils.NOTIFICATION_CHANNEL_MEDIA)
103+
.setSmallIcon(R.drawable.logo)
104+
.setContentTitle(getString(R.string.media_player_playing))
105+
.setSilent(true)
106+
.build()
107+
108+
ServiceCompat.startForeground(
109+
this,
110+
DefaultMediaNotificationProvider.DEFAULT_NOTIFICATION_ID,
111+
notification,
112+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
113+
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
114+
} else {
115+
0
116+
}
117+
)
118+
return super.onStartCommand(intent, flags, startId)
119+
}
120+
95121
@Suppress("DEPRECATION")
96122
override fun onCreate() {
97123
super.onCreate()
@@ -100,14 +126,14 @@ class BackgroundPlayerService :
100126

101127
seekForward = CommandButton.Builder()
102128
.setDisplayName(getString(R.string.media_player_seek_forward))
103-
.setIconResId(CommandButton.getIconResIdForIconConstant(CommandButton.ICON_SKIP_FORWARD_15))
129+
.setIconResId(R.drawable.ic_skip_next)
104130
.setSessionCommand(seekForwardSessionCommand)
105131
.setExtras(Bundle().apply { putInt(COMMAND_KEY_COMPACT_VIEW_INDEX, 2) })
106132
.build()
107133

108134
seekBackward = CommandButton.Builder()
109135
.setDisplayName(getString(R.string.media_player_seek_backward))
110-
.setIconResId(CommandButton.getIconResIdForIconConstant(CommandButton.ICON_SKIP_BACK_15))
136+
.setIconResId(R.drawable.ic_skip_previous)
111137
.setSessionCommand(seekBackSessionCommand)
112138
.setExtras(Bundle().apply { putInt(COMMAND_KEY_COMPACT_VIEW_INDEX, 0) })
113139
.build()
@@ -129,6 +155,7 @@ class BackgroundPlayerService :
129155
initExoPlayer()
130156
}
131157

158+
@Suppress("TooGenericExceptionCaught")
132159
private fun initExoPlayer() {
133160
serviceScope.launch {
134161
try {
@@ -151,15 +178,12 @@ class BackgroundPlayerService :
151178
}
152179
}
153180

154-
private fun buildMediaSession(player: ExoPlayer): MediaSession =
155-
MediaSession.Builder(applicationContext, player)
156-
.setId(BACKGROUND_MEDIA_SESSION_ID)
157-
.setCustomLayout(listOf(seekBackward, seekForward))
158-
.setCallback(object : MediaSession.Callback {
159-
override fun onConnect(
160-
session: MediaSession,
161-
controller: MediaSession.ControllerInfo
162-
): ConnectionResult = AcceptedResultBuilder(mediaSession ?: session)
181+
private fun buildMediaSession(player: ExoPlayer): MediaSession = MediaSession.Builder(applicationContext, player)
182+
.setId(BACKGROUND_MEDIA_SESSION_ID)
183+
.setCustomLayout(listOf(seekBackward, seekForward))
184+
.setCallback(object : MediaSession.Callback {
185+
override fun onConnect(session: MediaSession, controller: MediaSession.ControllerInfo): ConnectionResult =
186+
AcceptedResultBuilder(mediaSession ?: session)
163187
.setAvailablePlayerCommands(
164188
ConnectionResult.DEFAULT_PLAYER_COMMANDS.buildUpon()
165189
.remove(COMMAND_SEEK_TO_NEXT)
@@ -176,56 +200,52 @@ class BackgroundPlayerService :
176200
)
177201
.build()
178202

179-
override fun onPostConnect(
180-
session: MediaSession,
181-
controller: MediaSession.ControllerInfo
182-
) {
183-
session.setCustomLayout(listOf(seekBackward, seekForward))
184-
}
185-
186-
override fun onCustomCommand(
187-
session: MediaSession,
188-
controller: MediaSession.ControllerInfo,
189-
customCommand: SessionCommand,
190-
args: Bundle
191-
): ListenableFuture<SessionResult> = when (customCommand.customAction) {
192-
SESSION_COMMAND_ACTION_SEEK_FORWARD -> {
193-
session.player.seekForward()
194-
Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
195-
}
203+
override fun onPostConnect(session: MediaSession, controller: MediaSession.ControllerInfo) {
204+
session.setCustomLayout(listOf(seekBackward, seekForward))
205+
}
196206

197-
SESSION_COMMAND_ACTION_SEEK_BACK -> {
198-
session.player.seekBack()
199-
Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
200-
}
207+
override fun onCustomCommand(
208+
session: MediaSession,
209+
controller: MediaSession.ControllerInfo,
210+
customCommand: SessionCommand,
211+
args: Bundle
212+
): ListenableFuture<SessionResult> = when (customCommand.customAction) {
213+
SESSION_COMMAND_ACTION_SEEK_FORWARD -> {
214+
session.player.seekForward()
215+
Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
216+
}
201217

202-
else -> super.onCustomCommand(session, controller, customCommand, args)
218+
SESSION_COMMAND_ACTION_SEEK_BACK -> {
219+
session.player.seekBack()
220+
Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
203221
}
204-
})
205-
.build()
206222

207-
private fun buildNotificationProvider() = object : DefaultMediaNotificationProvider(this) {
208-
val isPlaying = mediaSession?.player?.isPlaying ?: false
223+
else -> super.onCustomCommand(session, controller, customCommand, args)
224+
}
225+
})
226+
.build()
209227

228+
private fun buildNotificationProvider() = object : DefaultMediaNotificationProvider(this) {
210229
@Suppress("DEPRECATION")
211230
override fun getMediaButtons(
212231
session: MediaSession,
213232
playerCommands: Player.Commands,
214233
customLayout: ImmutableList<CommandButton>,
215234
showPauseButton: Boolean
216235
): ImmutableList<CommandButton> {
217-
val playPauseButton =
218-
CommandButton.Builder()
219-
.setDisplayName(
220-
if (isPlaying) getString(R.string.media_player_pause)
221-
else getString(R.string.media_player_play)
222-
)
223-
.setIconResId(
224-
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow
225-
)
226-
.setPlayerCommand(COMMAND_PLAY_PAUSE)
227-
.setExtras(Bundle().apply { putInt(COMMAND_KEY_COMPACT_VIEW_INDEX, 1) })
228-
.build()
236+
val isPlaying = mediaSession?.player?.isPlaying == true
237+
val playPauseButton = CommandButton.Builder()
238+
.setDisplayName(
239+
if (isPlaying) {
240+
getString(R.string.media_player_pause)
241+
} else {
242+
getString(R.string.media_player_play)
243+
}
244+
)
245+
.setIconResId(if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow)
246+
.setPlayerCommand(COMMAND_PLAY_PAUSE)
247+
.setExtras(Bundle().apply { putInt(COMMAND_KEY_COMPACT_VIEW_INDEX, 1) })
248+
.build()
229249

230250
return ImmutableList.of(seekBackward, playPauseButton, seekForward)
231251
}

app/src/main/java/com/owncloud/android/ui/preview/PreviewMediaFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ class PreviewMediaFragment :
431431
}
432432
}
433433

434-
434+
@Suppress("ReturnCount")
435435
private fun loadStreamUrl(user: User?, clientFactory: ClientFactory?, fileId: Long): Uri? {
436436
val client: OwnCloudClient? = try {
437437
clientFactory?.create(user)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!--
2+
~ Nextcloud - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2018-2026 Google LLC
5+
~ SPDX-License-Identifier: Apache-2.0
6+
-->
7+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
8+
android:width="24dp"
9+
android:height="24dp"
10+
android:viewportWidth="960"
11+
android:viewportHeight="960">
12+
<path
13+
android:pathData="M660,720v-480h80v480h-80ZM220,720v-480l360,240 -360,240ZM300,480ZM300,570 L436,480 300,390v180Z"
14+
android:fillColor="#e3e3e3"/>
15+
</vector>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!--
2+
~ Nextcloud - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2018-2026 Google LLC
5+
~ SPDX-License-Identifier: Apache-2.0
6+
-->
7+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
8+
android:width="24dp"
9+
android:height="24dp"
10+
android:viewportWidth="960"
11+
android:viewportHeight="960">
12+
<path
13+
android:pathData="M220,720v-480h80v480h-80ZM740,720L380,480l360,-240v480ZM660,480ZM660,570v-180l-136,90 136,90Z"
14+
android:fillColor="#e3e3e3"/>
15+
</vector>

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@
477477
<string name="media_player_seek_backward">Seek backward</string>
478478
<string name="media_player_play">Play</string>
479479
<string name="media_player_pause">Pause</string>
480-
480+
<string name="media_player_playing">Playing media</string>
481481

482482
<string name="ssl_validator_btn_details_see">Details</string>
483483
<string name="ssl_validator_btn_details_hide">Hide</string>

0 commit comments

Comments
 (0)