mirror of
https://github.com/nextcloud/android.git
synced 2024-11-22 21:25:35 +03:00
Fix previewing audio file
Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
parent
ed252e5a55
commit
58cca587ca
4 changed files with 102 additions and 42 deletions
|
@ -16,6 +16,7 @@ import android.os.IBinder
|
|||
import android.widget.MediaController
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.nextcloud.client.account.User
|
||||
import com.nextcloud.client.network.ClientFactory
|
||||
import com.nextcloud.utils.ForegroundServiceHelper
|
||||
|
@ -23,7 +24,9 @@ import com.nextcloud.utils.extensions.getParcelableArgument
|
|||
import com.owncloud.android.R
|
||||
import com.owncloud.android.datamodel.ForegroundServiceType
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
import com.owncloud.android.lib.common.utils.Log_OC
|
||||
import com.owncloud.android.ui.notifications.NotificationUtils
|
||||
import com.owncloud.android.ui.preview.PreviewMediaActivity
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils
|
||||
import dagger.android.AndroidInjection
|
||||
import java.util.Locale
|
||||
|
@ -32,6 +35,8 @@ import javax.inject.Inject
|
|||
class PlayerService : Service() {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "PlayerService"
|
||||
|
||||
const val EXTRA_USER = "USER"
|
||||
const val EXTRA_FILE = "FILE"
|
||||
const val EXTRA_AUTO_PLAY = "EXTRA_AUTO_PLAY"
|
||||
|
@ -40,6 +45,8 @@ class PlayerService : Service() {
|
|||
const val ACTION_STOP = "STOP"
|
||||
const val ACTION_TOGGLE = "TOGGLE"
|
||||
const val ACTION_STOP_FILE = "STOP_FILE"
|
||||
|
||||
const val IS_MEDIA_CONTROL_LAYOUT_READY = "IS_MEDIA_CONTROL_LAYOUT_READY"
|
||||
}
|
||||
|
||||
class Binder(val service: PlayerService) : android.os.Binder() {
|
||||
|
@ -52,24 +59,34 @@ class PlayerService : Service() {
|
|||
}
|
||||
|
||||
private val playerListener = object : Player.Listener {
|
||||
|
||||
override fun onRunning(file: OCFile) {
|
||||
Log_OC.d(TAG,"PlayerService.onRunning()")
|
||||
val intent = Intent(PreviewMediaActivity.MEDIA_CONTROL_READY_RECEIVER).apply {
|
||||
putExtra(IS_MEDIA_CONTROL_LAYOUT_READY, false)
|
||||
}
|
||||
LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(intent)
|
||||
startForeground(file)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
// empty
|
||||
Log_OC.d(TAG,"PlayerService.onStart()")
|
||||
val intent = Intent(PreviewMediaActivity.MEDIA_CONTROL_READY_RECEIVER).apply {
|
||||
putExtra(IS_MEDIA_CONTROL_LAYOUT_READY, true)
|
||||
}
|
||||
LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(intent)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
// empty
|
||||
Log_OC.d(TAG,"PlayerService.onPause()")
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
Log_OC.d(TAG,"PlayerService.onStop()")
|
||||
stopServiceAndRemoveNotification(null)
|
||||
}
|
||||
|
||||
override fun onError(error: PlayerError) {
|
||||
Log_OC.d(TAG,"PlayerService.onError()")
|
||||
Toast.makeText(this@PlayerService, error.message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
@ -89,18 +106,23 @@ class PlayerService : Service() {
|
|||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
AndroidInjection.inject(this)
|
||||
player = Player(applicationContext, clientFactory, playerListener, audioManager)
|
||||
notificationBuilder = NotificationCompat.Builder(this)
|
||||
viewThemeUtils.androidx.themeNotificationCompatBuilder(this, notificationBuilder)
|
||||
|
||||
val stop = Intent(this, PlayerService::class.java)
|
||||
stop.action = ACTION_STOP
|
||||
val stop = Intent(this, PlayerService::class.java).apply {
|
||||
action = ACTION_STOP
|
||||
}
|
||||
|
||||
val pendingStop = PendingIntent.getService(this, 0, stop, PendingIntent.FLAG_IMMUTABLE)
|
||||
notificationBuilder.addAction(0, getString(R.string.player_stop).toUpperCase(Locale.getDefault()), pendingStop)
|
||||
|
||||
val toggle = Intent(this, PlayerService::class.java)
|
||||
toggle.action = ACTION_TOGGLE
|
||||
val toggle = Intent(this, PlayerService::class.java).apply {
|
||||
action = ACTION_TOGGLE
|
||||
}
|
||||
|
||||
val pendingToggle = PendingIntent.getService(this, 0, toggle, PendingIntent.FLAG_IMMUTABLE)
|
||||
notificationBuilder.addAction(
|
||||
0,
|
||||
|
@ -124,10 +146,12 @@ class PlayerService : Service() {
|
|||
}
|
||||
|
||||
private fun onActionToggle() {
|
||||
if (player.isPlaying) {
|
||||
player.pause()
|
||||
player.run {
|
||||
if (isPlaying) {
|
||||
pause()
|
||||
} else {
|
||||
player.start()
|
||||
start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,14 +177,17 @@ class PlayerService : Service() {
|
|||
private fun startForeground(currentFile: OCFile) {
|
||||
val ticker = String.format(getString(R.string.media_notif_ticker), getString(R.string.app_name))
|
||||
val content = getString(R.string.media_state_playing, currentFile.getFileName())
|
||||
notificationBuilder.setSmallIcon(R.drawable.ic_play_arrow)
|
||||
notificationBuilder.setWhen(System.currentTimeMillis())
|
||||
notificationBuilder.setOngoing(true)
|
||||
notificationBuilder.setContentTitle(ticker)
|
||||
notificationBuilder.setContentText(content)
|
||||
|
||||
notificationBuilder.run {
|
||||
setSmallIcon(R.drawable.ic_play_arrow)
|
||||
setWhen(System.currentTimeMillis())
|
||||
setOngoing(true)
|
||||
setContentTitle(ticker)
|
||||
setContentText(content)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
notificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_MEDIA)
|
||||
setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_MEDIA)
|
||||
}
|
||||
}
|
||||
|
||||
ForegroundServiceHelper.startService(
|
||||
|
|
|
@ -38,12 +38,14 @@ class PlayerServiceConnection(private val context: Context) : MediaController.Me
|
|||
}
|
||||
|
||||
fun start(user: User, file: OCFile, playImmediately: Boolean, position: Long) {
|
||||
val i = Intent(context, PlayerService::class.java)
|
||||
i.putExtra(PlayerService.EXTRA_USER, user)
|
||||
i.putExtra(PlayerService.EXTRA_FILE, file)
|
||||
i.putExtra(PlayerService.EXTRA_AUTO_PLAY, playImmediately)
|
||||
i.putExtra(PlayerService.EXTRA_START_POSITION_MS, position)
|
||||
i.action = PlayerService.ACTION_PLAY
|
||||
val i = Intent(context, PlayerService::class.java).apply {
|
||||
putExtra(PlayerService.EXTRA_USER, user)
|
||||
putExtra(PlayerService.EXTRA_FILE, file)
|
||||
putExtra(PlayerService.EXTRA_AUTO_PLAY, playImmediately)
|
||||
putExtra(PlayerService.EXTRA_START_POSITION_MS, position)
|
||||
action = PlayerService.ACTION_PLAY
|
||||
}
|
||||
|
||||
startForegroundService(i)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
package com.owncloud.android.ui.preview
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
|
@ -41,6 +44,7 @@ import androidx.core.view.WindowInsetsControllerCompat
|
|||
import androidx.core.view.marginBottom
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
|
@ -53,6 +57,7 @@ import com.nextcloud.client.jobs.BackgroundJobManager
|
|||
import com.nextcloud.client.jobs.download.FileDownloadHelper
|
||||
import com.nextcloud.client.media.ExoplayerListener
|
||||
import com.nextcloud.client.media.NextcloudExoPlayer.createNextcloudExoplayer
|
||||
import com.nextcloud.client.media.PlayerService
|
||||
import com.nextcloud.client.media.PlayerServiceConnection
|
||||
import com.nextcloud.client.network.ClientFactory
|
||||
import com.nextcloud.client.network.ClientFactory.CreationException
|
||||
|
@ -146,9 +151,28 @@ class PreviewMediaActivity :
|
|||
showMediaTypeViews()
|
||||
configureSystemBars()
|
||||
emptyListView = binding.emptyView.emptyListView
|
||||
setLoadingView()
|
||||
showProgressLayout()
|
||||
}
|
||||
|
||||
private fun registerMediaControlReceiver() {
|
||||
val filter = IntentFilter(MEDIA_CONTROL_READY_RECEIVER)
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(mediaControlReceiver, filter)
|
||||
}
|
||||
|
||||
private val mediaControlReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
intent.getBooleanExtra(PlayerService.IS_MEDIA_CONTROL_LAYOUT_READY, false).run {
|
||||
if (this) {
|
||||
hideProgressLayout()
|
||||
recreate()
|
||||
} else {
|
||||
showProgressLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun initArguments(savedInstanceState: Bundle?) {
|
||||
intent?.let {
|
||||
initWithIntent(it)
|
||||
|
@ -160,6 +184,11 @@ class PreviewMediaActivity :
|
|||
} else {
|
||||
initWithBundle(savedInstanceState)
|
||||
}
|
||||
|
||||
if (MimeTypeUtil.isAudio(file)) {
|
||||
registerMediaControlReceiver()
|
||||
requestForDownload(file)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initWithIntent(intent: Intent) {
|
||||
|
@ -206,11 +235,18 @@ class PreviewMediaActivity :
|
|||
)
|
||||
}
|
||||
|
||||
private fun setLoadingView() {
|
||||
private fun showProgressLayout() {
|
||||
binding.progress.visibility = View.VISIBLE
|
||||
binding.mediaController.visibility = View.GONE
|
||||
binding.emptyView.emptyListView.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun hideProgressLayout() {
|
||||
binding.progress.visibility = View.GONE
|
||||
binding.mediaController.visibility = View.VISIBLE
|
||||
binding.emptyView.emptyListView.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun setVideoErrorMessage(headline: String, @StringRes message: Int) {
|
||||
binding.emptyView.run {
|
||||
emptyListViewHeadline.text = headline
|
||||
|
@ -218,8 +254,8 @@ class PreviewMediaActivity :
|
|||
emptyListIcon.setImageResource(R.drawable.file_movie)
|
||||
emptyListViewText.visibility = View.VISIBLE
|
||||
emptyListIcon.visibility = View.VISIBLE
|
||||
binding.progress.visibility = View.GONE
|
||||
emptyListView.visibility = View.VISIBLE
|
||||
|
||||
hideProgressLayout()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -691,8 +727,9 @@ class PreviewMediaActivity :
|
|||
override fun onDestroy() {
|
||||
Log_OC.v(TAG, "onDestroy")
|
||||
|
||||
super.onDestroy()
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(mediaControlReceiver)
|
||||
|
||||
super.onDestroy()
|
||||
exoPlayer?.run {
|
||||
stop()
|
||||
release()
|
||||
|
@ -783,6 +820,8 @@ class PreviewMediaActivity :
|
|||
|
||||
companion object {
|
||||
private val TAG = PreviewMediaActivity::class.java.simpleName
|
||||
|
||||
const val MEDIA_CONTROL_READY_RECEIVER: String = "MEDIA_CONTROL_READY_RECEIVER"
|
||||
const val EXTRA_FILE = "FILE"
|
||||
const val EXTRA_USER = "USER"
|
||||
const val EXTRA_AUTOPLAY = "AUTOPLAY"
|
||||
|
|
|
@ -51,24 +51,16 @@
|
|||
|
||||
<FrameLayout
|
||||
android:id="@+id/progress"
|
||||
android:background="@color/color_dark_transparent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.elyeproj.loaderviewlibrary.LoaderImageView
|
||||
android:layout_width="@dimen/empty_list_icon_layout_width"
|
||||
android:layout_height="@dimen/empty_list_icon_layout_width"
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@null"
|
||||
app:corners="24" />
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/empty_list_icon_layout_width"
|
||||
android:layout_height="@dimen/empty_list_icon_layout_height"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@null"
|
||||
android:padding="@dimen/standard_half_padding"
|
||||
android:src="@drawable/file_movie"
|
||||
app:tint="@color/bg_default" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
|
|
Loading…
Reference in a new issue