darryncampbell / darryncampbell-cordova-plugin-intent

General purpose intent shim layer for cordova appliations on Android. Handles various techniques for sending and receiving intents.
MIT License
86 stars 134 forks source link

Intent.ACTION_MEDIA_BUTTON possible? #72

Closed fquirin closed 5 years ago

fquirin commented 5 years ago

Hi Darryn,

thanks for the great plugin! I'm building an open-source voice assistant (https://sepia-framework.github.io) and the HTML client uses this plugin on Android via Cordova to share timers and reminders with the native calendar/alarms. Works great! :-)

Now the client also has an audio player that (still) works kind of independent of the Android MEDIA events and I was wondering if it is possible to use the plugin for an Intent like this to stop media play:

private static void sendMediaButton(Context context, int keyCode) {
    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
    Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
    intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
    context.sendOrderedBroadcast(intent, null);

    keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
    intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
    intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
    context.sendOrderedBroadcast(intent, null);
}

My main concern is the 'KeyEvent' object that has to be added to extras somehow, but I've no idea how to build it as JSON object or any parsable string. It probably would look something like that:

{
    "action": "android.intent.action.MEDIA_BUTTON",
    "extras": {
        "android.intent.extra.KEY_EVENT": {
            "action": 0, 
            "code": 85
        }
    }
}

with: 0: KeyEvent.ACTION_DOWN 85: KEYCODE_MEDIA_PLAY_PAUSE

Can you help out here? :-)

darryncampbell commented 5 years ago

Hi fquirin,

Thank you for your kind words.

As you say, the missing piece here is how to create the 'keyevent' object as there is no way to create one of these with the current plugin. I don't plan on adding this capability since to be honest as is a very specific use case.

The best thing to do I think would be for you to fork the plugin and modify your fork to detect your specific 'android.intent.extra.KEY_EVENT' extra name about here: https://github.com/darryncampbell/darryncampbell-cordova-plugin-intent/blob/master/src/android/IntentShim.java#L555 and if you detect it, create the keyevent object and put the keyEvent extra in the Intent.

I think that is the right place in the code but you probably want to run it through the debugger just to be sure.

fquirin commented 5 years ago

Hi Darryn,

thanks for pointing me to the right position in code. I've added the KeyEvent, tested it and created a pull request: https://github.com/darryncampbell/darryncampbell-cordova-plugin-intent/pull/73

To make it work I had to stringify the value in extras or the code would never generate the extrasMap :

"extras": {
    "android.intent.extra.KEY_EVENT": JSON.stringify({
        "action": 0,
        "code": 85
    })
}

One thing I noticed is that IntentShim.java has a package-filePath mismatch. package com.darryncampbell.cordova.plugin.intent; is actually in the folder com/darryncampbell/plugin/intent missing "cordova". This does not seem to prevent the plugin from working but Android Studio marks this as an error.

darryncampbell commented 5 years ago

hmmm... I'm not sure about the package mismatch. It is probably wrong but at this point I don't want to change it in case I break anything :) Thanks for the pull request, I have pushed to npm as 1.1.7