Skip to content

Instantly share code, notes, and snippets.

@suanmiao
Created March 24, 2015 03:46
Show Gist options
  • Save suanmiao/46970b3007327c114d0f to your computer and use it in GitHub Desktop.
Save suanmiao/46970b3007327c114d0f to your computer and use it in GitHub Desktop.
package com.wandoujia.roshan.notification;
import java.util.List;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.Context;
import android.media.AudioManager;
import android.media.RemoteController;
import android.os.Build;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
import com.wandoujia.base.reflect.JavaCalls;
import com.wandoujia.roshan.R;
import com.wandoujia.roshan.app.RoshanApplication;
import com.wandoujia.roshan.app.runtime.RoshanRuntime;
import com.wandoujia.roshan.global.config.online.OnlineConfigHelper;
import com.wandoujia.roshan.global.constants.Constants;
import com.wandoujia.roshan.notification.monitor.MusicMonitor;
/**
* @author suan@wandoujia.com
*
* created to add music remote control and listener on api 19
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public class NotificationAndMusicStateListener extends SystemNotificationListener
implements RemoteController.OnClientUpdateListener {
private static final String TAG = "NotificationAndMusicStateListener";
private static NotificationAndMusicStateListener INSTANCE;
private RemoteController remoteController;
private MusicMonitor.MusicStateUpdateListener musicUpdateListener;
private boolean clientIdLost = false;
public static boolean isServiceEnable(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (manager != null) {
List<ActivityManager.RunningServiceInfo> serviceInfoList =
manager.getRunningServices(Integer.MAX_VALUE);
if (serviceInfoList != null) {
for (ActivityManager.RunningServiceInfo service : serviceInfoList) {
if (NotificationAndMusicStateListener.class.getName().equals(
service.service.getClassName()) && service.clientCount > 0) {
return true;
}
}
}
}
return false;
}
public static NotificationAndMusicStateListener getInstance() {
return INSTANCE;
}
@Override
public void onCreate() {
super.onCreate();
final RoshanRuntime runtime = (RoshanRuntime) ((RoshanApplication)
getApplicationContext()).getAppRuntime();
Handler eventHandler = runtime.getEventHandler();
eventHandler.sendEmptyMessage(Constants.Event.EVENT_MONITOR_SERVICE_CREATED);
INSTANCE = this;
Thread loadOngoingConfigTask = new Thread(TAG) {
@Override
public void run() {
ongoingList = OnlineConfigHelper.getOngoingList();
}
};
loadOngoingConfigTask.start();
}
@Override
public void onDestroy() {
if (INSTANCE == this) {
INSTANCE = null;
}
super.onDestroy();
}
public void setMusicUpdateListener(MusicMonitor.MusicStateUpdateListener listener) {
this.musicUpdateListener = listener;
}
public void registerRemoteController() {
remoteController = new RemoteController(this, this);
boolean registered;
try {
registered = ((AudioManager) getSystemService(AUDIO_SERVICE))
.registerRemoteController(remoteController);
} catch (NullPointerException e) {
registered = false;
}
if (registered) {
try {
remoteController.setArtworkConfiguration(
getResources().getDimensionPixelSize(R.dimen.remote_artwork_bitmap_width),
getResources().getDimensionPixelSize(R.dimen.remote_artwork_bitmap_height));
remoteController.setSynchronizationMode(RemoteController.POSITION_SYNCHRONIZATION_CHECK);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
public void unregisterRemoteController() {
((AudioManager) getSystemService(AUDIO_SERVICE)).unregisterRemoteController(remoteController);
}
public boolean sendMusicKeyEvent(int keyCode) {
Log.d(TAG, "send music event ,remoteController:" + remoteController + " clientIdLost:"
+ clientIdLost + " keycode:" + keyCode);
if (!clientIdLost && remoteController != null) {
// send "down" and "up" key events.
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
boolean down = remoteController.sendMediaKeyEvent(keyEvent);
keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
boolean up = remoteController.sendMediaKeyEvent(keyEvent);
Log.d(TAG, "send music event through remoteController key down:" + down + " key up:"
+ up);
return down && up;
} else {
Log.d(TAG, "send music event through audioManager ");
long eventTime = SystemClock.uptimeMillis();
KeyEvent key = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyCode, 0);
dispatchMediaKeyToAudioService(key);
dispatchMediaKeyToAudioService(KeyEvent.changeAction(key, KeyEvent.ACTION_UP));
}
return false;
}
private void dispatchMediaKeyToAudioService(KeyEvent event) {
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioManager != null) {
try {
audioManager.dispatchMediaKeyEvent(event);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onClientChange(boolean clearing) {
if (clearing) {
clientIdLost = true;
}
if (musicUpdateListener != null) {
musicUpdateListener.onClientChange(clearing, getTargetPkgName());
}
}
@Override
public void onClientPlaybackStateUpdate(int state) {
if (musicUpdateListener != null) {
musicUpdateListener.onClientPlaybackStateUpdate(state, getTargetPkgName());
}
}
@Override
public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs, long currentPosMs,
float speed) {
clientIdLost = false;
if (musicUpdateListener != null) {
musicUpdateListener
.onClientPlaybackStateUpdate(state, getTargetPkgName(), stateChangeTimeMs, currentPosMs,
speed);
}
}
@Override
public void onClientTransportControlUpdate(int transportControlFlags) {
clientIdLost = false;
if (musicUpdateListener != null) {
musicUpdateListener.onClientTransportControlUpdate(transportControlFlags);
}
}
@Override
public void onClientMetadataUpdate(RemoteController.MetadataEditor metadataEditor) {
clientIdLost = false;
if (musicUpdateListener != null) {
musicUpdateListener.onClientMetadataUpdate(metadataEditor);
}
}
private String getTargetPkgName() {
if (remoteController != null) {
PendingIntent mClientPendingIntentCurrent =
JavaCalls.getField(remoteController, "mClientPendingIntentCurrent");
if (mClientPendingIntentCurrent != null) {
return mClientPendingIntentCurrent.getCreatorPackage();
}
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment