Kamis, 03 Juni 2010

Allowing applications to play nice(r) with each other: Handling remote control buttons

[This post is by Jean-Michel Trivi, an operative working upon the Android Media framework, whose T-shirt of the day reads all your media buttons have been go to you. Tim Bray]

Many Android inclination come with the Music duplicate used to fool around audio files stored upon the device. Some inclination ship with the wired headset which facilities transport carry out buttons, so users can for example conveniently postponement as well as restart song playback, directly from the headset.

But the user might make make make make use of of of of the single duplicate for song listening, as well as an additional for listening to podcasts, both of which should be controlled by the headset remote control.

If your media playback duplicate creates the media playback service, only like Music, which responds to the media symbol events, how will the user know where those events have been going to? Music, or your brand brand brand brand brand new application?

In this article, well see how to hoop this properly in Android 2.2. Well first see how to set up intents to embrace MEDIA_BUTTON intents. Well afterwards report how your duplicate can appropriately turn the elite media symbol responder in Android 2.2. Since this underline relies upon the brand brand brand brand brand new API, well revisit the make make make make use of of of of of thoughtfulness to hope for your app to take value of Android 2.2, but restricting it to API turn 8 (Android 2.2).

An e.g. of the doing of media symbol intents

In the AndroidManifest.xml for this package you acknowledgement the category RemoteControlReceiver to embrace MEDIA_BUTTON intents:

<receiver android:name="RemoteControlReceiver"> <intent-filter> <action android:name="android.intent.action.MEDIA_BUTTON" /> </intent-filter></receiver>

Our category to hoop those intents can look something like this:

public category RemoteControlReceiver extends BroadcastReceiver { @Override open blank onReceive(Context context, Intent intent) { if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) { /* hoop media symbol vigilant here by celebration of the mass contents */ /* of EXTRA_KEY_EVENT to know which pass was pulpy */ } }}

In the media playback application, this is used to conflict to headset symbol presses when your wake up doesnt have the focus. For when it does, you override the Activity.onKeyDown() or onKeyUp() methods for the user interface to trap the headset button-related events.

However, this is problematic in the unfolding you referred to earlier. When the user presses play, what duplicate should begin playing? The Music application? The users elite podcast application?

Becoming the elite media symbol responder

In Android 2.2, you have been introducing dual brand brand brand brand brand new methods in android.media.AudioManager to acknowledgement your intention to turn the elite member to embrace media symbol events: registerMediaButtonEventReceiver() as well as the counterpart, unregisterMediaButtonEventReceiver(). Once the registration call is placed, the directed towards member will exclusively embrace the ACTION_MEDIA_BUTTON vigilant only as in the e.g. above.

In the wake up next were have been formulating an example of AudioManager with which you will register the component. We thus create the ComponentName example which references the dictated media symbol event responder.

public category MyMediaPlaybackActivity extends Activity { in isolation AudioManager mAudioManager; in isolation ComponentName mRemoteControlResponder; @Override open blank onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE); mRemoteControlResponder = brand brand brand brand brand new ComponentName(getPackageName(), RemoteControlReceiver.class.getName());}

The complement handles the media symbol registration requests in the last the single wins manner. This equates to you need to name where it creates clarity for the user to make this request. In the media playback application, proper uses of the registration have been for instance:

  • when the UI is displayed: the user is interacting with which application, so (s)he expects it to be the a single which will reply to the remote control,

  • when calm starts personification (e.g. calm accomplished downloading, or an additional duplicate caused your make make make use of of of to fool around content)

Registering is here performed for example when the UI comes to the foreground:

@Override open blank onResume() { super.onResume(); mAudioManager.registerMediaButtonEventReceiver( mRemoteControlResponder); }

If you had formerly registered the receiver, induction it again will pull it up the stack, as well as doesnt means any duplicate registration.

Additionally, it might make clarity for your registered member not to be called when your make make make use of of of or duplicate is broken (as illustrated below), or under conditions which have been specific to your application. For instance, in an duplicate which reads to the user her/his appointments of the day, it could unregister when the finished speaking the monthly calendar entries of the day.

@Override open blank onDestroy() { super.onDestroy(); mAudioManager.unregisterMediaButtonEventReceiver( mRemoteControlResponder); }

After unregistering, the previous member which requested to embrace the media symbol intents will once again embrace them.

Preparing your formula for Android 2.2 but restricting it to Android 2.2

While you might conclude the benefit this brand brand brand brand brand new API offers to the users, you might not wish to shorten your duplicate to inclination which await this feature. Andy McFadden shows us how to make make make make use of of of of thoughtfulness to take value of facilities which have been not available upon all devices. Lets make make make make use of of of of what you learned afterwards to capacitate your duplicate to make make make make use of of of of the brand brand brand brand brand new media symbol mechanism when it runs upon inclination which await this feature.

First you acknowledgement in the Activity the dual brand brand brand brand brand new methods you have used formerly for the registration mechanism:

in isolation immobile Method mRegisterMediaButtonEventReceiver; in isolation immobile Method mUnregisterMediaButtonEventReceiver;

We afterwards add the process which will make make make make use of of of of thoughtfulness upon the android.media.AudioManager category to find the dual methods when the underline is supported:

private immobile blank initializeRemoteControlRegistrationMethods() { try { if (mRegisterMediaButtonEventReceiver == null) { mRegisterMediaButtonEventReceiver = AudioManager.class.getMethod( "registerMediaButtonEventReceiver", brand brand brand brand brand new Class[] { ComponentName.class } ); } if (mUnregisterMediaButtonEventReceiver == null) { mUnregisterMediaButtonEventReceiver = AudioManager.class.getMethod( "unregisterMediaButtonEventReceiver", brand brand brand brand brand new Class[] { ComponentName.class } ); } /* success, this device will take value of improved remote */ /* carry out event doing */ } locate (NoSuchMethodException nsme) { /* failure, still regulating the legacy behavior, but this app */ /* is future-proof! */ }}

The process fields will need to be initialized when the Activity category is loaded:

immobile { initializeRemoteControlRegistrationMethods(); }

Were roughly done. Our formula will be easier to read as well as say if you hang the make make make make use of of of of of the methods initialized through thoughtfulness by the following. Note in bold the actual process invocation upon the AudioManager instance:

in isolation blank registerRemoteControl() { try { if (mRegisterMediaButtonEventReceiver == null) { return; } mRegisterMediaButtonEventReceiver.invoke(mAudioManager, mRemoteControlResponder); } locate (InvocationTargetException ite) { /* empty strange difference when probable */ Throwable means = ite.getCause(); if (cause instanceof RuntimeException) { chuck (RuntimeException) cause; } else if (cause instanceof Error) { chuck (Error) cause; } else { /* astonishing checked exception; hang as well as re-throw */ chuck brand brand brand brand brand new RuntimeException(ite); } } locate (IllegalAccessException ie) { Log.e(MyApp, "unexpected " + ie); } } in isolation blank unregisterRemoteControl() { try { if (mUnregisterMediaButtonEventReceiver == null) { return; } mUnregisterMediaButtonEventReceiver.invoke(mAudioManager, mRemoteControlResponder); } locate (InvocationTargetException ite) { /* empty strange difference when probable */ Throwable means = ite.getCause(); if (cause instanceof RuntimeException) { chuck (RuntimeException) cause; } else if (cause instanceof Error) { chuck (Error) cause; } else { /* astonishing checked exception; hang as well as re-throw */ chuck brand brand brand brand brand new RuntimeException(ite); } } locate (IllegalAccessException ie) { System.err.println("unexpected " + ie); } }

We have been now ready to make make make make use of of of of the dual brand brand brand brand brand new methods, registerRemoteControl() as well as unregisterRemoteControl() in the project which runs upon inclination supporting API turn 1, while still taking value of the facilities found in inclination running Android 2.2.


Posted by Generation Funky and gaul abisss. I'm here to change the World..
MOTORCYCLE MODIFICATION, MODIFIKASI MOTOR, GAMBAR, WALLPAPER. Gaul Abisss

Photography

Tidak ada komentar:

Posting Komentar