1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.music; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.media.AudioManager; 23 import android.os.Handler; 24 import android.os.Message; 25 import android.view.KeyEvent; 26 27 /** 28 * 29 */ 30 public class MediaButtonIntentReceiver extends BroadcastReceiver { 31 32 private static final int MSG_LONGPRESS_TIMEOUT = 1; 33 private static final int LONG_PRESS_DELAY = 1000; 34 35 private static long mLastClickTime = 0; 36 private static boolean mDown = false; 37 private static boolean mLaunched = false; 38 39 private static Handler mHandler = new Handler() { 40 @Override 41 public void handleMessage(Message msg) { 42 switch (msg.what) { 43 case MSG_LONGPRESS_TIMEOUT: 44 if (!mLaunched) { 45 Context context = (Context)msg.obj; 46 Intent i = new Intent(); 47 i.putExtra("autoshuffle", "true"); 48 i.setClass(context, MusicBrowserActivity.class); 49 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 50 context.startActivity(i); 51 mLaunched = true; 52 } 53 break; 54 } 55 } 56 }; 57 58 @Override 59 public void onReceive(Context context, Intent intent) { 60 String intentAction = intent.getAction(); 61 if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intentAction)) { 62 Intent i = new Intent(context, MediaPlaybackService.class); 63 i.setAction(MediaPlaybackService.SERVICECMD); 64 i.putExtra(MediaPlaybackService.CMDNAME, MediaPlaybackService.CMDPAUSE); 65 context.startService(i); 66 } else if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) { 67 KeyEvent event = (KeyEvent) 68 intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 69 70 if (event == null) { 71 return; 72 } 73 74 int keycode = event.getKeyCode(); 75 int action = event.getAction(); 76 long eventtime = event.getEventTime(); 77 78 // single quick press: pause/resume. 79 // double press: next track 80 // long press: start auto-shuffle mode. 81 82 String command = null; 83 switch (keycode) { 84 case KeyEvent.KEYCODE_MEDIA_STOP: 85 command = MediaPlaybackService.CMDSTOP; 86 break; 87 case KeyEvent.KEYCODE_HEADSETHOOK: 88 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 89 command = MediaPlaybackService.CMDTOGGLEPAUSE; 90 break; 91 case KeyEvent.KEYCODE_MEDIA_NEXT: 92 command = MediaPlaybackService.CMDNEXT; 93 break; 94 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 95 command = MediaPlaybackService.CMDPREVIOUS; 96 break; 97 case KeyEvent.KEYCODE_MEDIA_PAUSE: 98 command = MediaPlaybackService.CMDPAUSE; 99 break; 100 case KeyEvent.KEYCODE_MEDIA_PLAY: 101 command = MediaPlaybackService.CMDPLAY; 102 break; 103 } 104 105 if (command != null) { 106 if (action == KeyEvent.ACTION_DOWN) { 107 if (mDown) { 108 if ((MediaPlaybackService.CMDTOGGLEPAUSE.equals(command) || 109 MediaPlaybackService.CMDPLAY.equals(command)) 110 && mLastClickTime != 0 111 && eventtime - mLastClickTime > LONG_PRESS_DELAY) { 112 mHandler.sendMessage( 113 mHandler.obtainMessage(MSG_LONGPRESS_TIMEOUT, context)); 114 } 115 } else if (event.getRepeatCount() == 0) { 116 // only consider the first event in a sequence, not the repeat events, 117 // so that we don't trigger in cases where the first event went to 118 // a different app (e.g. when the user ends a phone call by 119 // long pressing the headset button) 120 121 // The service may or may not be running, but we need to send it 122 // a command. 123 Intent i = new Intent(context, MediaPlaybackService.class); 124 i.setAction(MediaPlaybackService.SERVICECMD); 125 if (keycode == KeyEvent.KEYCODE_HEADSETHOOK && 126 eventtime - mLastClickTime < 300) { 127 i.putExtra(MediaPlaybackService.CMDNAME, MediaPlaybackService.CMDNEXT); 128 context.startService(i); 129 mLastClickTime = 0; 130 } else { 131 i.putExtra(MediaPlaybackService.CMDNAME, command); 132 context.startService(i); 133 mLastClickTime = eventtime; 134 } 135 136 mLaunched = false; 137 mDown = true; 138 } 139 } else { 140 mHandler.removeMessages(MSG_LONGPRESS_TIMEOUT); 141 mDown = false; 142 } 143 if (isOrderedBroadcast()) { 144 abortBroadcast(); 145 } 146 } 147 } 148 } 149 } 150