先看下效果图:

    手机影音第七天 视频的播放下一个视频功能实现,视频进度、电量变化的实现_第1张图片

在这里,视频进度条会根据视频播放变化,下方的按钮中,播放下一个,上一个都已实现。

代码已经托管到码云上,想下载看的小伙伴可以从下方地址中获取

    https://git.oschina.net/joy_yuan/MobilePlayer


1、在这张图上,自定义的显示电量的那一列已经被系统自带的状态栏遮盖,下面就说一下实现方法:

    系统电量变化时,系统会发送一个广播,所有对这个广播感兴趣的activity都可以注册广播来接收这个广播。在这里接收系统电量变化,屏幕锁屏、开屏的广播,只能使用动态广播,不能用静态广播,这样是防止在锁屏后,某些程序偷偷干事情,开屏后其又隐藏,导致用户不知道。

    定义动态广播接收到系统的电量变化广播后,就根据电量值的区间,来动态的切换电量的图片,具体代码段如下:

//注册电量广播,像锁屏、开屏、电量变化这样的广播,静态注册的广播接收者收不到广播,因为导致安全问题,所以必须动态注册
receiver=new MyReceiver();

IntentFilter intentFilter=new IntentFilter();
//当电量变化时发这个广播
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(receiver, intentFilter);

---------------------------------------------------------------------------------------
/**
 * 监听电量变化的广播接收者
 */
class MyReceiver extends BroadcastReceiver{


    @Override
    public void onReceive(Context context, Intent intent) {
        int level=intent.getIntExtra("level",0);  //去intent获取key为level的值,默认是0
        setBattery(level);
    }
}

接收到电量的区间后,来动态设置电量图片

/**
 * 电量变化的方法
 * @param level
 */
private void setBattery(int level) {
    if (level<=0){
        ivBattery.setImageResource(R.drawable.ic_battery_0);
    }else if (level<=10){
        ivBattery.setImageResource(R.drawable.ic_battery_10);
    }else if (level<=20){
        ivBattery.setImageResource(R.drawable.ic_battery_20);
    }else if (level<=40){
        ivBattery.setImageResource(R.drawable.ic_battery_40);
    }else if (level<60){
        ivBattery.setImageResource(R.drawable.ic_battery_60);
    }else if (level<=80){
        ivBattery.setImageResource(R.drawable.ic_battery_80);
    }else if (level<=100){
        ivBattery.setImageResource(R.drawable.ic_battery_100);
    }
}


2、视频进度条的变化

    seekbar本身有一个setMax();这个是设置seekbar的最大值,我们传入一个视频的总时长就可以。在开始播放视频时,传一个空的handler,来进行更新seekbar方法。

    

/**
 * 准备好播放时的监听
 */
class MyOnPreparedListener implements MediaPlayer.OnPreparedListener {
    

    @Override
    public void onPrepared(MediaPlayer mp) {
        videoview.start(); //开始播放
        duration = videoview.getDuration();  //获取视频总时长
        seekbarVideo.setMax(duration);   //设置播放进度的最大值

        //发送消息,来更新视频进度
        handler.sendEmptyMessage(PROGRESS);

    }
}

然后在handler里,根据handler的what类型,来做更新进度的操作。videoview.getcurrentPosition()方法获取当前的视频进度,然后seekbar有个setpositon()可以设置进度,最后每隔一秒,再发送一个handler来更新这个进度

    

/**
 * 定义一个handler来处理信息
 */
public Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
            case PROGRESS:
                //根据准备好播放时候后,发送的更新视频进度消息,来更新视频进度
                int currentPosition=videoview.getCurrentPosition();
                seekbarVideo.setProgress(currentPosition);

                //隔一秒刷新一下进度
                removeMessages(PROGRESS);

                handler.sendEmptyMessageDelayed(PROGRESS,1000);
                break;
        }
    }
};


3、系统时间的变化:

        在上一面中讲到了视频进度条变换时,用到了handler,在handler里隔一秒刷新下handler,因此在这里也是更新系统时间放到了handler里。

    

/**
 * 定义一个handler来处理信息
 */
public Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
            case PROGRESS:
                //根据准备好播放时候后,发送的更新视频进度消息,来更新视频进度
                int currentPosition=videoview.getCurrentPosition();
                seekbarVideo.setProgress(currentPosition);

                //设置当前播放的时间,使其显示在播放器上
                tvCurrentTime.setText(utils.stringForTime(currentPosition));

                //设置系统播放时间,隔一秒刷新一下
                tvSystemTime.setText(getSystemTime());

                //隔一秒刷新一下进度
                removeMessages(PROGRESS);

                handler.sendEmptyMessageDelayed(PROGRESS,1000);
                break;
        }
    }
};


/**
 * 获取系统时间
 * @return
 */
private String getSystemTime() {
    SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
    return format.format(new Date());
}

    在这里要注意的是,获取系统时间的方法,用的那个SimpleDateFormat()方法,它的包是java.text.SimpleDateFormat;一定要注意了,Android系统可能会自动给我们导成其他包导致报错


4、要实现播放上一个下一个视频功能,我们就要获取视频数据的列表list,那么在videoPager中我们通过bundle,将list写入到bundle中,其中要注意的是 一定要给实体类MediaItem 序列化,即类实现Serializable接口即可,否则会导致报错。

    在videoPager中,按如下代码传入list到intent

//给对象序列化后传到SystemVideoPlayer中
Intent intent=new Intent(context, SystemVideoPlayer.class);
Bundle bundle=new Bundle();
bundle.putSerializable("mediallist",(ArrayList)mediaList);
intent.putExtras(bundle);
intent.putExtra("position",position);  //将点击的视频的位置传过去,方便定位播放的是哪个视频
context.startActivity(intent);

    在SystemVideoPlayer类中获取该list

    

//获取videopager里传过来的list数据,包含media列表的信息
medialist = (ArrayList) getIntent().getSerializableExtra("mediallist");
position = getIntent().getIntExtra("position",0);


获取到list和position后,即可非常方便的实现播放上一个,下一个视频

public void onClick(View v) {
    if ( v == btnVoice ) {
        // Handle clicks for btnVoice
    } else if ( v == switchPlayer ) {
        // Handle clicks for switchPlayer

    } else if ( v == btExit ) {
        // Handle clicks for btExit   退出
        finish();
    } else if ( v == btVideoPre ) {
        // Handle clicks for btVideoPre  播放上一个视频
        if (medialist!=null&&medialist.size()>0){
            position-=1;
            if (position<=0){
                position=medialist.size()-1;
            }
            MediaItem mediaitem=medialist.get(position);
            tvName.setText(mediaitem.getName());
            videoview.setVideoPath(mediaitem.getData());

        }else if (uri!=null){
            tvName.setText(uri.toString());
            videoview.setVideoURI(uri);
        }



    } else if ( v == btVideoStartPause ) {
        // Handle clicks for btVideoStartPause  播放暂停与启动
        if (videoview.isPlaying()){
            //视频在播放,则暂停
            videoview.pause();

            //按钮图片设置为暂停
            btVideoStartPause.setBackgroundResource(R.drawable.bt_video_play_selector);
        }else{
            //视频在暂停,设置为播放
            videoview.start();

            //按钮图片设置为播放

            btVideoStartPause.setBackgroundResource(R.drawable.bt_video_pause_selector);            }
    } else if ( v == btNext ) {
        // Handle clicks for btNext   播放下一个
     if (medialist!=null&&medialist.size()>0){
         position+=1;
         if (position>=medialist.size()){
             position=0;
         }

             MediaItem mediaItem = medialist.get(position);
             tvName.setText(mediaItem.getName());
             videoview.setVideoPath(mediaItem.getData());



     }else if (uri!=null){
         //把上一个下一个按钮设置灰色
         tvName.setText(uri.toString());
         videoview.setVideoURI(uri);
         btNext.setEnabled(false);
         btNext.setBackgroundResource(R.drawable.btn_next_gray);
     }

    } else if ( v == btVideoSwitchScreen ) {
        // Handle clicks for btVideoSwitchScreen
    }
}

这里做的是循环播放,即播放到最后一个后,按下一个,会播放第一个视频。