最近因公司项目要求需要写一个播放器,自带的又不太好用,也不太好看。自能自定义啦。查看了很多资料,都没有完善的,还好得以为前辈的指点得以完成,感谢Yang。本篇里面我有可能有些地方写得不好(都附上了注释)。希望各路大神指点,虚心受教。
先来个图(源码在后面附上)
视频列表里面的数据是本地的,如果你需要使用网络的只需要在此获取服务器的数据展示就行了。播放页面在后面。
package com.eteng.moblieplayer.video;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import com.eteng.moblieplayer.BaseActivity;
import com.eteng.moblieplayer.R;
import com.eteng.moblieplayer.adapter.VideoAdapter;
import com.eteng.moblieplayer.beans.VideoBenas;
import com.eteng.moblieplayer.utils.StringTimeUtil;
import org.xutils.view.annotation.ViewInject;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
/**
* Created by zqf on 2016/7/6.
*/
public class VideoActivity extends BaseActivity implements AdapterView.OnItemClickListener {
private ListView video_listview;
private TextView noresources_tv;
private VideoBenas beans;
private List data = new ArrayList();
private VideoAdapter adapter;
private StringTimeUtil util;
public Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
if (data != null && data.size() != 0) {
noresources_tv.setVisibility(View.GONE);
adapter = new VideoAdapter(data, VideoActivity.this, util);
video_listview.setAdapter(adapter);
} else {
noresources_tv.setVisibility(View.VISIBLE);
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settabtitle("视频列表");
setrightvisible(View.GONE);
video_listview = (ListView) findViewById(R.id.video_listviw);
noresources_tv = (TextView) findViewById(R.id.noresources_tv);
util = new StringTimeUtil();
getAllVideo();
video_listview.setOnItemClickListener(this);
}
private void getAllVideo() {
new Thread(new Runnable() {
@Override
public void run() {
ContentResolver resolver = getContentResolver();
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
//查找的条件
String[] projection = {MediaStore.Video.Media.TITLE, //标题
MediaStore.Video.Media.DESCRIPTION, //描述
MediaStore.Video.Media.SIZE, //大小
MediaStore.Video.Media.DURATION, //时长
MediaStore.Video.Media.DATA}; //绝对路径
Cursor cursor = resolver.query(uri, projection, null, null, null);
while (cursor.moveToNext()) {
//判断视频大小>3MB的才添加进来。
if (cursor.getLong(2) > 3 * 1024 * 1024) {
beans = new VideoBenas();
beans.setTitle(cursor.getString(0));
beans.setDescribe(cursor.getString(1));
beans.setSize(cursor.getLong(2));
beans.setLongtime(cursor.getString(3));
beans.setPath(cursor.getString(4));
data.add(beans);
}
}
handler.sendEmptyMessage(0);
}
}).start();
}
@Override
public void leftonclick() {
finish();
}
@Override
public void rightonclick() {
}
//加载子布局内容
@Override
public View setcontent() {
return View.inflate(VideoActivity.this, R.layout.activity_video, null);
}
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
VideoBenas item = data.get(position);
Intent intent = new Intent(VideoActivity.this, VideoPlayerActivity.class);
intent.setData(Uri.parse(item.getPath()));
intent.putExtra("videotitle",item.getTitle());
startActivity(intent);
}
}
好了,接下来就是播放器页面了。
package com.eteng.moblieplayer.video;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.eteng.moblieplayer.BaseActivity;
import com.eteng.moblieplayer.R;
import com.eteng.moblieplayer.utils.StringTimeUtil;
import com.eteng.moblieplayer.view.VideoView;
/**
* Created by zqf on 2016/7/6.
* 播放页面
*/
public class VideoPlayerActivity extends BaseActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnInfoListener {
private VideoView videoView;
//--播放的地址uri
private Uri uri;
private ImageView play_imag, fullview_imag, back_imag, battery_imag;
private SeekBar mseekBar;
private TextView videoTitle, SystemTime;
private TextView videocurrent_time, videototal_time;
private StringTimeUtil utils;
private MyBrodCastReceiver receiver;
//设置电量
private int leave;
//手势识别器
private GestureDetector detector;
//顶部布局
private RelativeLayout top_layout;
//底部布局
private LinearLayout bottom_layout;
/**
* 判断是否播放
*/
private boolean isPlayer = false;
/***
* 判断Activity是否被销毁
* --true-->销毁
* --false -->没有销毁
*/
private boolean isDestory = false;
//
private static final int PROGRESS = 1;
//隐藏顶部和底部的变量
private static final int HIDE_TOPBOTTOMLAYOUT = 2;
/**
* 网络加载等待布局
*/
private LinearLayout ll_loading;
/***
* 出现卡的缓冲加载
*/
private ProgressBar pg_buff;
private Handler mhandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case PROGRESS:
//设置进度
int currenttime = videoView.getCurrentPosition();
videocurrent_time.setText(utils.stringfortime(currenttime));
//更新seekbar
mseekBar.setProgress(currenttime);
//更新电量 //电量显示和系统时间可自行设置多久时间更新一次
setBattery();
//设置系统时间
setsystemTime();
/***
* 得到视频缓存度
* --缓存比例值-0~100
*/
int Percentage = videoView.getBufferPercentage();
int total = Percentage * mseekBar.getMax();
int secondaryprogress = total / 100;
mseekBar.setSecondaryProgress(secondaryprogress);
if (!isDestory) {
mhandler.removeMessages(PROGRESS);
//消息的死循环--用于更新播放进度
mhandler.sendEmptyMessageDelayed(PROGRESS, 1000);
}
break;
case HIDE_TOPBOTTOMLAYOUT:
hidelayout();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settabvisible(View.GONE);
initView();
initData();
setonclick();
//得到播放地址
uri = getIntent().getData();
videoView.setVideoURI(uri); //设置路径
videoView.setOnPreparedListener(this); //准备好的监听事件
}
private void setsystemTime() {
SystemTime.setText(utils.getSystemTime());
}
private void setBattery() {
if (leave <= 5) {
battery_imag.setImageResource(R.mipmap.icv_power_00);
} else if (leave <= 20) {
battery_imag.setImageResource(R.mipmap.icv_power_01);
} else if (leave <= 40) {
battery_imag.setImageResource(R.mipmap.icv_power_02);
} else if (leave <= 60) {
battery_imag.setImageResource(R.mipmap.icv_power_03);
} else if (leave <= 80) {
battery_imag.setImageResource(R.mipmap.icv_power_04);
} else if (leave <= 100) {
battery_imag.setImageResource(R.mipmap.icv_power_05);
}
}
/***
* true--显示--false--隐藏
*/
private boolean isShowLayout = false;
private void initData() {
videoTitle.setText(getIntent().getStringExtra("videotitle"));
isDestory = false;
utils = new StringTimeUtil();
//注册电量监听的广播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
receiver = new MyBrodCastReceiver();
registerReceiver(receiver, intentFilter);
//实例化
detector = new GestureDetector(VideoPlayerActivity.this, new GestureDetector.OnGestureListener() {
//单击
@Override
public boolean onDown(MotionEvent e) {
Log.e("TAG", "onDown");
if (isShowLayout) {
removeHideTopBottomLayoutMessage();
hidelayout();
} else {
sendDelayedHideTopBottomLayout();
showLayout();
}
return true;
}
//长按执行的顺序---1.onDown-->2.onShowPress-->onLongPress
@Override
public void onShowPress(MotionEvent e) {
Log.e("TAG", "onShowPress");
}
//单击后执行onDown接着执行的方法
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.e("TAG", "onSingleTapUp");
return false;
}
//滑动
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.e("TAG", "onScroll");
return false;
}
//长按
@Override
public void onLongPress(MotionEvent e) {
Log.e("TAG", "onLongPress");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});
}
/***
* 发送延迟隐藏
*/
private void sendDelayedHideTopBottomLayout() {
mhandler.sendEmptyMessageDelayed(HIDE_TOPBOTTOMLAYOUT, 5000);
}
/***
* 移除延迟隐藏的Handler消息
*/
private void removeHideTopBottomLayoutMessage() {
mhandler.removeMessages(HIDE_TOPBOTTOMLAYOUT);
}
/***
* 显示的方法
*/
private void showLayout() {
isShowLayout = true;
top_layout.setVisibility(View.VISIBLE);
bottom_layout.setVisibility(View.VISIBLE);
}
/***
* 隐藏的方法
*/
private void hidelayout() {
isShowLayout = false;
top_layout.setVisibility(View.GONE);
bottom_layout.setVisibility(View.GONE);
}
/***
* 使用手势适配器
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
detector.onTouchEvent(event);
return true; //返回true视交由人为处理
}
/***
* 卡或者拖动卡时候出现的回调
*
* @param mp
* @param what
* @param extra
* @return
*/
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_INFO_BUFFERING_START: //开始出现卡或者拖动卡
pg_buff.setVisibility(View.VISIBLE);
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END: //结束卡或者拖动卡情况
pg_buff.setVisibility(View.GONE);
break;
}
return true;
}
private class MyBrodCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//返回一个电量的范围值
leave = intent.getIntExtra("level", 0);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
isDestory = true;
unregisterReceiver(receiver);
receiver = null;
videoView.stopPlayback();
}
public void initView() {
pg_buff = (ProgressBar) findViewById(R.id.pg_buff);
videoView = (VideoView) findViewById(R.id.videoview);
ll_loading = (LinearLayout) findViewById(R.id.ll_loading);
top_layout = (RelativeLayout) findViewById(R.id.topLayout);
bottom_layout = (LinearLayout) findViewById(R.id.bottomLayout);
SystemTime = (TextView) findViewById(R.id.videosystemTime);
battery_imag = (ImageView) findViewById(R.id.videoPower);
back_imag = (ImageView) findViewById(R.id.videoBack);
play_imag = (ImageView) findViewById(R.id.videoPlay);
fullview_imag = (ImageView) findViewById(R.id.videoFullScreen);
mseekBar = (SeekBar) findViewById(R.id.videoPlayProgress);
videoTitle = (TextView) findViewById(R.id.videoTitle);
videocurrent_time = (TextView) findViewById(R.id.videoCurrentProgress);
videototal_time = (TextView) findViewById(R.id.videototalTime);
}
public void setonclick() {
back_imag.setOnClickListener(onclicklistener);
play_imag.setOnClickListener(onclicklistener);
fullview_imag.setOnClickListener(onclicklistener);
videoView.setOnInfoListener(this);
mseekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
/***
*
* @param seekBar-->自身的seekba
* @param progress-->seekbar的位置,视频的长度和seekbar的位置一一对应
* @param fromUser-->如果是人为的拖动值为--true,如seekbar自身在改变的值--false
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
videoView.seekTo(progress);
}
}
/**
* 手指开始拖动时进行回调
* @param seekBar
*/
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
removeHideTopBottomLayoutMessage();
}
/**
* 手指离开回调
* @param seekBar
*/
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
sendDelayedHideTopBottomLayout();
}
});
/***
* 视频加载出错时进行回掉
* --true-->人为处理出错的结果
*/
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(VideoPlayerActivity.this, "视频出错了", Toast.LENGTH_LONG).show();
finish();
return true;
}
});
}
View.OnClickListener onclicklistener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.videoPlay:
if (isPlayer) {
videoView.pause();
play_imag.setImageResource(R.mipmap.icv_play);
} else {
videoView.start();
play_imag.setImageResource(R.mipmap.icv_pause);
}
isPlayer = !isPlayer;
break;
case R.id.videoBack:
finish();
videoView.stopPlayback();
break;
}
}
};
@Override
public void leftonclick() {
}
@Override
public void rightonclick() {
}
//设置子布局
@Override
public View setcontent() {
return View.inflate(VideoPlayerActivity.this, R.layout.activity_videoplayer, null);
}
/***
* 监听是否准备好了
*
* @param mp
*/
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
play_imag.setImageResource(R.mipmap.icv_pause);
isPlayer = true;
//获取总时长
int duration = videoView.getDuration();
videototal_time.setText("/" + utils.stringfortime(duration));
//设置seekbar的最大值
mseekBar.setMax(duration);
setsystemTime();
mhandler.sendEmptyMessageDelayed(PROGRESS, 1000);
sendDelayedHideTopBottomLayout();
ll_loading.setVisibility(View.GONE);
}
}
最后结尾来个图吧!
上次忘记发源码地址啦,给补上,抱歉。
源码地址