It turns out there's a new security feature in Android 3.1 and above, where broadcast receivers don't register until the user manually opens the app at least once. Since I was trying to build a service-only app that had no UI to be opened, this was preventing all my intent listener attempts from working.
I've amended to have a splash-screen activity and now everything is working as I'd hoped. I'm now working to collate a list of player-specific intents to work from but for those trying to build something similar, com.android.music.playstatechanged seems to be the best start. This one is triggered by the default player (Google Play Music) when music either starts, pauses, or resumes and bundles itself with extra data including a boolean 'playing' property to differentiate between the play and pause states.
Essentially, this is the core receiver I'm now using. Have fun!
public class MainReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Start the service when music plays, stop the service when music ends.
if(intent.hasExtra("playing")) {
if(intent.getBooleanExtra("playing", false)) {
Intent service = new Intent(context, MainService.class);
context.startService(service);
} else {
Intent service = new Intent(context, MainService.class);
context.stopService(service);
}
}
}
}