Conversation
This file implements the SoundLoader class for audio playback management on Android, including methods for loading, playing, pausing, stopping, and seeking audio tracks. It also requests 'All Files Access' permission for Android 11 and handles player readiness with a listener.
|
Need better APIs and handle seek updates internally self.notification = MusicNotification(
on_play=self.play_music,
on_pause=self.pause_music,
on_seek=self.seek_music, # receives seconds (float)
on_next=self.next_music,
on_prev=self.prev_music,
auto_update_interval=1.0, # drives the Clock internally
) |
|
AudioManager and MusicNotification should be independent, methods like when music time stamp changes should cover from AudioManager |
Music Notifications — V1 UsageV1 separates playback from the Android notification.
Basic Usagefrom android_notify import AudioManager, MusicNotification
audio = AudioManager("music/song.mp3")
notification = MusicNotification(
title="My Song",
artist="Kivy Artist",
)
notification.bind(audio)
audio.play()Once bound, the notification follows the audio manager's playback state. AudioManager
audio = AudioManager("music/song.mp3")
audio.play()
audio.pause()
audio.seek(30)
audio.stop()It owns playback state such as: audio.position
audio.durationIt does not manage playlists or decide what track comes next. MusicNotificationCreate the notification independently: notification = MusicNotification(
title="My Song",
artist="Kivy Artist",
)Then bind it to an audio manager: notification.bind(audio)The notification becomes the Android control surface for that audio. Playback ControlsApplication code controls playback through audio.play()
audio.pause()
audio.seek(60)Likewise, Android notification controls should ultimately operate on the bound The application should not need to manually synchronize the notification after Next and Previous
Those actions belong to the application or playlist layer. The notification can expose callbacks for these actions: def play_next():
# Application decides which track comes next.
...
def play_previous():
# Application decides which track comes before the current track.
...
notification = MusicNotification(
title="My Song",
artist="Kivy Artist",
on_next=play_next,
on_previous=play_previous,
)
notification.bind(audio)When the user presses Next: For example: def play_next():
global audio
audio.stop()
audio = AudioManager("music/song2.mp3")
notification.bind(audio)
audio.play()The same pattern applies to Previous. This keeps responsibilities separate:
Track InformationTrack information belongs to the current media represented by the notification. For example: notification = MusicNotification(
title="My Song",
artist="Kivy Artist",
)When the application changes tracks, it can create/bind a new The notification should not need to know how the application chooses its tracks. Position and ProgressPlayback position belongs to The notification uses the audio manager's state to display progress. Application code should not need to repeatedly do this: notification.update_progress(audio.position)Instead, the notification observes position/state updates from the bound audio Keeping the Components Independent
This should work without a notification: audio = AudioManager("music/song.mp3")
audio.play()Likewise, a notification can exist before it is bound: notification = MusicNotification(
title="My Song",
artist="Kivy Artist",
)The connection is explicit: notification.bind(audio)This keeps the two components reusable and independent. Recommended Application StructureA simple application can look like: from android_notify import AudioManager, MusicNotification
class Player:
def __init__(self):
self.audio = AudioManager("music/song.mp3")
self.notification = MusicNotification(
title="My Song",
artist="Kivy Artist",
on_next=self.play_next,
on_previous=self.play_previous,
)
self.notification.bind(self.audio)
def play(self):
self.audio.play()
def pause(self):
self.audio.pause()
def seek(self, position):
self.audio.seek(position)
def play_next(self):
# Application / playlist chooses the next file.
self.audio.stop()
self.audio = AudioManager("music/song2.mp3")
self.notification.bind(self.audio)
self.audio.play()
def play_previous(self):
# Application / playlist chooses the previous file.
...The important part is that playlist logic stays outside V1 Design Principle
Avoid duplicating playback state between |
Added TODO comments regarding future removals and testing.
Usage sample
point to java file folder
paste as-is in java directory
package.domain.package.name