From 8df7cee6779770d161f3a3eb48ca34e6b22c6e59 Mon Sep 17 00:00:00 2001 From: tuancoltech Date: Tue, 3 Sep 2024 11:26:43 +0700 Subject: [PATCH] * Move extractDuration method to util class for better re-usability. * Minor Lint warning fixes --- .../arkmemo/media/ArkAudioRecorderImpl.kt | 6 +++--- .../arkmemo/repo/voices/VoiceNotesRepo.kt | 17 +--------------- .../ui/fragments/ArkMediaPlayerFragment.kt | 5 ++--- .../ui/fragments/ArkRecorderFragment.kt | 5 ++--- .../ui/fragments/EditGraphicNotesFragment.kt | 16 ++++----------- .../ui/viewmodels/ArkMediaPlayerViewModel.kt | 20 ++++++++----------- .../arkmemo/ui/viewmodels/NotesViewModel.kt | 4 ++-- .../arkmemo/ui/views/SwitchButton.kt | 6 +++--- .../dev/arkbuilders/arkmemo/utils/Utils.kt | 19 ++++++++++++++++++ 9 files changed, 44 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/media/ArkAudioRecorderImpl.kt b/app/src/main/java/dev/arkbuilders/arkmemo/media/ArkAudioRecorderImpl.kt index 5a06f856..a4dec4f8 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/media/ArkAudioRecorderImpl.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/media/ArkAudioRecorderImpl.kt @@ -61,10 +61,10 @@ class ArkAudioRecorderImpl @Inject constructor( } override fun maxAmplitude(): Int { - try { - return recorder?.maxAmplitude ?: 0 + return try { + recorder?.maxAmplitude ?: 0 } catch (e: Exception) { - return 0 + 0 } } diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/repo/voices/VoiceNotesRepo.kt b/app/src/main/java/dev/arkbuilders/arkmemo/repo/voices/VoiceNotesRepo.kt index 9d758977..b324b54b 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/repo/voices/VoiceNotesRepo.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/repo/voices/VoiceNotesRepo.kt @@ -1,6 +1,5 @@ package dev.arkbuilders.arkmemo.repo.voices -import android.media.MediaMetadataRetriever import android.util.Log import dev.arkbuilders.arklib.computeId import dev.arkbuilders.arklib.data.index.Resource @@ -10,8 +9,8 @@ import dev.arkbuilders.arkmemo.models.VoiceNote import dev.arkbuilders.arkmemo.preferences.MemoPreferences import dev.arkbuilders.arkmemo.repo.NotesRepo import dev.arkbuilders.arkmemo.repo.NotesRepoHelper +import dev.arkbuilders.arkmemo.utils.extractDuration import dev.arkbuilders.arkmemo.utils.listFiles -import dev.arkbuilders.arkmemo.utils.millisToString import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext import java.nio.file.Path @@ -111,20 +110,6 @@ class VoiceNotesRepo @Inject constructor( ) } } - - fun extractDuration(path: String): String { - return try { - val metadataRetriever = MediaMetadataRetriever() - metadataRetriever.setDataSource(path) - val duration = metadataRetriever.extractMetadata( - MediaMetadataRetriever.METADATA_KEY_DURATION - )?.toLong() ?: 0L - millisToString(duration) - } catch (e: Exception) { - Log.e(VOICES_REPO, "extractDuration exception: " + e.message) - "" - } - } } private const val VOICES_REPO = "VoiceNotesRepo" diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/ArkMediaPlayerFragment.kt b/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/ArkMediaPlayerFragment.kt index f74ca8b2..53529709 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/ArkMediaPlayerFragment.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/ArkMediaPlayerFragment.kt @@ -16,7 +16,6 @@ import dev.arkbuilders.arkmemo.ui.viewmodels.ArkMediaPlayerSideEffect import dev.arkbuilders.arkmemo.ui.viewmodels.ArkMediaPlayerState import dev.arkbuilders.arkmemo.ui.viewmodels.ArkMediaPlayerViewModel import dev.arkbuilders.arkmemo.utils.gone -import dev.arkbuilders.arkmemo.utils.millisToString import dev.arkbuilders.arkmemo.utils.visible import kotlinx.coroutines.launch import java.io.File @@ -76,8 +75,8 @@ class ArkMediaPlayerFragment: BaseEditNoteFragment() { binding.layoutAudioRecord.root.visible() binding.layoutAudioRecord.tvRecordGuide.text = getString(R.string.audio_record_guide_text_replace) - arkMediaPlayerViewModel.getDurationMillis { duration -> - binding.layoutAudioView.tvDuration.text = millisToString(duration) + arkMediaPlayerViewModel.getDurationString { duration -> + binding.layoutAudioView.tvDuration.text = duration } } else { diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/ArkRecorderFragment.kt b/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/ArkRecorderFragment.kt index 9ad46c32..08e0123a 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/ArkRecorderFragment.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/ArkRecorderFragment.kt @@ -33,7 +33,6 @@ import dev.arkbuilders.arkmemo.ui.viewmodels.RecorderState import dev.arkbuilders.arkmemo.ui.viewmodels.ArkRecorderViewModel import dev.arkbuilders.arkmemo.ui.views.toast import dev.arkbuilders.arkmemo.utils.gone -import dev.arkbuilders.arkmemo.utils.millisToString import dev.arkbuilders.arkmemo.utils.observeSaveResult import dev.arkbuilders.arkmemo.utils.visible import kotlinx.coroutines.launch @@ -391,8 +390,8 @@ class ArkRecorderFragment: BaseEditNoteFragment() { binding.layoutAudioView.root.visible() binding.layoutAudioRecord.tvRecordGuide.text = getString(R.string.audio_record_guide_text_replace) - mediaPlayViewModel.getDurationMillis { duration -> - binding.layoutAudioView.tvDuration.text = millisToString(duration) + mediaPlayViewModel.getDurationString { duration -> + binding.layoutAudioView.tvDuration.text = duration } } else { diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/EditGraphicNotesFragment.kt b/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/EditGraphicNotesFragment.kt index cc2a2a49..58fe3eee 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/EditGraphicNotesFragment.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/ui/fragments/EditGraphicNotesFragment.kt @@ -1,6 +1,5 @@ package dev.arkbuilders.arkmemo.ui.fragments -import android.os.Build import android.os.Bundle import android.text.Editable import android.text.TextWatcher @@ -32,6 +31,7 @@ import dev.arkbuilders.arkmemo.ui.adapters.EqualSpacingItemDecoration import dev.arkbuilders.arkmemo.ui.viewmodels.GraphicNotesViewModel import dev.arkbuilders.arkmemo.utils.getBrushSize import dev.arkbuilders.arkmemo.utils.getColorCode +import dev.arkbuilders.arkmemo.utils.getParcelableCompat import dev.arkbuilders.arkmemo.utils.gone import dev.arkbuilders.arkmemo.utils.observeSaveResult import dev.arkbuilders.arkmemo.utils.setDrawableColor @@ -59,17 +59,9 @@ class EditGraphicNotesFragment: BaseEditNoteFragment() { super.onCreate(savedInstanceState) notesViewModel.init {} observeSaveResult(notesViewModel.getSaveNoteResultLiveData()) - if (arguments != null) { - @Suppress("DEPRECATION") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) - requireArguments().getParcelable(GRAPHICAL_NOTE_KEY, GraphicNote::class.java)?.let { - note = it - graphicNotesViewModel.onNoteOpened(note) - } - else requireArguments().getParcelable(GRAPHICAL_NOTE_KEY)?.let { - note = it - graphicNotesViewModel.onNoteOpened(note) - } + arguments?.getParcelableCompat(GRAPHICAL_NOTE_KEY, GraphicNote::class.java)?.let { + note = it + graphicNotesViewModel.onNoteOpened(note) } } diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/ArkMediaPlayerViewModel.kt b/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/ArkMediaPlayerViewModel.kt index a37767db..594f6c67 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/ArkMediaPlayerViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/ArkMediaPlayerViewModel.kt @@ -1,10 +1,10 @@ package dev.arkbuilders.arkmemo.ui.viewmodels -import android.media.MediaMetadataRetriever import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.arkbuilders.arkmemo.media.ArkMediaPlayer +import dev.arkbuilders.arkmemo.utils.extractDuration import dev.arkbuilders.arkmemo.utils.millisToString import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -15,13 +15,13 @@ import java.io.File import javax.inject.Inject sealed class ArkMediaPlayerSideEffect { - object StartPlaying: ArkMediaPlayerSideEffect() + data object StartPlaying: ArkMediaPlayerSideEffect() - object PausePlaying: ArkMediaPlayerSideEffect() + data object PausePlaying: ArkMediaPlayerSideEffect() - object ResumePlaying: ArkMediaPlayerSideEffect() + data object ResumePlaying: ArkMediaPlayerSideEffect() - object StopPlaying: ArkMediaPlayerSideEffect() + data object StopPlaying: ArkMediaPlayerSideEffect() } data class ArkMediaPlayerState( @@ -133,18 +133,14 @@ class ArkMediaPlayerViewModel @Inject constructor( arkMediaPlayerSideEffect.value = ArkMediaPlayerSideEffect.PausePlaying } - fun getDurationMillis(onSuccess: (duration: Long) -> Unit) { + fun getDurationString(onSuccess: (duration: String) -> Unit) { if (currentPlayingVoiceNotePath.isEmpty() || File(currentPlayingVoiceNotePath).length() == 0L) return viewModelScope.launch(Dispatchers.IO) { - val metadataRetriever = MediaMetadataRetriever() - metadataRetriever.setDataSource(currentPlayingVoiceNotePath) - val duration = metadataRetriever.extractMetadata( - MediaMetadataRetriever.METADATA_KEY_DURATION - )?.toLong() ?: 0L + val durationString = extractDuration(currentPlayingVoiceNotePath) withContext(Dispatchers.Main) { - onSuccess.invoke(duration) + onSuccess.invoke(durationString) } } } diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/NotesViewModel.kt b/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/NotesViewModel.kt index 08519a2c..c0d7375b 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/NotesViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/ui/viewmodels/NotesViewModel.kt @@ -18,7 +18,7 @@ import dev.arkbuilders.arkmemo.models.GraphicNote import dev.arkbuilders.arkmemo.models.Note import dev.arkbuilders.arkmemo.models.TextNote import dev.arkbuilders.arkmemo.models.VoiceNote -import dev.arkbuilders.arkmemo.repo.voices.VoiceNotesRepo +import dev.arkbuilders.arkmemo.utils.extractDuration import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collectLatest @@ -137,7 +137,7 @@ class NotesViewModel @Inject constructor( notes.removeIf { it.resource?.id == parentResId ?: note.resource?.id } } if (note is VoiceNote) { - note.duration = (voiceNotesRepo as VoiceNotesRepo).extractDuration(note.path.pathString) + note.duration = extractDuration(note.path.pathString) } notes.add(note) this.notes.value = notes diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/ui/views/SwitchButton.kt b/app/src/main/java/dev/arkbuilders/arkmemo/ui/views/SwitchButton.kt index 83c8ee03..355d1604 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/ui/views/SwitchButton.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/ui/views/SwitchButton.kt @@ -227,7 +227,7 @@ class SwitchButton : View, Checkable { } else { setUncheckViewState(viewState) } - isUiInited = true + isUIInitialized = true postInvalidate() } @@ -410,7 +410,7 @@ class SwitchButton : View, Checkable { if (isEventBroadcast) { throw RuntimeException("should NOT switch the state in method: [onCheckedChanged]!") } - if (!isUiInited) { + if (!isUIInitialized) { isChecked = !isChecked if (broadcast) { broadcastEvent() @@ -671,7 +671,7 @@ class SwitchButton : View, Checkable { private var shadowEffect = false private var showIndicator = false private var isTouchingDown = false - private var isUiInited = false + private var isUIInitialized = false private var isEventBroadcast = false private var onCheckedChangeListener: OnCheckedChangeListener? = null private var touchDownTime: Long = 0 diff --git a/app/src/main/java/dev/arkbuilders/arkmemo/utils/Utils.kt b/app/src/main/java/dev/arkbuilders/arkmemo/utils/Utils.kt index d96b10fb..892c6428 100644 --- a/app/src/main/java/dev/arkbuilders/arkmemo/utils/Utils.kt +++ b/app/src/main/java/dev/arkbuilders/arkmemo/utils/Utils.kt @@ -3,7 +3,9 @@ package dev.arkbuilders.arkmemo.utils import android.content.ClipData import android.content.ClipboardManager import android.content.Context +import android.media.MediaMetadataRetriever import android.os.Build +import android.util.Log import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment @@ -108,3 +110,20 @@ fun millisToString(duration: Long): String { if (remainingSeconds <= 9) "0$remainingSeconds" else remainingSeconds }" } + +/** + * Extract duration of a media file and return it in human-readable format + */ +fun extractDuration(path: String): String { + return try { + val metadataRetriever = MediaMetadataRetriever() + metadataRetriever.setDataSource(path) + val duration = metadataRetriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_DURATION + )?.toLong() ?: 0L + millisToString(duration) + } catch (e: Exception) { + Log.e("ExtractDuration", "extractDuration exception: " + e.message) + "" + } +}