mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
Merge branch 'eddyizm:development' into development
This commit is contained in:
commit
51883cd82b
16 changed files with 177 additions and 24 deletions
|
|
@ -1,6 +1,10 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## Pending release..
|
## Pending release..
|
||||||
|
* fix: reverts change causing album disc/track list to get out of order by @eddyizm in https://github.com/eddyizm/tempus/pull/237
|
||||||
|
* fix: Add listener to enable equalizer when audioSessionId changes by @jaime-grj in https://github.com/eddyizm/tempus/pull/235
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/eddyizm/tempus/compare/v4.1.0...v4.1.2
|
||||||
|
|
||||||
## [4.1.0](https://github.com/eddyizm/tempo/releases/tag/v4.1.0) (2025-11-05)
|
## [4.1.0](https://github.com/eddyizm/tempo/releases/tag/v4.1.0) (2025-11-05)
|
||||||
## What's Changed
|
## What's Changed
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ android {
|
||||||
minSdkVersion 24
|
minSdkVersion 24
|
||||||
targetSdk 35
|
targetSdk 35
|
||||||
|
|
||||||
versionCode 3
|
versionCode 4
|
||||||
versionName '4.1.0'
|
versionName '4.1.3'
|
||||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||||
|
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ class MediaService : MediaLibraryService() {
|
||||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL =
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL =
|
||||||
"android.media3.session.demo.REPEAT_ALL"
|
"android.media3.session.demo.REPEAT_ALL"
|
||||||
const val ACTION_BIND_EQUALIZER = "com.cappielloantonio.tempo.service.BIND_EQUALIZER"
|
const val ACTION_BIND_EQUALIZER = "com.cappielloantonio.tempo.service.BIND_EQUALIZER"
|
||||||
|
const val ACTION_EQUALIZER_UPDATED = "com.cappielloantonio.tempo.service.EQUALIZER_UPDATED"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateMediaItems() {
|
fun updateMediaItems() {
|
||||||
|
|
@ -283,16 +284,7 @@ class MediaService : MediaLibraryService() {
|
||||||
private fun initializeEqualizerManager() {
|
private fun initializeEqualizerManager() {
|
||||||
equalizerManager = EqualizerManager()
|
equalizerManager = EqualizerManager()
|
||||||
val audioSessionId = player.audioSessionId
|
val audioSessionId = player.audioSessionId
|
||||||
if (equalizerManager.attachToSession(audioSessionId)) {
|
attachEqualizerIfPossible(audioSessionId)
|
||||||
val enabled = Preferences.isEqualizerEnabled()
|
|
||||||
equalizerManager.setEnabled(enabled)
|
|
||||||
|
|
||||||
val bands = equalizerManager.getNumberOfBands()
|
|
||||||
val savedLevels = Preferences.getEqualizerBandLevels(bands)
|
|
||||||
for (i in 0 until bands) {
|
|
||||||
equalizerManager.setBandLevel(i.toShort(), savedLevels[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeMediaLibrarySession() {
|
private fun initializeMediaLibrarySession() {
|
||||||
|
|
@ -426,6 +418,10 @@ class MediaService : MediaLibraryService() {
|
||||||
customLayout = librarySessionCallback.buildCustomLayout(player)
|
customLayout = librarySessionCallback.buildCustomLayout(player)
|
||||||
mediaLibrarySession.setCustomLayout(customLayout)
|
mediaLibrarySession.setCustomLayout(customLayout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAudioSessionIdChanged(audioSessionId: Int) {
|
||||||
|
attachEqualizerIfPossible(audioSessionId)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if (player.isPlaying) {
|
if (player.isPlaying) {
|
||||||
scheduleWidgetUpdates()
|
scheduleWidgetUpdates()
|
||||||
|
|
@ -541,6 +537,21 @@ class MediaService : MediaLibraryService() {
|
||||||
widgetUpdateScheduled = false
|
widgetUpdateScheduled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun attachEqualizerIfPossible(audioSessionId: Int): Boolean {
|
||||||
|
if (audioSessionId == 0 || audioSessionId == -1) return false
|
||||||
|
val attached = equalizerManager.attachToSession(audioSessionId)
|
||||||
|
if (attached) {
|
||||||
|
val enabled = Preferences.isEqualizerEnabled()
|
||||||
|
equalizerManager.setEnabled(enabled)
|
||||||
|
val bands = equalizerManager.getNumberOfBands()
|
||||||
|
val savedLevels = Preferences.getEqualizerBandLevels(bands)
|
||||||
|
for (i in 0 until bands) {
|
||||||
|
equalizerManager.setBandLevel(i.toShort(), savedLevels[i])
|
||||||
|
}
|
||||||
|
sendBroadcast(Intent(ACTION_EQUALIZER_UPDATED))
|
||||||
|
}
|
||||||
|
return attached
|
||||||
|
}
|
||||||
|
|
||||||
private fun getRenderersFactory() = DownloadUtil.buildRenderersFactory(this, false)
|
private fun getRenderersFactory() = DownloadUtil.buildRenderersFactory(this, false)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,16 @@ public class AlbumCatalogueAdapter extends RecyclerView.Adapter<AlbumCatalogueAd
|
||||||
filtering.filter(currentFilter);
|
filtering.filter(currentFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Filter getFilter() {
|
public Filter getFilter() {
|
||||||
return filtering;
|
return filtering;
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,16 @@ public class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ViewHolder
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
ItemLibraryArtistBinding item;
|
ItemLibraryArtistBinding item;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,16 @@ public class ArtistCatalogueAdapter extends RecyclerView.Adapter<ArtistCatalogue
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Filter getFilter() {
|
public Filter getFilter() {
|
||||||
return filtering;
|
return filtering;
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,16 @@ public class ArtistHorizontalAdapter extends RecyclerView.Adapter<ArtistHorizont
|
||||||
return artists.get(id);
|
return artists.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
ItemHorizontalArtistBinding item;
|
ItemHorizontalArtistBinding item;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,16 @@ public class ArtistSimilarAdapter extends RecyclerView.Adapter<ArtistSimilarAdap
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
ItemLibrarySimilarArtistBinding item;
|
ItemLibrarySimilarArtistBinding item;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,16 @@ public class DownloadHorizontalAdapter extends RecyclerView.Adapter<DownloadHori
|
||||||
return shuffling;
|
return shuffling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
private List<Child> groupSong(List<Child> songs) {
|
private List<Child> groupSong(List<Child> songs) {
|
||||||
switch (view) {
|
switch (view) {
|
||||||
case Constants.DOWNLOAD_TYPE_TRACK:
|
case Constants.DOWNLOAD_TYPE_TRACK:
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,16 @@ public class PodcastChannelCatalogueAdapter extends RecyclerView.Adapter<Podcast
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Filter getFilter() {
|
public Filter getFilter() {
|
||||||
return filtering;
|
return filtering;
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,16 @@ public class PodcastEpisodeAdapter extends RecyclerView.Adapter<PodcastEpisodeAd
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
ItemHomePodcastEpisodeBinding item;
|
ItemHomePodcastEpisodeBinding item;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -252,6 +252,16 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAd
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPlaybackState(String mediaId, boolean playing) {
|
public void setPlaybackState(String mediaId, boolean playing) {
|
||||||
String oldId = this.currentPlayingId;
|
String oldId = this.currentPlayingId;
|
||||||
boolean oldPlaying = this.isPlaying;
|
boolean oldPlaying = this.isPlaying;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@ package com.cappielloantonio.tempo.ui.fragment
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
|
|
@ -12,6 +14,7 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import com.cappielloantonio.tempo.R
|
import com.cappielloantonio.tempo.R
|
||||||
|
|
@ -28,6 +31,17 @@ class EqualizerFragment : Fragment() {
|
||||||
private lateinit var safeSpace: Space
|
private lateinit var safeSpace: Space
|
||||||
private val bandSeekBars = mutableListOf<SeekBar>()
|
private val bandSeekBars = mutableListOf<SeekBar>()
|
||||||
|
|
||||||
|
private var receiverRegistered = false
|
||||||
|
private val equalizerUpdatedReceiver = object : BroadcastReceiver() {
|
||||||
|
@OptIn(UnstableApi::class)
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
if (intent?.action == MediaService.ACTION_EQUALIZER_UPDATED) {
|
||||||
|
initUI()
|
||||||
|
restoreEqualizerPreferences()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val connection = object : ServiceConnection {
|
private val connection = object : ServiceConnection {
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||||
|
|
@ -49,12 +63,29 @@ class EqualizerFragment : Fragment() {
|
||||||
intent.action = MediaService.ACTION_BIND_EQUALIZER
|
intent.action = MediaService.ACTION_BIND_EQUALIZER
|
||||||
requireActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE)
|
requireActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE)
|
||||||
}
|
}
|
||||||
|
if (!receiverRegistered) {
|
||||||
|
ContextCompat.registerReceiver(
|
||||||
|
requireContext(),
|
||||||
|
equalizerUpdatedReceiver,
|
||||||
|
IntentFilter(MediaService.ACTION_EQUALIZER_UPDATED),
|
||||||
|
ContextCompat.RECEIVER_NOT_EXPORTED
|
||||||
|
)
|
||||||
|
receiverRegistered = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
super.onStop()
|
super.onStop()
|
||||||
requireActivity().unbindService(connection)
|
requireActivity().unbindService(connection)
|
||||||
equalizerManager = null
|
equalizerManager = null
|
||||||
|
if (receiverRegistered) {
|
||||||
|
try {
|
||||||
|
requireContext().unregisterReceiver(equalizerUpdatedReceiver)
|
||||||
|
} catch (_: Exception) {
|
||||||
|
// ignore if not registered
|
||||||
|
}
|
||||||
|
receiverRegistered = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/discover_song_cover_image_view"
|
android:id="@+id/discover_song_cover_image_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="196dp"
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
android:background="?attr/colorSurfaceContainerHighest"
|
android:background="?attr/colorSurfaceContainerHighest"
|
||||||
android:foreground="@drawable/gradient_discover_background_image" />
|
android:foreground="@drawable/gradient_discover_background_image" />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val ACTION_BIND_EQUALIZER = "com.cappielloantonio.tempo.service.BIND_EQUALIZER"
|
const val ACTION_BIND_EQUALIZER = "com.cappielloantonio.tempo.service.BIND_EQUALIZER"
|
||||||
|
const val ACTION_EQUALIZER_UPDATED = "com.cappielloantonio.tempo.service.EQUALIZER_UPDATED"
|
||||||
}
|
}
|
||||||
private val widgetUpdateHandler = Handler(Looper.getMainLooper())
|
private val widgetUpdateHandler = Handler(Looper.getMainLooper())
|
||||||
private var widgetUpdateScheduled = false
|
private var widgetUpdateScheduled = false
|
||||||
|
|
@ -160,16 +161,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
private fun initializeEqualizerManager() {
|
private fun initializeEqualizerManager() {
|
||||||
equalizerManager = EqualizerManager()
|
equalizerManager = EqualizerManager()
|
||||||
val audioSessionId = player.audioSessionId
|
val audioSessionId = player.audioSessionId
|
||||||
if (equalizerManager.attachToSession(audioSessionId)) {
|
attachEqualizerIfPossible(audioSessionId)
|
||||||
val enabled = Preferences.isEqualizerEnabled()
|
|
||||||
equalizerManager.setEnabled(enabled)
|
|
||||||
|
|
||||||
val bands = equalizerManager.getNumberOfBands()
|
|
||||||
val savedLevels = Preferences.getEqualizerBandLevels(bands)
|
|
||||||
for (i in 0 until bands) {
|
|
||||||
equalizerManager.setBandLevel(i.toShort(), savedLevels[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializePlayer() {
|
private fun initializePlayer() {
|
||||||
|
|
@ -333,6 +325,10 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
override fun onRepeatModeChanged(repeatMode: Int) {
|
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||||
Preferences.setRepeatMode(repeatMode)
|
Preferences.setRepeatMode(repeatMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAudioSessionIdChanged(audioSessionId: Int) {
|
||||||
|
attachEqualizerIfPossible(audioSessionId)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if (player.isPlaying) {
|
if (player.isPlaying) {
|
||||||
scheduleWidgetUpdates()
|
scheduleWidgetUpdates()
|
||||||
|
|
@ -450,6 +446,22 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
player.playWhenReady = isPlaying
|
player.playWhenReady = isPlaying
|
||||||
player.prepare()
|
player.prepare()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun attachEqualizerIfPossible(audioSessionId: Int): Boolean {
|
||||||
|
if (audioSessionId == 0 || audioSessionId == -1) return false
|
||||||
|
val attached = equalizerManager.attachToSession(audioSessionId)
|
||||||
|
if (attached) {
|
||||||
|
val enabled = Preferences.isEqualizerEnabled()
|
||||||
|
equalizerManager.setEnabled(enabled)
|
||||||
|
val bands = equalizerManager.getNumberOfBands()
|
||||||
|
val savedLevels = Preferences.getEqualizerBandLevels(bands)
|
||||||
|
for (i in 0 until bands) {
|
||||||
|
equalizerManager.setBandLevel(i.toShort(), savedLevels[i])
|
||||||
|
}
|
||||||
|
sendBroadcast(Intent(ACTION_EQUALIZER_UPDATED))
|
||||||
|
}
|
||||||
|
return attached
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val WIDGET_UPDATE_INTERVAL_MS = 1000L
|
private const val WIDGET_UPDATE_INTERVAL_MS = 1000L
|
||||||
|
|
|
||||||
2
fastlane/metadata/android/en-US/changelogs/4.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/4.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
reverts change causing album disc/track list to get out of order
|
||||||
|
Add listener to enable equalizer when audioSessionId
|
||||||
Loading…
Add table
Add a link
Reference in a new issue