Amazon Fire TV Controller buttons

I’m trying to detect button presses for the Amazon Fire TV for the Rewind and Forward wind buttons of the TV remote.

It turns out that the Play/Pause button is well mapped in MonoGame to Keys.MediaPlayPause

However the Rewind and Forward wind buttons are not mapped to anything?

Using ILSpy I’m seeing that in Android code

public enum Keycode
...

/// <summary>
	///     <para tool="javadoc-to-mdoc">Key code constant: Fast Forward media key. </para>
	/// </summary>
	[IntDefinition(null, JniField = "android/view/KeyEvent.KEYCODE_MEDIA_FAST_FORWARD")]
	MediaFastForward = 90,
	/// <summary>
	///     <para tool="javadoc-to-mdoc">Key code constant: Play Next media key. </para>
	/// </summary>
	[IntDefinition(null, JniField = "android/view/KeyEvent.KEYCODE_MEDIA_NEXT")]
	MediaNext = 87,

And then in MonoGame code

// Microsoft.Xna.Framework.Input.Keyboard
..
	dictionary[Keycode.MediaPlayPause] = Keys.MediaPlayPause;
	dictionary[Keycode.MediaStop] = Keys.MediaStop;
	dictionary[Keycode.MediaNext] = Keys.MediaNextTrack;
	dictionary[Keycode.MediaPrevious] = Keys.MediaPreviousTrack;

So it looks like there is a key that Android call

KeyEvent.KEYCODE_MEDIA_FAST_FORWARD

(and another for rewind) that are not mapped to any Key in MonoGame, (although KeyEvent.KEYCODE_MEDIA_NEXT is)?

So my question is;

Ideally, is there a way I can detect for these button presses in MonoGame?

or failing that, is there a way to use standard Mono and C# to detect it via the Activity1 class or whatever?

Ok so an update for a way to workaround this issue. It’s not pretty! One issue is having to use event listening before trying to use those values in the Game Loop. So here goes…

Optionally have in interface to represent the buttons you need to capture, eg IHaveStartButtons

Then in Activity1, override the OnKeyUp and OnKeyDown virtual methods and set true/false the button values of interest (in the interface) which are then held in the Activity itself, until such time the game code wants to access those values.

public class Activity1 : Microsoft.Xna.Framework.AndroidGameActivity, IHaveStartButtons
    {
        public bool IsStartButton1Pressed { get; set; }
        public bool IsStartButton2Pressed { get; set; }

        public override bool OnKeyDown([GeneratedEnum] Android.Views.Keycode keyCode, KeyEvent e)
        {
            // If any special buttons are pressed, store the values now.
            if (keyCode == Android.Views.Keycode.MediaRewind)
                IsStartButton1Pressed = true;
            if (keyCode == Android.Views.Keycode.MediaFastForward)
                IsStartButton2Pressed = true;

            return base.OnKeyDown(keyCode, e);
        }

        public override bool OnKeyUp([GeneratedEnum] Android.Views.Keycode keyCode, KeyEvent e)
        {
            if (keyCode == Android.Views.Keycode.MediaRewind)
                IsStartButton1Pressed = false;
            if (keyCode == Android.Views.Keycode.MediaFastForward)
                IsStartButton2Pressed = false;

            return base.OnKeyUp(keyCode, e);
        }
...
}

Then in your game code it becomes something like this to poll the Activity and copy over/make use of our button presses:

// Poll the Activity to detect for button presses this frame.
IHaveStartButtons activity = Game.Activity as IHaveStartButtons;
if (activity != null)
{
    if (activity.IsStartButton1Pressed)
        this.IsStartButton1Pressed = true;
    if (activity.IsStartButton2Pressed)
        this.IsStartButton2Pressed = true;
}

It would have been much better to have been able to externally listen for key events from the Activity but it seemed I could only use the overrides on the Activity itself.

Perhaps in future these keyboard key mappings could be included as standard in MonoGame as surely it wouldn’t break anything to add new keys that were never present in Xna/Windows but extends the reach of MonoGame to new platforms with greater ease and clarity