forked from len0rd/rockbox
Add support multimedia keys/buttons to the core, and adapt Rockbox on android for it (multimedia buttons are found on wired headsets and the lock screen in cyanogenmod).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28421 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
dbe2ac1ec6
commit
49f1ec8e8a
13 changed files with 300 additions and 17 deletions
|
@ -16,10 +16,21 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name=".RockboxService"/>
|
||||
<receiver android:name=".Helper.MediaButtonReceiver$MediaReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity android:name="KeyboardActivity"></activity>
|
||||
<activity android:name="YesnoActivity"></activity>
|
||||
</application>
|
||||
<uses-sdk android:minSdkVersion="4" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
||||
|
||||
|
||||
|
||||
|
||||
</manifest>
|
||||
|
|
164
android/src/org/rockbox/Helper/MediaButtonReceiver.java
Normal file
164
android/src/org/rockbox/Helper/MediaButtonReceiver.java
Normal file
|
@ -0,0 +1,164 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2010 Thomas Martitz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
package org.rockbox.Helper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.rockbox.RockboxService;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
public class MediaButtonReceiver
|
||||
{
|
||||
/* A note on the API being used. 2.2 introduces a new and sane API
|
||||
* for handling multimedia button presses
|
||||
* http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html
|
||||
*
|
||||
* the old API is flawed. It doesn't have management for
|
||||
* concurrent media apps
|
||||
*
|
||||
* if multiple media apps are running
|
||||
* probably all of them want to respond to media keys
|
||||
*
|
||||
* it's not clear which app wins, it depends on the
|
||||
* priority set for the IntentFilter (see below)
|
||||
*
|
||||
* so this all might or might not work on < 2.2 */
|
||||
|
||||
IMultiMediaReceiver api;
|
||||
|
||||
public MediaButtonReceiver(Context c)
|
||||
{
|
||||
try {
|
||||
api = new NewApi(c);
|
||||
} catch (Exception e) {
|
||||
api = new OldApi(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void register()
|
||||
{
|
||||
api.register();
|
||||
}
|
||||
|
||||
public void unregister()
|
||||
{
|
||||
api.register();
|
||||
}
|
||||
|
||||
/* helper class for the manifest */
|
||||
public static class MediaReceiver extends BroadcastReceiver
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()))
|
||||
{
|
||||
KeyEvent key = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
|
||||
if (key.getAction() == KeyEvent.ACTION_UP)
|
||||
{ /* pass the pressed key to Rockbox */
|
||||
if (RockboxService.get_instance().get_fb().dispatchKeyEvent(key))
|
||||
abortBroadcast();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private interface IMultiMediaReceiver
|
||||
{
|
||||
void register();
|
||||
void unregister();
|
||||
}
|
||||
|
||||
private static class NewApi implements IMultiMediaReceiver
|
||||
{
|
||||
private Method register_method;
|
||||
private Method unregister_method;
|
||||
private AudioManager audio_manager;
|
||||
private ComponentName receiver_name;
|
||||
/* the constructor gets the methods through reflection so that
|
||||
* this compiles on pre-2.2 devices */
|
||||
NewApi(Context c) throws SecurityException, NoSuchMethodException
|
||||
{
|
||||
register_method = AudioManager.class.getMethod(
|
||||
"registerMediaButtonEventReceiver",
|
||||
new Class[] { ComponentName.class } );
|
||||
unregister_method = AudioManager.class.getMethod(
|
||||
"unregisterMediaButtonEventReceiver",
|
||||
new Class[] { ComponentName.class } );
|
||||
|
||||
audio_manager = (AudioManager)c.getSystemService(Context.AUDIO_SERVICE);
|
||||
receiver_name = new ComponentName(c, MediaReceiver.class);
|
||||
}
|
||||
public void register()
|
||||
{
|
||||
try {
|
||||
register_method.invoke(audio_manager, receiver_name);
|
||||
} catch (Exception e) {
|
||||
// Nothing
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister()
|
||||
{
|
||||
try
|
||||
{
|
||||
unregister_method.invoke(audio_manager, receiver_name);
|
||||
} catch (Exception e) {
|
||||
// Nothing
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class OldApi implements IMultiMediaReceiver
|
||||
{
|
||||
private static final IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
|
||||
private MediaReceiver receiver;
|
||||
private Context context;
|
||||
OldApi(Context c)
|
||||
{
|
||||
filter.setPriority(1); /* 1 higher than the built-in media player */
|
||||
receiver = new MediaReceiver();
|
||||
context = c;
|
||||
}
|
||||
|
||||
public void register()
|
||||
{
|
||||
context.registerReceiver(receiver, filter);
|
||||
}
|
||||
|
||||
public void unregister()
|
||||
{
|
||||
context.unregisterReceiver(receiver);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ package org.rockbox;
|
|||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.rockbox.Helper.MediaButtonReceiver;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
|
@ -35,6 +37,7 @@ public class RockboxFramebuffer extends View
|
|||
{
|
||||
private Bitmap btm;
|
||||
private ByteBuffer native_buf;
|
||||
private MediaButtonReceiver media_monitor;
|
||||
|
||||
public RockboxFramebuffer(Context c, int lcd_width,
|
||||
int lcd_height, ByteBuffer native_fb)
|
||||
|
@ -47,6 +50,8 @@ public class RockboxFramebuffer extends View
|
|||
btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565);
|
||||
native_buf = native_fb;
|
||||
requestFocus();
|
||||
media_monitor = new MediaButtonReceiver(c);
|
||||
media_monitor.register();
|
||||
/* the service needs to know the about us */
|
||||
((RockboxService)c).set_fb(this);
|
||||
}
|
||||
|
@ -122,6 +127,12 @@ public class RockboxFramebuffer extends View
|
|||
set_lcd_active(1);
|
||||
}
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
suspend();
|
||||
media_monitor.unregister();
|
||||
}
|
||||
|
||||
public native void set_lcd_active(int active);
|
||||
public native void touchHandler(boolean down, int x, int y);
|
||||
public native boolean buttonHandler(int keycode, boolean state);
|
||||
|
|
|
@ -139,6 +139,7 @@ public class RockboxService extends Service
|
|||
{
|
||||
public void run()
|
||||
{
|
||||
LOG("main");
|
||||
/* the following block unzips libmisc.so, which contains the files
|
||||
* we ship, such as themes. It's needed to put it into a .so file
|
||||
* because there's no other way to ship files and have access
|
||||
|
@ -276,6 +277,7 @@ public class RockboxService extends Service
|
|||
public void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
fb.destroy();
|
||||
/* Make sure our notification is gone. */
|
||||
stopForeground();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue