Android VideoView实现播放本地和网络视频,滑动快进快退、滑动调整音量和调整亮度,分享功能,进度显示,双击暂停,单击暂停等功能
原生VideoView控件的实现,可自定义布局,类似直播的播放界面:
一.效果图:
二.功能列表:
1、打开本地媒体器,SeekBar滑动进度条,暂停/播放按钮三个功能;
2、锁定按钮功能;
3、分享功能(两种机制 如果是本地视频则分享视频,如果是网络视频分享网络视频地址);
4、VideoView滑动监听(快进快退,音量加减、亮度加减);
5、全屏按钮和缩小按钮点击功能;
6、左下角显示当前时间,右下角显示视频的总时长,中间显示视频当前进度
7、播放网络视频功能;
8、单击双击监听(双击暂停,单击显示所有状态,单击播放暂停)
9、按返回键,连续按两次才会退出,按一次提醒再按一次才会退出
10、视频播放器能够出现在打开方式上,即视频长按可以选择我的播放器进行播放
11、部分按钮三秒后自动隐藏
三.下面直接上代码,比较简单:(贴出所有的案例代码,直接拿走就可以使用)
1.activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.m1571.myvideoview.CustomVideoView
android:id="@+id/videoview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:src="@mipmap/ic_launcher"
android:layout_height="match_parent" />
<RelativeLayout
android:id="@+id/rl_vd"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/im_vd_back"
android:layout_margin="20px"
android:layout_width="wrap_content"
android:src="@drawable/login_icon_back"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_video_details_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimary"
android:layout_centerInParent="true"/>
<ImageView
android:id="@+id/im_video_details_start"
android:layout_width="106px"
android:layout_height="106px"
android:layout_centerInParent="true"
android:src="@drawable/zhibo_icon_begin" />
<!--头像-->
<LinearLayout
android:id="@+id/ll_head_all"
android:layout_width="80px"
android:layout_height="wrap_content"
android:layout_marginRight="20px"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="105px"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/im_video_details_head"
android:layout_width="80px"
android:layout_height="80px"
android:layout_centerHorizontal="true"
android:src="@drawable/ic_default_avatar" />
<ImageView
android:id="@+id/im_video_details_follow"
android:layout_width="38px"
android:layout_height="38px"
android:layout_below="@+id/im_video_details_head"
android:layout_centerHorizontal="true"
android:layout_marginTop="-25px"
android:src="@drawable/ic_like_selected" />
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_vd_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30px"
android:orientation="vertical">
<ImageView
android:layout_width="54px"
android:layout_height="54px"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/meiying_icon_imessage" />
<TextView
android:id="@+id/tv_video_details_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10px"
android:text="1.3万"
android:textColor="#ffffff"
android:textSize="24px" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_vd_fabulous"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30px"
android:orientation="vertical">
<ImageView
android:layout_width="54px"
android:layout_height="54px"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/meiying_icon_zan" />
<TextView
android:id="@+id/tv_video_details_fabulous"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10px"
android:text="1.3万"
android:textColor="#ffffff"
android:textSize="24px" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_vd_share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30px"
android:orientation="vertical">
<ImageView
android:layout_width="54px"
android:layout_height="54px"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/meiying_icon_share" />
<TextView
android:id="@+id/tv_video_details_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10px"
android:text="share"
android:textColor="#ffffff"
android:textSize="24px" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/tv_video_details_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/im_video_details_start"
android:layout_centerVertical="true"
android:layout_marginLeft="20px"
android:layout_marginRight="130px"
android:layout_marginTop="172px"
android:text="KING"
android:textColor="#ffffff"
android:textSize="30px" />
<RelativeLayout
android:id="@+id/rl_video_details_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_video_details_name"
android:layout_marginLeft="20px"
android:layout_marginRight="130px"
android:layout_marginTop="20px"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_video_details_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="3"
android:text="悟空和唐僧一起上某卫视非诚勿扰,悟空上台,2有一根破棍. 2.保镖职业危险.3.动不动打妖精,对女生不温柔. 对女生不温柔不温柔对对女生不温柔女生不温柔对女生不温柔坐过牢,曾被压五指山下500年。唐僧上台,哗!灯全亮,悟空和唐僧一起上某卫视非诚勿扰,悟空上台,2有一根破棍. 2.保镖职业危险.3.动不动打妖精,对女生不温柔. 对女生不温柔不温柔对对女生不温柔女生不温柔对女生不温柔坐过牢,曾被压五指山下500年。唐僧上台,哗!灯全亮"
android:textColor="#ffffff"
android:textSize="24px" />
<TextView
android:id="@+id/tv_video_details_full_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_video_details_content"
android:text="全文"
android:textColor="#729EFF"
android:textSize="24px" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20px"
android:layout_marginLeft="20px"
android:layout_marginRight="20px"
android:layout_marginTop="20px"
android:orientation="horizontal">
<ImageButton
android:id="@+id/im_selectFile"
android:layout_width="46px"
android:layout_height="46px"
android:background="#0000"
android:layout_centerVertical="true"
android:onClick="openFile"
android:src="@drawable/ic_media_open"
tools:ignore="OnClick" />
<ImageView
android:id="@+id/im_start_end"
android:layout_toRightOf="@+id/im_selectFile"
android:layout_width="55px"
android:layout_height="55px"
android:layout_marginLeft="8px"
android:layout_centerVertical="true"
android:src="@drawable/ic_play" />
<TextView
android:id="@+id/tv_vd_start_time"
android:layout_width="wrap_content"
android:layout_marginLeft="8px"
android:layout_centerVertical="true"
android:layout_height="wrap_content"
android:text="00:00"
android:layout_toRightOf="@+id/im_start_end"
android:textColor="#ffffff"
android:textSize="26px" />
<SeekBar
android:id="@+id/seekBar_vd"
android:layout_width="500px"
android:layout_centerVertical="true"
android:layout_centerInParent="true"
android:layout_height="wrap_content"
android:layout_marginLeft="35px"
android:layout_marginRight="35px" />
<TextView
android:id="@+id/tv_vd_all_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="03:00"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_gravity="center|right"
android:gravity="center|right"
android:textColor="#ffffff"
android:textSize="26px" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
2.Utils 网络视频地址:
package com.example.m1571.myvideoview;
public class Utils {
public static final String videoUrl = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" ;
public static final String videoUrl1 = "http://video.jiecao.fm/8/17/bGQS3BQQWUYrlzP1K4Tg4Q__.mp4";
}
3.MainActivity
package com.example.m1571.myvideoview;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
/**
* 视频资源要添加res文件夹下创建raw文件夹
* 需要在onRestart()方法里重新加载视频,防止退出返回时视频黑屏
* 我这样写简单粗暴而已,当然,也可优雅的以自己看播放控件的VideoView处理方法,去处理资源释放和播放显示的问题。
* 记得修改布局控件<com.daqie.videobackground.CustomVideoView...引用的包名,不然会报错哦
* android:screenOrientation="portrait" 习惯性的把横竖屏切换也设置一下
* android:theme="@style/Theme.AppCompat.Light.NoActionBar" ActionBar也可以设置成不显示的状态,可以根据自己喜好和项目需求
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//创建播放视频的控件对象
private CustomVideoView videoview;
private ImageView imageView,imStartEnd;
private int bum = 0;
private TextView tv_video_details_content;
private TextView tv_video_details_full_text;
protected Handler mHandler;
private RelativeLayout rl_vd;
private EditText mEtComment;
private ImageView im_video_details_start;
//将长度转换为时间
StringBuilder mFormatBuilder = new StringBuilder();
Formatter mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
private TextView tv_vd_all_time;
private SeekBar seekBar_vd;
private Handler msgHandler; // Android消息机制 (高级篇讲解)
private Timer timer; // 定时器
private TimerTask timerTask; // 定时功能
private Timer timer_currentposition; // 定时器
private TimerTask currentposiTask; // 实时显示当前视频位置和总长度
private boolean isInternetMedia = false; // 判断是网络视频还是本地视频,用于两套分享机制和标题名
private int orientation; // 获取当前屏幕横屏还是竖屏,1为竖屏,2为横屏
private Timer timer_current; // 定时器
private TimerTask currentTimeTask; // 实时显示当前时间
private Uri uri;
final String TAG = "测试 MainActivity";
private boolean mediaUrinull; // 判断视频路径是否存在即是否在播放
private boolean islocked = false; // 判断是否被锁定
// 左边边屏幕滑动亮度显示
private float startX = 0;//手指按下时的X坐标
private float startY = 0;//手指按下时的Y坐标
private LinearLayout ll_head_all;
private TextView tv_video_details_name;
private RelativeLayout rl_video_details_content,rlSeekBar;
private ImageView imVdBack;
final int REQ_OPEN_FILE = 2333; // 返回码
private TextView tv_video_details_textview;
private Vibrator vibrator;//手机震动器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 判断当前横屏还是竖屏,用于切换界面
orientation = getResources().getConfiguration().orientation;
// 消息支持(可以写成内部类,用匿名类的话onCreate有点长)
msgHandler = new MyHandler();
// if (orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
// setContentView(R.layout.activity_main_portrait);
// Log.d(TAG,"现在为竖屏模式portrait...");
// } else {
// requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);
// setContentView(R.layout.activity_main_landscape);
// Log.d(TAG,"现在为横屏模式landscape...");
// }
//加载数据
initView();
}
@SuppressLint("ClickableViewAccessibility")
private void initView() {
//本地的视频 需要在手机SD卡根目录添加一个 fl1234.mp4 视频
// String videoUrl1 = Environment.getExternalStorageDirectory().getPath()+"/fl1234.mp4" ;
//网络视频
String videoUrl2 = Utils.videoUrl1;
uri = Uri.parse(videoUrl2);
//加载视频资源控件
videoview = (CustomVideoView) findViewById(R.id.videoview);
imageView = (ImageView) findViewById(R.id.imageView);
imStartEnd = (ImageView) findViewById(R.id.im_start_end);
im_video_details_start = (ImageView) findViewById(R.id.im_video_details_start);
ImageView im_video_details_head = (ImageView) findViewById(R.id.im_video_details_head);
ImageView im_video_details_follow = (ImageView) findViewById(R.id.im_video_details_follow);
imVdBack = (ImageView) findViewById(R.id.im_vd_back);
tv_video_details_textview = (TextView) findViewById(R.id.tv_video_details_textview);
TextView tv_video_details_comment = (TextView) findViewById(R.id.tv_video_details_comment);
TextView tv_video_details_fabulous = (TextView) findViewById(R.id.tv_video_details_fabulous);
TextView tv_video_details_share = (TextView) findViewById(R.id.tv_video_details_share);
tv_video_details_name = (TextView) findViewById(R.id.tv_video_details_name);
rl_video_details_content = (RelativeLayout) findViewById(R.id.rl_video_details_content);
rlSeekBar = (RelativeLayout) findViewById(R.id.rl_seekbar);
rl_vd = (RelativeLayout) findViewById(R.id.rl_vd);
LinearLayout ll_vd_share = (LinearLayout) findViewById(R.id.ll_vd_share);
LinearLayout ll_vd_fabulous = (LinearLayout) findViewById(R.id.ll_vd_fabulous);
LinearLayout ll_vd_comment = (LinearLayout) findViewById(R.id.ll_vd_comment);
ll_head_all = (LinearLayout) findViewById(R.id.ll_head_all);
tv_video_details_content = (TextView) findViewById(R.id.tv_video_details_content);
tv_video_details_full_text = (TextView) findViewById(R.id.tv_video_details_full_text);
final TextView tv_vd_start_time = (TextView) findViewById(R.id.tv_vd_start_time);
tv_vd_all_time = (TextView) findViewById(R.id.tv_vd_all_time);
seekBar_vd = (SeekBar) findViewById(R.id.seekBar_vd);
imVdBack.setOnClickListener(this);
im_video_details_follow.setOnClickListener(this);
im_video_details_head.setOnClickListener(this);
ll_vd_comment.setOnClickListener(this);
ll_vd_share.setOnClickListener(this);
ll_vd_fabulous.setOnClickListener(this);
tv_video_details_full_text.setOnClickListener(this);
getNetVideoBitmap(videoUrl2);
//获取视频长度:
// MediaMetadataRetriever mmr = new MediaMetadataRetriever();
// mmr.setDataSource(videoUrl2);
// String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); // 播放时长单位为毫秒
//设置播放加载路径
// videoview.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.video));
videoview.setVideoURI(uri);
// 播放控制 (暂停、继承)
imStartEnd.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View view) {
// findViewById(R.id.id_help).setVisibility(View.GONE); //将说明关闭
// 此处可以优化 (事先把两个图标先加载好, 不要每次现加载)
if ( videoview.isPlaying()) {
Log.w(TAG, "正在播放,现在暂停...");
if ( uri != null) {
videoview.pause();
imStartEnd.setImageDrawable(getDrawable(R.drawable.ic_play));
im_video_details_start.setVisibility(View.VISIBLE);
}
} else {
Log.w(TAG, "不在播放,现在继续...");
if ( uri != null){
videoview.start();
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
}
}
}
});
// 播放控制(进度拖放)
seekBar_vd.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// 进度条开始拖动的时候
// 首先判断是不是用户操作,不然每隔0.5秒定时器会刷新一直显示
if (fromUser) {
// controlBar.setVisibility(View.VISIBLE);
SimpleDateFormat sdf;
double currentTime = (progress / 100.0 )* videoview.getDuration(); // 将当前位置换算成视频总时长的指定位置时间
int hour = (int) (currentTime / (3600 * 1000));
if ( hour < 0 || hour == 0) {
sdf = new SimpleDateFormat("mm:ss"); // 转换时间
} else {
sdf = new SimpleDateFormat("HH:mm:ss"); // 转换时间
}
sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); // 设置中国时区
String startformat = sdf.format(currentTime);//开始及滑动的时间
String allTime = getAllTime();//总时长
//合并显示的时间
String result = sdf.format(currentTime) + " / " + getAllTime(); // 将时分秒转换成String类型
tv_vd_start_time.setText(startformat);
tv_vd_all_time.setText(allTime);
tv_video_details_textview.setVisibility(View.VISIBLE);
tv_video_details_textview.setText( result);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
// 控制视频跳转到目标位置
int progress = seekBar.getProgress();
int position = progress * videoview.getDuration() / 100;
videoview.seekTo( position );
// 隐藏掉主工具栏
// if(mRunnable_2 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_2); // 清除线程
// msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
// }
// // 隐藏掉中间信息框
// if(mRunnable_4 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_4); // 清除线程
// msgHandler.postDelayed(mRunnable_4, 1000); // 延时1秒
// }
}
});
imageView.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View v) {
//播放
videoview.start();
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
imStartEnd.setImageDrawable(getDrawable(R.drawable.ic_pause));
}
});
im_video_details_start.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View v) {
//播放
videoview.start();
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
imStartEnd.setImageDrawable(getDrawable(R.drawable.ic_pause));
}
});
//循环播放
videoview.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@SuppressLint("NewApi")
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
Toast.makeText(MainActivity.this, "视频结束,马上自动重播", Toast.LENGTH_SHORT).show();
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
videoview.setVideoPath(Utils.videoUrl1);
videoview.requestFocus();
videoview.start();
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
}
});
//监听视频
videoview.setOnTouchListener(new View.OnTouchListener() {
long lastTime,curTime; // 最后一点击和当前点击的时间
@SuppressLint("NewApi")
@Override
public boolean onTouch(View v, MotionEvent event) {
//若已经播放则暂停,反之则播放--单击效果
// if (videoview.isPlaying()) {
// videoview.pause();
// im_video_details_start.setVisibility(View.VISIBLE);
// } else {
// videoview.start();
// im_video_details_start.setVisibility(View.INVISIBLE);
// }
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
lastTime = curTime; // 获取第一次点击时间
curTime = System.currentTimeMillis(); // 获取当前时间
Log.w(TAG, "单击点中画面..");
// imageButton_islocked.setVisibility(View.VISIBLE);
// internetControlBar.setVisibility(View.GONE);
// findViewById(R.id.id_help).setVisibility(View.GONE); //将说明关闭
// 首先判断是否被锁定
if (!islocked) {
ll_head_all.setVisibility(View.VISIBLE);
tv_video_details_name.setVisibility(View.VISIBLE);
rl_video_details_content.setVisibility(View.VISIBLE);
rlSeekBar.setVisibility(View.VISIBLE);
imVdBack.setVisibility(View.VISIBLE);
// imageButton_share.setVisibility(View.VISIBLE);
// titleBar.setVisibility(View.VISIBLE);
if (uri == null) {
mediaUrinull = true;
} else {
mediaUrinull = false;
}
// 隐藏掉主工具栏
if (mRunnable_2 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
msgHandler.removeCallbacks(mRunnable_2); // 清除线程
msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
}
// 隐藏掉分享按钮
// if (mRunnable_5 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_5); // 清除线程
// msgHandler.postDelayed(mRunnable_5, 3000); // 延时3秒
// }
// 隐藏标题Layout按钮
// if (mRunnable_7 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_7); // 清除线程
// msgHandler.postDelayed(mRunnable_7, 3000); // 延时3秒
// }
}
// 隐藏锁定按钮
// if (mRunnable_3 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_3); // 清除线程
// msgHandler.postDelayed(mRunnable_3, 3000); // 延时3秒
// }
// 判断双击的时间间隔
if (curTime - lastTime < 500) {
Log.w(TAG, "双击点中画面..");
// 首先判断是否被锁定
if (!islocked) {
if (videoview.isPlaying() && !mediaUrinull) {
videoview.pause();
imStartEnd.setImageDrawable(getDrawable(R.drawable.ic_play));
im_video_details_start.setVisibility(View.VISIBLE);
} else if (!videoview.isPlaying() && !mediaUrinull) {
videoview.start();
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
im_video_details_start.setVisibility(View.INVISIBLE);
// imageButton_pause.setImageDrawable(getDrawable(R.drawable.ic_pause));
}
}
return true;
}
break;
}
default:
break;
}
return false;
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
videoview.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
});
}
//正在缓冲
// videoview.setOnInfoListener(new MediaPlayer.OnInfoListener() {
// @Override
// public boolean onInfo(MediaPlayer mp, int what, int extra) {
// if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
mProgressBar.setVisibility(View.VISIBLE);
// } else {
mProgressBar.setVisibility(View.GONE);
// }
// return true;
// }
// });
/**
* 视频准备完毕
*/
videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) { //监听视频准备好
String allTime = getAllTime();
tv_vd_all_time.setText(allTime);
// mProgressBar.setVisibility(View.GONE);
// int alltime=videoview.getDuration()/1000;//这里获取到的时间是ms为单位的,所以要转换成秒的话就要除以1000
// tv_vd_all_time.setText(alltime+"");
// int currentPosition = videoview.getCurrentPosition();
//
// String stringForTime = stringForTime(alltime);
// tv_vd_all_time.setText(stringForTime);
}
});
// 接受外部调用
// Intent intent = getIntent();
// Uri mediaUri = intent.getData();
// uri = intent.getData();
uri = Uri.parse(videoUrl2);
// if(uri != null)
// {
// videoview.setVideoURI(uri);
// videoview.start();
// }
}
//返回重启加载
@Override
protected void onRestart() {
initView();
super.onRestart();
}
//防止锁屏或者切出的时候,音乐在播放
// @Override
// protected void onStop() {
// videoview.stopPlayback();
// super.onStop();
// }
// 点击 ‘打开’ 按钮
@SuppressLint("NewApi")
public void openFile(View view) {
Intent intent = new Intent( Intent.ACTION_GET_CONTENT); // 特殊种类的数据,比如相片或者录音
intent.setType("video/*"); // 只显示视频
startActivityForResult(intent, REQ_OPEN_FILE);
// ImageView im_start_end = (ImageView) findViewById(R.id.im_start_end);
// findViewById(R.id.id_help).setVisibility(View.GONE); //将说明关闭
if (uri != null) {
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
} else {
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_play));
}
}
// 从媒体管理器返回
@SuppressLint("NewApi")
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ( requestCode == REQ_OPEN_FILE) {
if ( resultCode == RESULT_OK) {
uri = data.getData();
videoview.setVideoURI(uri);
videoview.start();
isInternetMedia = false;
if (uri != null) {
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
} else {
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_play));
}
}
// 隐藏掉主工具栏
if(mRunnable_2 != null) {
msgHandler.removeCallbacks(mRunnable_2);
msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
}
// 隐藏锁定按钮
// if(mRunnable_3 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_3); // 清除线程
// msgHandler.postDelayed(mRunnable_3, 3000); // 延时3秒
// }
// 隐藏掉分享按钮
// if(mRunnable_5 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_5); // 清除线程
// msgHandler.postDelayed(mRunnable_5, 3000); // 延时3秒
// }
// 隐藏标题Layout按钮
// if(mRunnable_7 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_7); // 清除线程
// msgHandler.postDelayed(mRunnable_7, 3000); // 延时3秒
// }
}
}
/**
* 显示网络视频的某一帧做封面
*
* @param videoUrl
* @return
*/
public Bitmap getNetVideoBitmap(String videoUrl) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
//根据url获取缩略图
retriever.setDataSource(videoUrl, new HashMap());
//获得第一帧图片
bitmap = retriever.getFrameAtTime();
imageView.setImageBitmap(bitmap);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} finally {
retriever.release();
}
return bitmap;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.im_vd_back:
finish();
break;
case R.id.im_video_details_follow:
Toast.makeText(this, "follow", Toast.LENGTH_SHORT).show();
break;
case R.id.im_video_details_head:
Toast.makeText(this, "head", Toast.LENGTH_SHORT).show();
break;
case R.id.ll_vd_comment:
Toast.makeText(this, "comment", Toast.LENGTH_SHORT).show();
// showCommentPopup(rl_vd);
break;
case R.id.ll_vd_share:
Toast.makeText(this, "share", Toast.LENGTH_SHORT).show();
if ( !isInternetMedia && uri != null) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("video/*");
startActivity(Intent.createChooser(intent, "分享我的视频到..."));
} else if ( isInternetMedia) {
// String content = ((EditText) findViewById(R.id.id_internetUri)).getText().toString();
// content = content.trim(); // 去除两边的空白
// if ( content.length() == 0) return;
Intent intent = new Intent( Intent.ACTION_SEND);
intent.setType( "text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "KING");
startActivity(Intent.createChooser(intent, "分享网络视频地址到..."));
}
break;
case R.id.ll_vd_fabulous:
Toast.makeText(this, "fabulous", Toast.LENGTH_SHORT).show();
break;
case R.id.tv_video_details_full_text:
bum++;
if (bum % 2 == 0) {
tv_video_details_content.setEllipsize(TextUtils.TruncateAt.END); // 关闭
tv_video_details_content.setMaxLines(3);
tv_video_details_full_text.setText("全文");
} else {
tv_video_details_content.setEllipsize(null); // 展开
tv_video_details_content.setMaxLines(10000);
tv_video_details_full_text.setText("收起");
}
break;
default:
break;
}
}
//将长度转换为时间
private String stringForTime(int timeMs) {
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours > 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
// 监听触摸屏幕
@Override
public boolean onTouchEvent(MotionEvent event) {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
if (uri == null) {
mediaUrinull = true;
} else {
mediaUrinull = false;
}
switch ( event.getAction()) {
case MotionEvent.ACTION_DOWN: {
startX = event.getX();
startY = event.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
// TODO 音量
float distanceX = event.getX() - startX;
float distanceY = event.getY() - startY;
if (!mediaUrinull && startX < 0.25*screenWidth && Math.abs(distanceX) < 50 && distanceY > 100) {
// TODO 减小亮度
setBrightness(-6);
}
else if (!mediaUrinull && startX < 0.25*screenWidth && Math.abs(distanceX) < 50 && distanceY < -100) {
// TODO 增加亮度
setBrightness(6);
}
if (!mediaUrinull && startX > 0.75*screenWidth && Math.abs(distanceX) < 50 && distanceY > 100) {
// TODO 减小音量
setVolume(false);
}
else if (!mediaUrinull && startX > 0.75*screenWidth && Math.abs(distanceX) < 50 && distanceY < -100) {
// TODO 增加音量
setVolume(true);
}
if ( !mediaUrinull && Math.abs(distanceY) < 50 && distanceX > 100) {
// TODO 快进
setvideo( true);
}
else if ( !mediaUrinull && Math.abs(distanceY) < 50 && distanceX < -100) {
// TODO 快退
setvideo( false);
}
break;
}
}
return super.onTouchEvent(event);
}
// 设置屏幕亮度 lp = 0 最暗 lp = 1 最亮
private void setBrightness( float brightness) {
// 首先判断是否被锁定
if ( !islocked) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = lp.screenBrightness + brightness / 255.0f;
if (lp.screenBrightness > 1) {
lp.screenBrightness = 1;
} else if ( lp.screenBrightness < 0.1) {
lp.screenBrightness = (float) 0.1;
}
getWindow().setAttributes(lp);
float sb = lp.screenBrightness;
tv_video_details_textview.setVisibility(View.VISIBLE);
tv_video_details_textview.setText("亮度:" + (int) Math.ceil(sb * 100) + "%");
// 隐藏掉中间信息框
// if(mRunnable_4 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_4); // 清除线程
// msgHandler.postDelayed(mRunnable_4, 1000); // 延时1秒
// }
}
}
// 设置音量大小
@SuppressLint("MissingPermission")
private void setVolume(boolean flag) {
// 首先判断是否被锁定
if ( !islocked) {
// 获取音量管理器
AudioManager manager = (AudioManager) getSystemService(AUDIO_SERVICE);
// 获取当前音量
int curretnV = manager.getStreamVolume(AudioManager.STREAM_MUSIC);
if ( flag) {
curretnV ++ ;
} else {
curretnV -- ;
if (curretnV < 0) {
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(300);
curretnV = 0;
}
}
manager.setStreamVolume(AudioManager.STREAM_MUSIC, curretnV, AudioManager.FLAG_SHOW_UI);
tv_video_details_textview.setVisibility(View.VISIBLE);
tv_video_details_textview.setText("音量:" + (float)Math.ceil((curretnV / 16.0) * 100) + "%");
// 隐藏掉中间信息框
// if(mRunnable_4 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_4); // 清除线程
// msgHandler.postDelayed(mRunnable_4, 1000); // 延时1秒
// }
}
}
// 设置快进快退
private void setvideo( boolean flag) {
// 首先判断是否被锁定
if ( !islocked) {
// controlBar.setVisibility( View.VISIBLE); // 显示主工具栏
int currentT = videoview.getCurrentPosition();//播放的位置
int nowTime;
if ( flag) {
// TODO 真为快进
videoview.seekTo(currentT + 300);
nowTime = (currentT + 300);
} else {
// TODO 假为快退
videoview.seekTo(currentT - 300);
nowTime = (currentT - 300);
}
if ( nowTime < 0)
nowTime = 0;
changeTime( nowTime);
// 隐藏掉主工具栏
if(mRunnable_2 != null) {
msgHandler.removeCallbacks(mRunnable_2);
msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
}
}
}
// 定时器 /
@Override
protected void onStop()
{
if(timer != null)
{
//本界面隐藏时,要停止定时器(因为本界面已经隐藏了,如果继续刷新界面将毫无意义、白白耗费CPU)
timer.cancel();
timer = null;
}
if(timer_current != null)
{
//本界面隐藏时,要停止定时器(因为本界面已经隐藏了,如果继续刷新界面将毫无意义、白白耗费CPU)
timer_current.cancel();
timer_current = null;
}
if(timer_currentposition != null)
{
//本界面隐藏时,要停止定时器(因为本界面已经隐藏了,如果继续刷新界面将毫无意义、白白耗费CPU)
timer_currentposition.cancel();
timer_currentposition = null;
}
videoview.stopPlayback();
super.onStop();
}
// 定时器 /
@Override
protected void onStart()
{
super.onStart();
if(timer == null)
{
// 启动定时器(间隔500ms)
timerTask = new MyTimerTask();
timer = new Timer();
timer.schedule(timerTask, 500, 500);
}
if(timer_current == null && orientation == 2)
{
// 启动定时器(间隔500ms)
currentTimeTask = new CurrentTimerTask();
timer_current = new Timer();
timer_current.schedule(currentTimeTask, 500, 500);
}
if(timer_currentposition == null)
{
// 启动定时器(间隔500ms)
currentposiTask = new CurrentpositionTask();
timer_currentposition = new Timer();
timer_currentposition.schedule(currentposiTask, 500, 500);
}
// if ( uri != null && mRunnable_8 != null) {
// // 将标题显示
// msgHandler.removeCallbacks(mRunnable_7); // 清除线程
// new Thread(mRunnable_8).start();
// }
}
@Override
protected void onDestroy() {
super.onDestroy();
if (videoview != null) {
videoview.suspend();
}
try {
videoview.stopPlayback();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
if (!videoview.isPlaying()) {
videoview.resume();
}
}
@Override
protected void onPause() {
super.onPause();
if (videoview.canPause()) {
videoview.pause();
}
}
// 获得视频总时长
private String getAllTime() {
SimpleDateFormat sdf;
int allTime = videoview.getDuration(); // 获取视频时间总长度
if ( allTime <= 0) {
allTime = 0;
}
int hour = allTime / (3600 * 1000);
if ( hour < 0 || hour == 0) {
sdf = new SimpleDateFormat("mm:ss"); // 转换时间
} else {
sdf = new SimpleDateFormat("HH:mm:ss"); // 转换时间
}
sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); // 设置中国时区
String result = sdf.format(allTime); // 将时分秒转换成String类型
return result;
}
// 秒数转换为分钟数
private void changeTime( int time) {
SimpleDateFormat sdf;
int hour = time / (3600 * 1000);
if ( hour < 0 || hour == 0) {
sdf = new SimpleDateFormat("mm:ss"); // 转换时间
} else {
sdf = new SimpleDateFormat("HH:mm:ss"); // 转换时间
}
sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); // 设置中国时区
String currentTime = sdf.format(time); // 将时分秒转换成String类型
String result = currentTime + " / " + getAllTime();
// tv_video_details_textview.setVisibility(View.VISIBLE);
// tv_video_details_textview.setText( result);
Log.w("时间", time + "");
// 隐藏掉中间信息框
// if(mRunnable_4 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_4); // 清除线程
// msgHandler.postDelayed(mRunnable_4, 1000); // 延时1秒
// }
}
// 当视频停止时
// 更新显示进度: duration总时长 position 当前播放位置
public void showProgess(int duration, int position)
{
// 转成百分比
int percent = position * 100 / duration;
seekBar_vd.setProgress( percent);
}
// 消息支持 /
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
if ( msg.what == 1) {
// 从消息里去除进度数据,然后更新UI
int duration = msg.arg1;
int position = msg.arg2;
showProgess(duration, position);
} else if (msg.what == 2) {
// 将主工具栏隐藏
ll_head_all.setVisibility(View.GONE);
tv_video_details_name.setVisibility(View.GONE);
rl_video_details_content.setVisibility(View.GONE);
rlSeekBar.setVisibility(View.GONE);
imVdBack.setVisibility(View.GONE);
tv_video_details_textview.setVisibility(View.GONE);
} else if ( msg.what == 3) {
// 将锁定按钮隐藏
// imageButton_islocked.setVisibility( View.GONE);
} else if ( msg.what == 4) {
// 将中间信息框隐藏
// brightnessTextView.setVisibility(View.GONE);
} else if ( msg.what == 5) {
// 将分享按钮隐藏
// imageButton_share.setVisibility(View.GONE);
} else if ( msg.what == 6) {
// 实时更新当前系统时间UI
String timestr = (String)msg.obj;
// ((TextView)findViewById(R.id.id_time)).setText(timestr);
} else if ( msg.what == 7) {
// 将标题Layout隐藏
// titleBar.setVisibility(View.GONE);
} else if ( msg.what == 8) {
// 显示标题
// String titleUri = (String)msg.obj;
// ((TextView)findViewById(R.id.id_title)).setText(titleUri);
} else if ( msg.what == 9) {
// 显示当前位置
String curr = (String) msg.obj;
//设置开始时间(实事播放时间)
((TextView)findViewById(R.id.tv_vd_start_time)).setText(curr);
}
}
}
// 定时器任务 ///
private class MyTimerTask extends TimerTask {
@Override
public void run() {
// 如果当前VideoView并不在播放中,就不做什么
if ( !videoview.isPlaying() )
return;
// 取得当前播放进度
int duration = videoview.getDuration(); // 获取视频的总时长 ,单位 毫秒(ms)
int position = videoview.getCurrentPosition(); // 获取视频的当前播放位置,单位 毫秒(ms)
// 注意:在工作线程里不能直接更新UI,必须发消息给UI线程,然后在Handler里处理
// 发消息给UI线程
Message msg = new Message();
msg.what = 1; // 消息类型
msg.arg1 = duration; // 第1个参数
msg.arg2 = position; // 第2个参数
msgHandler.sendMessage(msg);
}
}
// 定时器任务,在横屏实时显示当前时间
private class CurrentTimerTask extends TimerTask {
SimpleDateFormat sdfc = new SimpleDateFormat("HH:mm:ss");
@Override
public void run() {
// 得到当前时间
String timestr = sdfc.format(System.currentTimeMillis());
// 在定时器回调里也不能更新UI,需要发消息5
Message msg = new Message();
msg.what = 6; // 消息类型
msg.obj = timestr;
msgHandler.sendMessage(msg);
}
}
// 定时器任务,实时显示当前位置
private class CurrentpositionTask extends TimerTask {
SimpleDateFormat sdf;
@Override
public void run() {
// 得到当前时间
int hour = videoview.getCurrentPosition() / (3600 * 1000);
if ( hour < 0 || hour == 0) {
sdf = new SimpleDateFormat("mm:ss"); // 转换时间
} else {
sdf = new SimpleDateFormat("HH:mm:ss"); // 转换时间
}
sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); // 设置中国时区
String currentTime = sdf.format(videoview.getCurrentPosition()); // 将时分秒转换成String类型
String result = currentTime + " / " + getAllTime();
String startTime = currentTime;
// 在定时器回调里也不能更新UI,需要发消息5
Message msg = new Message();
msg.what = 9; // 消息类型
// msg.obj = result;
msg.obj = startTime;
msgHandler.sendMessage(msg);
}
}
private long exitTime = 0; // 判断点击返回键的次数
// 返回键判断点击两次退出
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){
if((System.currentTimeMillis()-exitTime) > 2000){
Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
System.exit(0);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
// 发送隐藏主工具栏的消息
private Runnable mRunnable_2 = new Runnable() {
@Override
public void run() {
Message msg = new Message();
msg.what = 2;
msgHandler.sendMessage(msg);
}
};
}
4.AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission
android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
4.自定义CustomVideoView
package com.example.m1571.myvideoview;
import android.content.Context;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.VideoView;
/**
* 自定义视频播放类
*/
public class CustomVideoView extends VideoView {
public CustomVideoView(Context context) {
super(context);
}
public CustomVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//我们重新计算高度
int width = getDefaultSize(0, widthMeasureSpec);
int height = getDefaultSize(0, heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
super.setOnPreparedListener(l);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event);
}
}
图标可以去这个网站去找:矢量图
五.具体的功能简单分析:
1.VideoView第一次加载没有播放时显示的网络视频的某一帧,用于当作视频的封面效果:
//网络视频
String videoUrl2 = Utils.videoUrl1;
uri = Uri.parse(videoUrl2);
getNetVideoBitmap(videoUrl2);
/**
* 显示网络视频的某一帧做封面
*
* @param videoUrl
* @return
*/
public Bitmap getNetVideoBitmap(String videoUrl) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
//根据url获取缩略图
retriever.setDataSource(videoUrl, new HashMap());
//获得第一帧图片
bitmap = retriever.getFrameAtTime();
imageView.setImageBitmap(bitmap);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} finally {
retriever.release();
}
return bitmap;
}
2.播放按钮的处理:
// 播放控制 (暂停、继承)
imStartEnd.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View view) {
// findViewById(R.id.id_help).setVisibility(View.GONE); //将说明关闭
// 此处可以优化 (事先把两个图标先加载好, 不要每次现加载)
if ( videoview.isPlaying()) {
Log.w(TAG, "正在播放,现在暂停...");
if ( uri != null) {
videoview.pause();
imStartEnd.setImageDrawable(getDrawable(R.drawable.ic_play));
im_video_details_start.setVisibility(View.VISIBLE);
}
} else {
Log.w(TAG, "不在播放,现在继续...");
if ( uri != null){
videoview.start();
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
}
}
}
});
3.视频播放进度条的监听处理:
// 播放控制(进度拖放)
seekBar_vd.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// 进度条开始拖动的时候
// 首先判断是不是用户操作,不然每隔0.5秒定时器会刷新一直显示
if (fromUser) {
// controlBar.setVisibility(View.VISIBLE);
SimpleDateFormat sdf;
double currentTime = (progress / 100.0 )* videoview.getDuration(); // 将当前位置换算成视频总时长的指定位置时间
int hour = (int) (currentTime / (3600 * 1000));
if ( hour < 0 || hour == 0) {
sdf = new SimpleDateFormat("mm:ss"); // 转换时间
} else {
sdf = new SimpleDateFormat("HH:mm:ss"); // 转换时间
}
sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); // 设置中国时区
String startformat = sdf.format(currentTime);//开始及滑动的时间
String allTime = getAllTime();//总时长
//合并显示的时间
String result = sdf.format(currentTime) + " / " + getAllTime(); // 将时分秒转换成String类型
tv_vd_start_time.setText(startformat);
tv_vd_all_time.setText(allTime);
tv_video_details_textview.setVisibility(View.VISIBLE);
tv_video_details_textview.setText( result);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
// 控制视频跳转到目标位置
int progress = seekBar.getProgress();
int position = progress * videoview.getDuration() / 100;
videoview.seekTo( position );
// 隐藏掉主工具栏
// if(mRunnable_2 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_2); // 清除线程
// msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
// }
// // 隐藏掉中间信息框
// if(mRunnable_4 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_4); // 清除线程
// msgHandler.postDelayed(mRunnable_4, 1000); // 延时1秒
// }
}
});
4.视频封面第一帧图片的监听:
imageView.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View v) {
//播放
videoview.start();
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
imStartEnd.setImageDrawable(getDrawable(R.drawable.ic_pause));
}
});
5.视频循环播放的监听:
//循环播放
videoview.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@SuppressLint("NewApi")
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
Toast.makeText(MainActivity.this, "视频结束,马上自动重播", Toast.LENGTH_SHORT).show();
imageView.setVisibility(View.GONE);
im_video_details_start.setVisibility(View.INVISIBLE);
videoview.setVideoPath(Utils.videoUrl1);
videoview.requestFocus();
videoview.start();
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
}
});
6.对于视频播放器的监听,可以实现点击播放暂停功能和双击播放暂停功能:
//监听视频
videoview.setOnTouchListener(new View.OnTouchListener() {
long lastTime,curTime; // 最后一点击和当前点击的时间
@SuppressLint("NewApi")
@Override
public boolean onTouch(View v, MotionEvent event) {
//若已经播放则暂停,反之则播放--单击效果
// if (videoview.isPlaying()) {
// videoview.pause();
// im_video_details_start.setVisibility(View.VISIBLE);
// } else {
// videoview.start();
// im_video_details_start.setVisibility(View.INVISIBLE);
// }
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
lastTime = curTime; // 获取第一次点击时间
curTime = System.currentTimeMillis(); // 获取当前时间
Log.w(TAG, "单击点中画面..");
// imageButton_islocked.setVisibility(View.VISIBLE);
// internetControlBar.setVisibility(View.GONE);
// findViewById(R.id.id_help).setVisibility(View.GONE); //将说明关闭
// 首先判断是否被锁定
if (!islocked) {
ll_head_all.setVisibility(View.VISIBLE);
tv_video_details_name.setVisibility(View.VISIBLE);
rl_video_details_content.setVisibility(View.VISIBLE);
rlSeekBar.setVisibility(View.VISIBLE);
imVdBack.setVisibility(View.VISIBLE);
// imageButton_share.setVisibility(View.VISIBLE);
// titleBar.setVisibility(View.VISIBLE);
if (uri == null) {
mediaUrinull = true;
} else {
mediaUrinull = false;
}
// 隐藏掉主工具栏
if (mRunnable_2 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
msgHandler.removeCallbacks(mRunnable_2); // 清除线程
msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
}
// 隐藏掉分享按钮
// if (mRunnable_5 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_5); // 清除线程
// msgHandler.postDelayed(mRunnable_5, 3000); // 延时3秒
// }
// 隐藏标题Layout按钮
// if (mRunnable_7 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_7); // 清除线程
// msgHandler.postDelayed(mRunnable_7, 3000); // 延时3秒
// }
}
// 隐藏锁定按钮
// if (mRunnable_3 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_3); // 清除线程
// msgHandler.postDelayed(mRunnable_3, 3000); // 延时3秒
// }
// 判断双击的时间间隔
if (curTime - lastTime < 500) {
Log.w(TAG, "双击点中画面..");
// 首先判断是否被锁定
if (!islocked) {
if (videoview.isPlaying() && !mediaUrinull) {
videoview.pause();
imStartEnd.setImageDrawable(getDrawable(R.drawable.ic_play));
im_video_details_start.setVisibility(View.VISIBLE);
} else if (!videoview.isPlaying() && !mediaUrinull) {
videoview.start();
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
im_video_details_start.setVisibility(View.INVISIBLE);
// imageButton_pause.setImageDrawable(getDrawable(R.drawable.ic_pause));
}
}
return true;
}
break;
}
default:
break;
}
return false;
}
});
7.视频缓冲的监听(在缓冲过程中加载动画):
// 视频缓冲监听
loadingGif = (GifImageView) findViewById(R.id.id_loading_gif);
videoview.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START){
//Toast.makeText(MainActivity.this, "正在缓冲", Toast.LENGTH_LONG).show();
loadingGif.setVisibility(View.VISIBLE);
Log.w(TAG,"正在缓冲");
}else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_END){
//此接口每次回调完START就回调END,若不加上判断就会出现缓冲图标一闪一闪的卡顿现象
if(mp.isPlaying()){
//Toast.makeText(MainActivity.this, "缓冲结束", Toast.LENGTH_LONG).show();
loadingGif.setVisibility(View.GONE);
Log.w(TAG,"缓冲结束");
videoview.setVisibility(View.VISIBLE);
}
}
return true;
}
});
8.视频错误监听:
// 错误监听
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.w("通知", "播放中出现错误");
switch (what) {
case -1004:
Log.w("Streaming Media", "MEDIA_ERROR_IO");
break;
case -1007:
Log.w("Streaming Media", "MEDIA_ERROR_MALFORMED");
break;
case 200:
Log.w("Streaming Media", "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK");
break;
case 100:
Log.w("Streaming Media", "MEDIA_ERROR_SERVER_DIED");
break;
case -110:
Log.w("Streaming Media", "MEDIA_ERROR_TIMED_OUT");
break;
case 1:
Log.w("Streaming Media", "MEDIA_ERROR_UNKNOWN");
break;
case -1010:
Log.w("Streaming Media", "MEDIA_ERROR_UNSUPPORTED");
break;
}
switch (extra) {
case 800:
Log.w("Streaming Media", "MEDIA_INFO_BAD_INTERLEAVING");
break;
case 702:
Log.w("Streaming Media", "MEDIA_INFO_BUFFERING_END");
break;
case 701:
Log.w("Streaming Media", "MEDIA_INFO_METADATA_UPDATE");
break;
case 802:
Log.w("Streaming Media", "MEDIA_INFO_METADATA_UPDATE");
break;
case 801:
Log.w("Streaming Media", "MEDIA_INFO_NOT_SEEKABLE");
break;
case 1:
Log.w("Streaming Media", "MEDIA_INFO_UNKNOWN");
break;
case 3:
Log.w("Streaming Media", "MEDIA_INFO_VIDEO_RENDERING_START");
break;
case 700:
Log.w("Streaming Media", "MEDIA_INFO_VIDEO_TRACK_LAGGING");
break;
}
loadingGif.setVisibility(View.GONE);
mediaUri = null;
return false;
}
});
9.全屏控制(借鉴):
imageButton_fullScreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
//切换竖屏
Log.w(TAG, "点击缩小");
MainActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//setContentView(R.layout.activity_main_portrait);
}else{
//切换横屏
Log.w(TAG, "点击全屏");
MainActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//setContentView(R.layout.activity_main_landscape);
}
}
});
10.视频准备完毕,可以获取视频的总时长并展示:
/**
* 视频准备完毕
*/
videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) { //监听视频准备好
String allTime = getAllTime();
tv_vd_all_time.setText(allTime);
// mProgressBar.setVisibility(View.GONE);
// int alltime=videoview.getDuration()/1000;//这里获取到的时间是ms为单位的,所以要转换成秒的话就要除以1000
// tv_vd_all_time.setText(alltime+"");
// int currentPosition = videoview.getCurrentPosition();
//
// String stringForTime = stringForTime(alltime);
// tv_vd_all_time.setText(stringForTime);
}
});
11.调用手机系统视频文件夹选择本地的视频文件来播放:
// 点击 ‘打开’ 按钮
@SuppressLint("NewApi")
public void openFile(View view) {
Intent intent = new Intent( Intent.ACTION_GET_CONTENT); // 特殊种类的数据,比如相片或者录音
intent.setType("video/*"); // 只显示视频
startActivityForResult(intent, REQ_OPEN_FILE);
// ImageView im_start_end = (ImageView) findViewById(R.id.im_start_end);
// findViewById(R.id.id_help).setVisibility(View.GONE); //将说明关闭
if (uri != null) {
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
} else {
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_play));
}
}
// 从媒体管理器返回
@SuppressLint("NewApi")
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ( requestCode == REQ_OPEN_FILE) {
if ( resultCode == RESULT_OK) {
uri = data.getData();
videoview.setVideoURI(uri);
videoview.start();
isInternetMedia = false;
if (uri != null) {
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_pause));
} else {
imStartEnd.setImageDrawable( getDrawable(R.drawable.ic_play));
}
}
// 隐藏掉主工具栏
if(mRunnable_2 != null) {
msgHandler.removeCallbacks(mRunnable_2);
msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
}
// 隐藏锁定按钮
// if(mRunnable_3 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_3); // 清除线程
// msgHandler.postDelayed(mRunnable_3, 3000); // 延时3秒
// }
// 隐藏掉分享按钮
// if(mRunnable_5 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_5); // 清除线程
// msgHandler.postDelayed(mRunnable_5, 3000); // 延时3秒
// }
// 隐藏标题Layout按钮
// if(mRunnable_7 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_7); // 清除线程
// msgHandler.postDelayed(mRunnable_7, 3000); // 延时3秒
// }
}
}
在onCreate方法中使用:
// 接受外部调用
// Intent intent = getIntent();
// Uri mediaUri = intent.getData();
// uri = intent.getData();
uri = Uri.parse(videoUrl2);
// if(uri != null)
// {
// videoview.setVideoURI(uri);
// videoview.start();
// }
11.分享视频:
case R.id.ll_vd_share:
Toast.makeText(this, "share", Toast.LENGTH_SHORT).show();
if ( !isInternetMedia && uri != null) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("video/*");
startActivity(Intent.createChooser(intent, "分享我的视频到..."));
} else if ( isInternetMedia) {
// String content = ((EditText) findViewById(R.id.id_internetUri)).getText().toString();
// content = content.trim(); // 去除两边的空白
// if ( content.length() == 0) return;
Intent intent = new Intent( Intent.ACTION_SEND);
intent.setType( "text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "KING");
startActivity(Intent.createChooser(intent, "分享网络视频地址到..."));
}
break;
12.监听屏幕的滑动事件,实现滑动调声音,亮度以及快进快退:
// 监听触摸屏幕
@Override
public boolean onTouchEvent(MotionEvent event) {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
if (uri == null) {
mediaUrinull = true;
} else {
mediaUrinull = false;
}
switch ( event.getAction()) {
case MotionEvent.ACTION_DOWN: {
startX = event.getX();
startY = event.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
// TODO 音量
float distanceX = event.getX() - startX;
float distanceY = event.getY() - startY;
if (!mediaUrinull && startX < 0.25*screenWidth && Math.abs(distanceX) < 50 && distanceY > 100) {
// TODO 减小亮度
setBrightness(-6);
}
else if (!mediaUrinull && startX < 0.25*screenWidth && Math.abs(distanceX) < 50 && distanceY < -100) {
// TODO 增加亮度
setBrightness(6);
}
if (!mediaUrinull && startX > 0.75*screenWidth && Math.abs(distanceX) < 50 && distanceY > 100) {
// TODO 减小音量
setVolume(false);
}
else if (!mediaUrinull && startX > 0.75*screenWidth && Math.abs(distanceX) < 50 && distanceY < -100) {
// TODO 增加音量
setVolume(true);
}
if ( !mediaUrinull && Math.abs(distanceY) < 50 && distanceX > 100) {
// TODO 快进
setvideo( true);
}
else if ( !mediaUrinull && Math.abs(distanceY) < 50 && distanceX < -100) {
// TODO 快退
setvideo( false);
}
break;
}
}
return super.onTouchEvent(event);
}
// 设置屏幕亮度 lp = 0 最暗 lp = 1 最亮
private void setBrightness( float brightness) {
// 首先判断是否被锁定
if ( !islocked) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = lp.screenBrightness + brightness / 255.0f;
if (lp.screenBrightness > 1) {
lp.screenBrightness = 1;
} else if ( lp.screenBrightness < 0.1) {
lp.screenBrightness = (float) 0.1;
}
getWindow().setAttributes(lp);
float sb = lp.screenBrightness;
tv_video_details_textview.setVisibility(View.VISIBLE);
tv_video_details_textview.setText("亮度:" + (int) Math.ceil(sb * 100) + "%");
// 隐藏掉中间信息框
// if(mRunnable_4 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_4); // 清除线程
// msgHandler.postDelayed(mRunnable_4, 1000); // 延时1秒
// }
}
}
// 设置音量大小
@SuppressLint("MissingPermission")
private void setVolume(boolean flag) {
// 首先判断是否被锁定
if ( !islocked) {
// 获取音量管理器
AudioManager manager = (AudioManager) getSystemService(AUDIO_SERVICE);
// 获取当前音量
int curretnV = manager.getStreamVolume(AudioManager.STREAM_MUSIC);
if ( flag) {
curretnV ++ ;
} else {
curretnV -- ;
if (curretnV < 0) {
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(300);
curretnV = 0;
}
}
manager.setStreamVolume(AudioManager.STREAM_MUSIC, curretnV, AudioManager.FLAG_SHOW_UI);
tv_video_details_textview.setVisibility(View.VISIBLE);
tv_video_details_textview.setText("音量:" + (float)Math.ceil((curretnV / 16.0) * 100) + "%");
// 隐藏掉中间信息框
// if(mRunnable_4 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_4); // 清除线程
// msgHandler.postDelayed(mRunnable_4, 1000); // 延时1秒
// }
}
}
// 设置快进快退
private void setvideo( boolean flag) {
// 首先判断是否被锁定
if ( !islocked) {
// controlBar.setVisibility( View.VISIBLE); // 显示主工具栏
int currentT = videoview.getCurrentPosition();//播放的位置
int nowTime;
if ( flag) {
// TODO 真为快进
videoview.seekTo(currentT + 300);
nowTime = (currentT + 300);
} else {
// TODO 假为快退
videoview.seekTo(currentT - 300);
nowTime = (currentT - 300);
}
if ( nowTime < 0)
nowTime = 0;
changeTime( nowTime);
// 隐藏掉主工具栏
if(mRunnable_2 != null) {
msgHandler.removeCallbacks(mRunnable_2);
msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
}
}
}
// 秒数转换为分钟数
private void changeTime( int time) {
SimpleDateFormat sdf;
int hour = time / (3600 * 1000);
if ( hour < 0 || hour == 0) {
sdf = new SimpleDateFormat("mm:ss"); // 转换时间
} else {
sdf = new SimpleDateFormat("HH:mm:ss"); // 转换时间
}
sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); // 设置中国时区
String currentTime = sdf.format(time); // 将时分秒转换成String类型
String result = currentTime + " / " + getAllTime();
// tv_video_details_textview.setVisibility(View.VISIBLE);
// tv_video_details_textview.setText( result);
Log.w("时间", time + "");
// 隐藏掉中间信息框
// if(mRunnable_4 != null) { // 判断是否重复点击,是的话清除掉这个线程重新新建一个
// msgHandler.removeCallbacks(mRunnable_4); // 清除线程
// msgHandler.postDelayed(mRunnable_4, 1000); // 延时1秒
// }
}
13.获取视频总时长:
// 获得视频总时长
private String getAllTime() {
SimpleDateFormat sdf;
int allTime = videoview.getDuration(); // 获取视频时间总长度
if ( allTime <= 0) {
allTime = 0;
}
int hour = allTime / (3600 * 1000);
if ( hour < 0 || hour == 0) {
sdf = new SimpleDateFormat("mm:ss"); // 转换时间
} else {
sdf = new SimpleDateFormat("HH:mm:ss"); // 转换时间
}
sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); // 设置中国时区
String result = sdf.format(allTime); // 将时分秒转换成String类型
return result;
}
14.发送消息及定时任务:
private Handler msgHandler;
msgHandler = new MyHandler();
// 发送隐藏主工具栏的消息
private Runnable mRunnable_2 = new Runnable() {
@Override
public void run() {
Message msg = new Message();
msg.what = 2;
msgHandler.sendMessage(msg);
}
};
}
// 隐藏掉主工具栏
if(mRunnable_2 != null) {
msgHandler.removeCallbacks(mRunnable_2);
msgHandler.postDelayed(mRunnable_2, 3000); // 延时3秒
}
// 消息支持 /
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
if ( msg.what == 1) {
// 从消息里去除进度数据,然后更新UI
int duration = msg.arg1;
int position = msg.arg2;
showProgess(duration, position);
} else if (msg.what == 2) {
// 将主工具栏隐藏
ll_head_all.setVisibility(View.GONE);
tv_video_details_name.setVisibility(View.GONE);
rl_video_details_content.setVisibility(View.GONE);
rlSeekBar.setVisibility(View.GONE);
imVdBack.setVisibility(View.GONE);
tv_video_details_textview.setVisibility(View.GONE);
} else if ( msg.what == 3) {
// 将锁定按钮隐藏
// imageButton_islocked.setVisibility( View.GONE);
} else if ( msg.what == 4) {
// 将中间信息框隐藏
// brightnessTextView.setVisibility(View.GONE);
} else if ( msg.what == 5) {
// 将分享按钮隐藏
// imageButton_share.setVisibility(View.GONE);
} else if ( msg.what == 6) {
// 实时更新当前系统时间UI
String timestr = (String)msg.obj;
// ((TextView)findViewById(R.id.id_time)).setText(timestr);
} else if ( msg.what == 7) {
// 将标题Layout隐藏
// titleBar.setVisibility(View.GONE);
} else if ( msg.what == 8) {
// 显示标题
// String titleUri = (String)msg.obj;
// ((TextView)findViewById(R.id.id_title)).setText(titleUri);
} else if ( msg.what == 9) {
// 显示当前位置
String curr = (String) msg.obj;
//设置开始时间(实事播放时间)
((TextView)findViewById(R.id.tv_vd_start_time)).setText(curr);
}
}
}
// 定时器任务 ///
private class MyTimerTask extends TimerTask {
@Override
public void run() {
// 如果当前VideoView并不在播放中,就不做什么
if ( !videoview.isPlaying() )
return;
// 取得当前播放进度
int duration = videoview.getDuration(); // 获取视频的总时长 ,单位 毫秒(ms)
int position = videoview.getCurrentPosition(); // 获取视频的当前播放位置,单位 毫秒(ms)
// 注意:在工作线程里不能直接更新UI,必须发消息给UI线程,然后在Handler里处理
// 发消息给UI线程
Message msg = new Message();
msg.what = 1; // 消息类型
msg.arg1 = duration; // 第1个参数
msg.arg2 = position; // 第2个参数
msgHandler.sendMessage(msg);
}
}
// 定时器任务,在横屏实时显示当前时间
private class CurrentTimerTask extends TimerTask {
SimpleDateFormat sdfc = new SimpleDateFormat("HH:mm:ss");
@Override
public void run() {
// 得到当前时间
String timestr = sdfc.format(System.currentTimeMillis());
// 在定时器回调里也不能更新UI,需要发消息5
Message msg = new Message();
msg.what = 6; // 消息类型
msg.obj = timestr;
msgHandler.sendMessage(msg);
}
}
// 定时器任务,实时显示当前位置
private class CurrentpositionTask extends TimerTask {
SimpleDateFormat sdf;
@Override
public void run() {
// 得到当前时间
int hour = videoview.getCurrentPosition() / (3600 * 1000);
if ( hour < 0 || hour == 0) {
sdf = new SimpleDateFormat("mm:ss"); // 转换时间
} else {
sdf = new SimpleDateFormat("HH:mm:ss"); // 转换时间
}
sdf.setTimeZone(TimeZone.getTimeZone("GMT+00:00")); // 设置中国时区
String currentTime = sdf.format(videoview.getCurrentPosition()); // 将时分秒转换成String类型
String result = currentTime + " / " + getAllTime();
String startTime = currentTime;
// 在定时器回调里也不能更新UI,需要发消息5
Message msg = new Message();
msg.what = 9; // 消息类型
// msg.obj = result;
msg.obj = startTime;
msgHandler.sendMessage(msg);
}
}
Demo后续会上