android 有声小说播放器(可以离线在线播放)

使用service实现播放器

播放器:bilibili IJKplayer 的 exoplayer 框架


播放器 android 有声小说播放器(可以离线在线播放)



播放器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<ChapterItem> playerList;//播放资源列表
    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<ChapterItem> getPlayerList() {
        return playerList;
    }

    public void setPlayerList(ArrayList<ChapterItem> playerList) {
        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);
    }
}