package cn.qylk.service; import java.io.IOException; import java.util.List; import java.util.Timer; import java.util.TimerTask; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; 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.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.audiofx.Equalizer; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; import cn.qylk.ListUI; import cn.qylk.R; import cn.qylk.app.APP; import cn.qylk.app.IPlayList.PlayMode; import cn.qylk.app.MediaBtnReceiver; import cn.qylk.app.MyAction; import cn.qylk.app.SensorTest; import cn.qylk.app.SleepTimer; import cn.qylk.app.TrackInfo; import cn.qylk.lrc.LRCbean; import cn.qylk.lrc.MediaLyric; import cn.qylk.myview.DesktopLrc; import cn.qylk.myview.LrcPackage; import cn.qylk.utils.ID3; import cn.qylk.utils.SendAction; import cn.qylk.utils.SendAction.ServiceControl; /** * 后台服务 * * @author qylk2011 all rights resolved */ public class LocalService extends Service { // 服务 public class MyBinder extends Binder { public LocalService getService() { return LocalService.this; } } /** * 因为本程序支持后台无界面播放,当前台UI销毁后,<br> * 考虑到如有电话接入,也必须停止或暂停播放,因此只能<br> * 把广播设置在service中 */ private class T_Receiver extends PhoneStateListener { @Override public void onCallStateChanged(int state, String incomingNumber) { if (state == TelephonyManager.CALL_STATE_RINGING) {// 有电话接入 if (mPlayer.isPlaying()) PauseOrContinue(true); } super.onCallStateChanged(state, incomingNumber); } } private class task extends TimerTask { @Override public void run() { if (mPlayer.isPlaying()) { if (deslrc != null) deslrc.updateView(GetMediaPos()); if (listener != null) listener.ontimeout(GetMediaPos()); if (++i == 10) sendPosition(GetMediaPos()); } } } public interface TimerOut { public void ontimeout(int pos); } private static final int NOTIFICATION_ID = 4332; private static final String TAG="Q_LocalService"; private MyBinder binder = new MyBinder(); /** * 播放远程控制 */ private BroadcastReceiver Control = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(MyAction.INTENT_BTNACTION)) { Bundle bundle = intent.getExtras(); ServiceControl control = (ServiceControl) bundle .getSerializable("action"); switch (control) { case PRE:// 上一首 pre(); break; case NEXT:// 下一首 next(); break; case PAUSE_CONTINE: PauseOrContinue(mPlayer.isPlaying()); break; case PAUSE: PauseOrContinue(true); break; case PLAYNEW: play(); break; default: break; } } else if (action.equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) { if (APP.Config.unplunge) PauseOrContinue(true); } } }; private DesktopLrc deslrc; private Equalizer eq; private boolean flag; private int i; private TimerOut listener; private AudioManager mAudioManager; private ComponentName mbCN; private MediaPlayer mPlayer;// 播放器 private NotificationManager NM; private int SysMaxVolume; private Timer timer; private TrackInfo track; private WakeLock wakeLock;// 用于阻止睡眠的锁 /** * 调整音量 * * @param value * :(以100为最大值) */ public void AdjVolume(int value) { mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int) SysMaxVolume * value / 100, 0); } private void cancelNotification() { NM.cancel(NOTIFICATION_ID); } private void dealDeskLrc() { List<LRCbean> lrc = MediaLyric.FetchLyric(track, -1); if (lrc != null) { deslrc.setLyric(new LrcPackage(lrc, track)); deslrc.initLrcIndex(GetMediaPos()); } } public void DesktopLrc(boolean show) { if (show) { deslrc = new DesktopLrc(this); dealDeskLrc(); } else if (deslrc != null) { deslrc.destoryView(this); deslrc = null; } } public int getAudioSessionId() { return mPlayer.getAudioSessionId(); } /** * 获取当前的预置EQ * * @return */ public short getEQ() { return eq.getCurrentPreset(); } /** * 获取播放实时位置 */ public int GetMediaPos() { return mPlayer.getCurrentPosition(); } private int getSysMaxVolume() { return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);// 系统音量最大值,并非100 } /** * 获取音频流音量,已换算成百分制,以100为最大音量 */ public int getVolume() { return (int) mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) * 100 / SysMaxVolume; } /** * 恢复上一次播放位置 */ private void InitMediaStatus() { try { InitPlayer(); mPlayer.seekTo(APP.Config.lastbarekpoint); mPlayer.pause(); SendStatusChanged(false); } catch (IOException e) { Log.v(TAG, "IOException in init MediaPlayer"); } catch (IllegalArgumentException e) { Log.v(TAG, "IllegalArgumentException in init MediaPlayer"); } } private void InitPlayer() throws IOException, IllegalArgumentException { SendAction.SendMsg_UI_Update(); mPlayer.reset(); mPlayer.setDataSource(track.path); mPlayer.prepare(); mPlayer.start(); if (flag) { TrackInfo info = APP.list.getPreviousEntity(); if (info.id != track.id) new ID3().SaveId3v2(info); flag = false; } } /** * 是否在播放 * * @return */ public boolean IsPlaying() { if (mPlayer != null) return mPlayer.isPlaying(); else return false; } /** * 下一首 */ public void next() {// 下一首 APP.list.goNext(); play(); } private void Notification(int msg) { Notification(getResources().getString(msg)); } /** * 通知栏信息 */ private void Notification(String msg) { PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, ListUI.class), 0); Notification notification = new Notification.Builder(this) .setContentIntent(contentIntent) .setSmallIcon(R.drawable.myicon) .setWhen(System.currentTimeMillis()).setAutoCancel(false) .setContentTitle("QMUSIC PLAYING").setContentText(msg) .getNotification(); startForeground(NOTIFICATION_ID, notification); } @Override public IBinder onBind(Intent intent) { Log.v(TAG, "OnBind"); return binder; } @Override public void onCreate() { Log.v(TAG, "Service Creating"); PowerManager pm = (PowerManager) getApplicationContext() .getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Service"); wakeLock.acquire(); IntentFilter filter = new IntentFilter(); filter.addAction(MyAction.INTENT_BTNACTION);// 过滤器设置 filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY); registerReceiver(Control, filter);// 注册广播接收器 TelephonyManager manager = (TelephonyManager) this .getSystemService(TELEPHONY_SERVICE); manager.listen(new T_Receiver(), PhoneStateListener.LISTEN_CALL_STATE);// 监听电话状态 NM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification(R.string.qylk);// 通知栏提示信息提示 track = APP.list.getTrackEntity(); mPlayer = new MediaPlayer(); mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mPlayer.setOnCompletionListener(new OnCompletionListener() {// 一曲完成,自动播放下一曲 @Override public void onCompletion(MediaPlayer mp) { if (APP.list.getMode() != PlayMode.Repeat_One) { next(); } else play(); } }); InitMediaStatus(); eq = new Equalizer(0, getAudioSessionId()); eq.setEnabled(true);// 启用均衡器 setEQ(APP.Config.eq);//恢复上次EQ设置 mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); mbCN = new ComponentName(getPackageName(), MediaBtnReceiver.class.getName()); mAudioManager.registerMediaButtonEventReceiver(mbCN);// 注册一个MedioButtonReceiver广播监听 SysMaxVolume = getSysMaxVolume(); startTimer(); Log.v(TAG, "Service Created"); } @Override public void onDestroy() { super.onDestroy(); timercancel(); cancelNotification(); SleepTimer.getInstance().cancel();// 取消睡眠定时器 APP.Config.StoreLast(GetMediaPos());// 存储断点 SendStatusChanged(false); if (wakeLock != null) { wakeLock.release();// 释放睡眠锁 wakeLock = null; } mPlayer.stop(); mPlayer.release(); mAudioManager.unregisterMediaButtonEventReceiver(mbCN); unregisterReceiver(Control);// 解注册 DesktopLrc(false);// 关闭桌面歌词 SensorTest.getInstance().StopService();// 关闭感应器 Log.v(TAG, "Service Destory"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_NOT_STICKY;// 非粘滞 } /** * 暂停或继续 * * @param pause * true:pause<br> * false otherwise */ public void PauseOrContinue(boolean pause) {// 暂停播放 if (pause) { mPlayer.pause(); } else { mPlayer.start(); } SendStatusChanged(!pause); } /** * 播放 */ private void play() {// 播放 try { Notification(track.title + "-->" + track.artist); InitPlayer(); if (deslrc != null) dealDeskLrc(); } catch (Exception e) { Log.e(TAG, "ERROR IN PLAY()"); } } /** * 上一首 */ public void pre() {// 上一首 APP.list.goLast(); play(); } /** * 播发歌曲进度 * * @param pos */ private void sendPosition(int pos) { i = 0; Intent intent = new Intent(MyAction.INTENT_POSITION); intent.putExtra("pos", pos); sendBroadcast(intent);// 向UI发送消息,告知当前歌曲id } /** * 发送后台歌曲播放状态 * * @return Bundle */ private void SendStatusChanged(boolean isplaying) { SendAction.SendStatusChanged(isplaying); } /** * 设置预置EQ * * @param preset * :The valid range may be [0, 9] */ public void setEQ(short preset) { eq.usePreset(preset); } /** * 设置播放位置 */ public void SetMediaPos(int pos) { mPlayer.seekTo(pos); } /** * 设置更改ID3V2的消息标志,此动作将在歌曲播放完以后执行 * * @param rw * :false to cancel this msg */ public void setRWFlag(boolean rw) { this.flag = rw; } public void setTimeOutListener(TimerOut listener) { this.listener = listener; } private void startTimer() { timer = new Timer(); timer.schedule(new task(), 0, 100); } public void timercancel() { if (timer != null) { timer.cancel(); timer.purge(); timer = null; } } }