10 Commits

Author SHA1 Message Date
eddyizm
611b5001be chore: bumped version for new tag 2025-11-06 16:08:55 -08:00
eddyizm
923cfd5bc9 fix: equalizer missing referenced value 2025-11-06 16:08:07 -08:00
eddyizm
36d2320e70 chore: bump version and changelog for release 2025-11-06 15:44:46 -08:00
eddyizm
17713ee400 fix: Add listener to enable equalizer when audioSessionId changes (#235) 2025-11-06 15:40:39 -08:00
eddyizm
ee3465868e Album track list bug (#237) 2025-11-06 15:40:14 -08:00
eddyizm
9e8141a8d9 chore: name version 2025-11-06 14:49:19 -08:00
eddyizm
043e1b39b0 Revert "fix: do not override itemType and itemId"
This reverts commit d35146dba3.
2025-11-06 14:35:29 -08:00
Jaime García
938c1de906 chore: Remove comment 2025-11-06 04:48:24 +01:00
Jaime García
a0dfe63660 fix: Add listener to enable equalizer when audioSessionId changes 2025-11-06 03:18:39 +01:00
eddyizm
28c2f87b26 chore: updated change log 2025-11-05 09:15:11 -08:00
15 changed files with 162 additions and 17 deletions

View File

@@ -1,10 +1,16 @@
# 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)
## What's Changed
* chore(i18n): Update Spanish (es-ES) translation by @jaime-grj in https://github.com/eddyizm/tempus/pull/205 * chore(i18n): Update Spanish (es-ES) translation by @jaime-grj in https://github.com/eddyizm/tempus/pull/205
* feat: shuffle for artists without using `getTopSongs` by @pca006132 in https://github.com/eddyizm/tempus/pull/207 * shuffle for artists without using `getTopSongs` by @pca006132 in https://github.com/eddyizm/tempus/pull/207
* chore: Update USAGE.md with instant mix details by @zc-devs in https://github.com/eddyizm/tempus/pull/220 * Update USAGE.md with instant mix details by @zc-devs in https://github.com/eddyizm/tempus/pull/220
* feat: sort artists by album count by @pca006132 in https://github.com/eddyizm/tempus/pull/206 * feat: sort artists by album count by @pca006132 in https://github.com/eddyizm/tempus/pull/206
* Fix downloaded tab performance by @pca006132 in https://github.com/eddyizm/tempus/pull/210 * Fix downloaded tab performance by @pca006132 in https://github.com/eddyizm/tempus/pull/210
* fix: remove NestedScrollViews for fragment_album_page by @pca006132 in https://github.com/eddyizm/tempus/pull/216 * fix: remove NestedScrollViews for fragment_album_page by @pca006132 in https://github.com/eddyizm/tempus/pull/216
@@ -12,8 +18,12 @@
* fix: do not override getItemViewType and getItemId by @pca006132 in https://github.com/eddyizm/tempus/pull/221 * fix: do not override getItemViewType and getItemId by @pca006132 in https://github.com/eddyizm/tempus/pull/221
* chore: update media3 dependencies by @pca006132 in https://github.com/eddyizm/tempus/pull/217 * chore: update media3 dependencies by @pca006132 in https://github.com/eddyizm/tempus/pull/217
* fix: update MediaItems after network change by @pca006132 in https://github.com/eddyizm/tempus/pull/222 * fix: update MediaItems after network change by @pca006132 in https://github.com/eddyizm/tempus/pull/222
* fix: skip mapping downloaded item by @pca006132 in https://github.com/eddyizm/tempus/pull/228
--- ## New Contributors
* @pca006132 made their first contribution in https://github.com/eddyizm/tempus/pull/207
**Full Changelog**: https://github.com/eddyizm/tempus/compare/v4.0.7...v4.1.0
## [4.0.7](https://github.com/eddyizm/tempo/releases/tag/v4.0.7) (2025-10-28) ## [4.0.7](https://github.com/eddyizm/tempo/releases/tag/v4.0.7) (2025-10-28)
## What's Changed ## What's Changed

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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:

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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(
@@ -234,4 +265,4 @@ class EqualizerFragment : Fragment() {
} }
private fun Int.dpToPx(context: Context): Int = private fun Int.dpToPx(context: Context): Int =
(this * context.resources.displayMetrics.density).toInt() (this * context.resources.displayMetrics.density).toInt()

View File

@@ -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

View File

@@ -0,0 +1,2 @@
reverts change causing album disc/track list to get out of order
Add listener to enable equalizer when audioSessionId