播放器:bilibili IJKplayer 的 exoplayer 框架
播放器service代码:
public class PlayerService extends Service {
private IjkExoMediaPlayer player;
public static final int PLAYING = 1;//正在播放
public static final int PLAYSTOP = 2;//停止
public static final int PLAYPAUSE = 3;// 暂停
public int playerState = PLAYSTOP;
public ArrayList
public int position;
public int currentTime;
public int seekTime = 0;
public int update = 0;
public int intenetState = NOINTENET;
public static final int NOINTENET = 0;//网络状态
public static final int WIFY = 1;
public static final int PHONE = 2;
public int buffering = 0;//缓冲进度
public int clock = 0; // 定时
public boolean isPauseForCall = false; //是否因为来电导致播放暂停
public int allTims=0; //播放总时长
PhoneStateListener phoneStateListener = new PhoneStateListener() {// 来电监听 来电暂停 结束继续播放
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
if (state == TelephonyManager.CALL_STATE_RINGING) {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int ringvolume = audioManager
.getStreamVolume(AudioManager.STREAM_RING);
if (ringvolume > 0) {
if (player != null && player.isPlaying()) {
isPauseForCall = true;
pause();
}
}
} else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
if (player != null && player.isPlaying()) {
isPauseForCall = true;
pause();
}
} else if (state == TelephonyManager.CALL_STATE_IDLE) {
if (isPauseForCall) { //是否是电话导致播放器暂停
reStart();
isPauseForCall = false;
}
}
}
};
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Common.GET_OK:
setData(msg.obj.toString());
break;
case Common.INIT_OK:
handler.sendEmptyMessageDelayed(Common.INIT_OK, 1000);
if (player != null && player.getCurrentPosition() > 0) {//广播发送 缓冲 和播放时间
buffering=player.getBufferedPercentage();
currentTime = (int) player.getCurrentPosition();
Intent intent = new Intent();
intent.setAction(Common.PlayerTime);
intent.putExtra("currentTime", currentTime);
intent.putExtra("buffering", buffering);
sendBroadcast(intent);
}
if (update == 0) {//播放记录
update++;
if (sharedPreferences != null) {// 用户最后一次播放记录
sharedPreferences.edit().putString("bookid", currentBookId).putString("cid", currentCid).putInt("time", currentTime).putInt("position", position).apply();
}
} else {
if (update >= 6) {
update = 0;
if (sharedPreferences != null) {//每本书的最后的播放记录 6秒更新一次
sharedPreferences.edit().putString("bookid", currentBookId).putString("cid", currentCid).putInt("time", currentTime).putInt("position", position).apply();
}
if (player!=null&&changeHistoryDao != null&& player.getCurrentPosition() > 0) {
changeHistoryDao.updateHistory(currentCid, currentTime + "", currentBookId);
}
} else {
update++;
}
}
if (Common.clock != 1) {//定时器 到时间自动停止播放
switch (Common.clock) {
case 2:
if (clock < 600) {
clock++;
} else {
Common.clock = 1;
clock = 0;
pause();
}
break;
case 3:
if (clock < 12000) {
clock++;
} else {
Common.clock = 1;
clock = 0;
pause();
}
break;
case 4:
if (clock < 18000) {
clock++;
} else {
Common.clock = 1;
clock = 0;
pause();
}
break;
case 5:
if (clock < 36000) {
clock++;
} else {
Common.clock = 1;
clock = 0;
pause();
}
break;
case 6:
if (clock < 54000) {
clock++;
} else {
Common.clock = 1;
clock = 0;
pause();
}
break;
}
}
break;
case Common.NETWORK_STATE:// 查询网络状态
intenetLisenter();
handler.sendEmptyMessageDelayed(Common.NETWORK_STATE, 1000);
break;
}
}
};
private SharedPreferences sharedPreferences;
private String bookname;
public PlayerService() {
}
NotificationManager nm;
@Override
public void onCreate() {
super.onCreate();
changeHistoryDao = new BookLibDao(getApplicationContext());
changeHistoryDao.open();
player = new MediaPlayer(getApplicationContext());
handler.obtainMessage(Common.INIT_OK).sendToTarget();// 时间间隔1秒 查询当前播放时间
handler.obtainMessage(Common.NETWORK_STATE).sendToTarget();// 查询网络状态
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
registerReceiver();
player.setKeepInBackground(true);
player.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(IMediaPlayer iMediaPlayer) {
allTims=(int) player.getDuration()/1000;//加载成功 获取音频文件总时长
player.start();
player.setVolume(1f, 1f);音量
sendPlayerChangeBroacast();通知 播放器和更新通知栏 播放状态发生变化
Intent intent = new Intent();
intent.setAction(Common.InitPlayAllTime);
intent.putExtra("allTims", allTims);
sendBroadcast(intent); 发送播放总时长
}
});
播放完成监听
player.setOnCompletionListener(new IMediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(IMediaPlayer iMediaPlayer) {//此状态可能有误差 播放器error后也会回掉此方法所以加上个时间匹配
if (allTims* 1000 - 5000 <= currentTime && currentTime <= allTims * 1000 + 5000) {
next();
}
}
});
player.setOnErrorListener(new IMediaPlayer.OnErrorListener() {
@Override
public boolean onError(IMediaPlayer iMediaPlayer, int i, int i1) {
sendPlayerChangeBroacast();
return false;
}
});
sharedPreferences = getSharedPreferences(Common.LastPlayerHistory, MODE_PRIVATE);
TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
tmgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
// 从通知栏跳到播放器
BroadcastReceiver NMReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String ctrl_code = intent.getAction();
if (player != null) {
if ("play".equals(ctrl_code)) {
pauseOrPlayer();
} else if ("next".equals(ctrl_code)) {
next();
} else if ("delete".equals(ctrl_code)) {
if (nm != null) {
nm.cancelAll();
android.os.Process.killProcess(android.os.Process.myPid());
}
} else if ("open".equals(ctrl_code)) {
startActivity(new Intent(context, PlayerAty.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
Class clazz = null;
try {
Object statusBarManager = context.getSystemService("statusbar");
Method collapse;
if (Build.VERSION.SDK_INT <= 16) {
collapse = statusBarManager.getClass().getMethod("collapse");
} else {
collapse = statusBarManager.getClass().getMethod("collapsePanels");
}
collapse.invoke(statusBarManager);
} catch (Exception localException) {
localException.printStackTrace();
}
}
}
}
};
void registerReceiver() {接受通知栏 的命令
IntentFilter intentFilter4 = new IntentFilter();
intentFilter4.addAction("play");
intentFilter4.addAction("next");
intentFilter4.addAction("delete");
intentFilter4.addAction("open");
registerReceiver(NMReceiver, intentFilter4);
}
播放状态变化时要通知 播放器和通知栏
void sendPlayerChangeBroacast() {
if (player != null) {
Intent intent = new Intent();
intent.setAction(Common.PlaerStateChange);
intent.putExtra("PlaerStateChange", player.isPlaying());
sendBroadcast(intent);
if (bookname != null) {
ChapterDao dao1 = new ChapterDao(getApplicationContext());
dao1.open();
ChapterItem query = dao1.query(currentCid);
dao1.close();
initNotificationBar(bookname, query.getTitle(), player.isPlaying());
}
}
}
void intenetLisenter() {//网络状态监听
ConnectivityManager manager = (ConnectivityManager) getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
if (activeNetwork != null) { // connected to the internet
if (activeNetwork.isConnected()) {
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
if (intenetState != WIFY) {
//切换到wify
} else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
if (intenetState != PHONE) {
intenetState = PHONE
}
} else {
} else {
}
}
@Override
public IBinder onBind(Intent intent) {
return new PlayerIBinder();
}
public class PlayerIBinder extends Binder {
public PlayerService getService() {
return PlayerService.this;
}
}
设置 播放资源 path 可以是本地文件目录也可以是网络url
private void setData(String path) {
player.reset();
sendPlayerChangeBroacast();
if (Utils.isNull(path)) {
return;
}
try {
player.setDataSource(path);
player.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
public void seekTo(int presess) {
player.seekTo(presess);
}
public void pause() {
if (player != null) {
player.pause();
playerState = PLAYPAUSE;
}
sendPlayerChangeBroacast();
}
public void next() {
if (playerList == null) {
return;
}
if (position < playerList.size() - 1) {
Intent intent = new Intent();
intent.setAction(Common.PlayerTime);
intent.putExtra("currentTime", 0);
intent.putExtra("buffering", 0);
sendBroadcast(intent);
player.reset();
ChapterItem item = playerList.get(++position);
start(item.getCid(), item.getBookId(), position, 0, true);
sendPlayerChangeBroacast();
}
}
public void upOne() {
if (playerList == null) {
return;
}
if (position > 0) {
currentTime = 0;
player.reset();
ChapterItem item = playerList.get(--position);
start(item.getCid(), item.getBookId(), position, 0, true);
sendPlayerChangeBroacast();
}
}
public void playOrPause() {
if (player != null) {
if (player.isPlaying()) {
pause();
} else {
reStart();
}
}
}
public boolean isplaying() {
if (player != null) {
return player.isPlaying();
} else {
return false;
}
}
public void stop(){
if (player!=null){
player.stop();
player.reset();
}
}
public ArrayList
return playerList;
}
public void setPlayerList(ArrayList
this.playerList = playerList;
}
通知栏
public void initNotificationBar(String name, String chapterName, boolean isplaying) {
Notification notification = new Notification();
notification.icon = R.mipmap.nm;
RemoteViews contentView = new RemoteViews(getPackageName(),
R.layout.notafitycation);
notification.contentView = contentView;
contentView.setTextViewText(R.id.name, name);
contentView.setTextViewText(R.id.chapterName, chapterName);
contentView.setImageViewResource(R.id.next, R.mipmap.next);
if (isplaying) {
contentView.setImageViewResource(R.id.player, R.mipmap.n_player);
} else {
contentView.setImageViewResource(R.id.player, R.mipmap.n_pause);
}
Intent intentPlay = new Intent("play");
PendingIntent pIntentPlay = PendingIntent.getBroadcast(this, 0,
intentPlay, 0);
contentView.setOnClickPendingIntent(R.id.player, pIntentPlay);
Intent intentPause = new Intent("next");
PendingIntent pIntentPause = PendingIntent.getBroadcast(this, 0,
intentPause, 0);
contentView.setOnClickPendingIntent(R.id.next, pIntentPause);
Intent intentOpen = new Intent("open");
PendingIntent pIntentOpen = PendingIntent.getBroadcast(this, 0,
intentOpen, 0);
contentView.setOnClickPendingIntent(R.id.rl, pIntentOpen);
Intent intentNext = new Intent("delete");
PendingIntent pIntentNext = PendingIntent.getBroadcast(this, 0,
intentNext, 0);
contentView.setOnClickPendingIntent(R.id.delete, pIntentNext);
notification.flags = Notification.FLAG_NO_CLEAR;
nm.notify(100001, notification);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(NMReceiver);
}
}