How it works - MShekow/stop-it GitHub Wiki
How Stop It! works
To be able to create bookmarks, we need Android to inform Stop It! about the following events:
- Changes of the currently playing audio track
- Playback state changed from playing to paused (or vice versa)
The first implementation made use of BroadcastReceivers
, listening to com.android.music.playstatechanged
Intents. However, devices running Android 8+ no longer receive such Intents. Instead, we use the Media API which pretty much all modern video/audio players implement. We take a lot of inspiration from the Media Controller Test sample app made by Google. Retrieving the MediaSessionManager
we register an OnActiveSessionsChangedListener
that notifies us whenever new MediaController
s exist / cease to exist (because a video/audio app was started or quit). We make copies from the MediaController
s given to us by OnActiveSessionsChangedListener.onActiveSessionsChanged(controllers)
, and register MediaController.Callback
s to be informed about state changes. From the MediaController
s we can also get MediaController.TransportControls
to control the playback, which is useful to resume playback for a previously created bookmark.
To have sufficient permissions to use the Media API, Stop It! implements a NotificationListenerService
. The user has to explicitly grant notification listening access to Stop It!. We need to be able to listen to notifications anyway, because notifications typically will cause audio playback to pause briefly, causing the MediaController.Callback
functions to be called. These calls make it look like the user had briefly paused and unpaused the audio playback, wishing a bookmark to be created, but this is not the case. To avoid incorrect detections, the NotificationListenerService
verifies that no notifications were posted during the last few seconds.
To persistently store bookmarks, Stop It! uses Room.