1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Thomas Martitz
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 package org
.rockbox
.Helper
;
24 import org
.rockbox
.RockboxFramebuffer
;
25 import org
.rockbox
.RockboxService
;
26 import android
.content
.BroadcastReceiver
;
27 import android
.content
.ComponentName
;
28 import android
.content
.Context
;
29 import android
.content
.Intent
;
30 import android
.content
.IntentFilter
;
31 import android
.media
.AudioManager
;
32 import android
.view
.KeyEvent
;
34 public class MediaButtonReceiver
36 /* A note on the API being used. 2.2 introduces a new and sane API
37 * for handling multimedia button presses
38 * http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html
40 * the old API is flawed. It doesn't have management for
41 * concurrent media apps
43 * if multiple media apps are running
44 * probably all of them want to respond to media keys
46 * it's not clear which app wins, it depends on the
47 * priority set for the IntentFilter (see below)
49 * so this all might or might not work on < 2.2 */
51 IMultiMediaReceiver api
;
53 public MediaButtonReceiver(Context c
)
57 } catch (Throwable t
) {
58 /* Throwable includes Exception and the expected
59 * NoClassDefFoundError */
61 Logger
.i("MediaButtonReceiver: Falling back to compatibility API");
65 public void register()
70 public void unregister()
75 /* helper class for the manifest */
76 public static class MediaReceiver
extends BroadcastReceiver
78 private void startService(Context c
, Intent baseIntent
)
80 baseIntent
.setClass(c
, RockboxService
.class);
81 c
.startService(baseIntent
);
84 public void onReceive(Context context
, Intent intent
)
86 if (Intent
.ACTION_MEDIA_BUTTON
.equals(intent
.getAction()))
88 KeyEvent key
= (KeyEvent
)intent
.getParcelableExtra(Intent
.EXTRA_KEY_EVENT
);
89 if (key
.getAction() == KeyEvent
.ACTION_UP
)
90 { /* pass the pressed key to Rockbox, starting it if needed */
91 RockboxService s
= RockboxService
.getInstance();
92 if (s
== null || !s
.isRockboxRunning())
93 startService(context
, intent
);
94 else if (RockboxFramebuffer
.buttonHandler(key
.getKeyCode(), false))
101 private interface IMultiMediaReceiver
107 private static class NewApi
108 implements IMultiMediaReceiver
, AudioManager
.OnAudioFocusChangeListener
110 private AudioManager audio_manager
;
111 private ComponentName receiver_name
;
112 private boolean running
= false;
116 audio_manager
= (AudioManager
)c
.getSystemService(Context
.AUDIO_SERVICE
);
117 receiver_name
= new ComponentName(c
, MediaReceiver
.class);
120 public void register()
123 audio_manager
.registerMediaButtonEventReceiver(receiver_name
);
124 audio_manager
.requestAudioFocus(this, AudioManager
.STREAM_MUSIC
, AudioManager
.AUDIOFOCUS_GAIN
);
126 } catch (Exception e
) {
132 public void unregister()
136 audio_manager
.unregisterMediaButtonEventReceiver(receiver_name
);
137 audio_manager
.abandonAudioFocus(this);
139 } catch (Exception e
) {
145 public void onAudioFocusChange(int focusChange
)
147 Logger
.d("Audio focus" + ((focusChange
>0)?
"gained":"lost")+
150 { /* Play nice and stop for the the other app */
151 if (focusChange
== AudioManager
.AUDIOFOCUS_LOSS
)
152 RockboxFramebuffer
.buttonHandler(KeyEvent
.KEYCODE_MEDIA_STOP
, false);
158 private static class OldApi
implements IMultiMediaReceiver
160 private static final IntentFilter filter
= new IntentFilter(Intent
.ACTION_MEDIA_BUTTON
);
161 private MediaReceiver receiver
;
162 private Context context
;
165 filter
.setPriority(1); /* 1 higher than the built-in media player */
166 receiver
= new MediaReceiver();
170 public void register()
172 context
.registerReceiver(receiver
, filter
);
175 public void unregister()
177 context
.unregisterReceiver(receiver
);