0

I have stared tirelessly at the documentation that android provides for the

MediaButtonReceiver class (https://developer.android.com/reference/kotlin/androidx/media/session/MediaButtonReceiver?hl=en)

and the guide on responding to media buttons

(https://developer.android.com/guide/topics/media-apps/mediabuttons).

Also looked around StackOverflow for people who had a similar issue to this and followed the guidelines that people provided there but I still have not found a way to solve this issue.

Receiving media key events in Service

What I'm trying to do is make my service pick up events from a volume down/up and play button from a bluetooth remote. When checking the sytem_process logs I can see that the button events are indeed getting sent to the service but the callback is not picking up on any of these events. Any clue to what the issue is? Log.d is never called on the callbacks

AndroidManifest.xml

    <application
        android:name=".BaseApplication"
        android:allowBackup="true"
        android:debuggable="true"
        android:extractNativeLibs="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="HardcodedDebugMode">

        <activity
            android:name=".activity.MainActivity"
            android:screenOrientation="reverseLandscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".receivers.OnBootReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
            <intent-filter android:priority="999">
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
        </receiver>

        <receiver android:name="androidx.media.session.MediaButtonReceiver">
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_BUTTON"/>
            </intent-filter>
        </receiver>

        <service android:name=".service.MyForegroundService">
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_BUTTON" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.example.example.myservice.ACTION_BIND" />
            </intent-filter>
        </service>

    </application>

</manifest>

MyService.kt

class MyForegroundService : Service() {
    private val TAG = "MyForegroundService"

    private lateinit var mediaSession: MediaSessionCompat

    private fun getVolumeProvider(): VolumeProviderCompat? {
        val audio: AudioManager = getSystemService(AUDIO_SERVICE) as AudioManager
        val STREAM_TYPE: Int = AudioManager.STREAM_MUSIC
        val currentVolume: Int = audio.getStreamVolume(STREAM_TYPE)
        val maxVolume: Int = audio.getStreamMaxVolume(STREAM_TYPE)
        val VOLUME_UP = 1
        val VOLUME_DOWN = -1
        return object : VolumeProviderCompat(
            VOLUME_CONTROL_RELATIVE,
            maxVolume,
            currentVolume
        ) {
            override fun onAdjustVolume(direction: Int) {
                Log.d(TAG, "onAdjustVolume: ")
                // Up = 1, Down = -1, Release = 0
                // Replace with your action, if you don't want to adjust system volume
                if (direction == VOLUME_UP) {
                    audio.adjustStreamVolume(
                        STREAM_TYPE,
                        AudioManager.ADJUST_RAISE, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
                    )
                } else if (direction == VOLUME_DOWN) {
                    audio.adjustStreamVolume(
                        STREAM_TYPE,
                        AudioManager.ADJUST_LOWER, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
                    )
                }
                setCurrentVolume(audio.getStreamVolume(STREAM_TYPE))
            }
        }
    }

     private val callback = object : MediaSessionCompat.Callback() {
        override fun onMediaButtonEvent(mediaButtonIntent: Intent): Boolean {
            val keyEvent = mediaButtonIntent.extras?.get(Intent.EXTRA_KEY_EVENT)
            Log.d(TAG, "onMediaButtonEvent: $keyEvent")
            return super.onMediaButtonEvent(mediaButtonIntent)
        }

        override fun onPlay() {
            Log.d(TAG, "onPlay: ")
            super.onPlay()
        }

        override fun onCommand(command: String?, extras: Bundle?, cb: ResultReceiver?) {
            Log.d(TAG, "onCommand: ")
            super.onCommand(command, extras, cb)
        }
    }

    override fun onCreate() {
        super.onCreate()
        mediaSession = MediaSessionCompat(applicationContext, "MyForegroundService")
        mediaSession.setFlags(
            MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or
                    MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
        )
        mediaSession.setPlaybackToRemote(getVolumeProvider())
        mediaSession.setCallback(callback)
        mediaSession.setActive(true)

    }

    override fun onBind(intent: Intent?): IBinder? {
        return binder
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        MediaButtonReceiver.handleIntent(mediaSession, intent)
        return START_STICKY
    }

    private fun startForeground() {
        // ...
        startForeground(1, notification)
    }

    override fun onDestroy() {
        super.onDestroy()
        mediaSession.release()
        stopForeground(true)
    }
}
Smith S
  • 13
  • 3
  • Fixed this issue by following the answer from this post https://stackoverflow.com/questions/57709401/service-does-not-receive-multimedia-button-click-events – Smith S Nov 22 '20 at 19:36

1 Answers1

0

Did you register your receiver like:

IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
MediaButtonIntentReceiver r = new MediaButtonIntentReceiver();
filter.setPriority(1000); 
registerReceiver(r, filter); 

look at this example: https://stackoverflow.com/a/38290944/11543864

And I think the receiver in the service in your xml won't work. Use the service only for keeping up your application and then you can receive/listen on different events.

st3ffb3
  • 398
  • 3
  • 15
  • I registered that receiver on the onCreate after this post and it didn't work for me even after I followed that example. Also what do you mean by not having the receiver in the xml? Looking at the documentation it seems like must be added to the tags for the to know where to send the media button actions to. – Smith S Nov 22 '20 at 11:03