android实现控制视频播放次数,实质就是每个视频片段播放完后,通过MediaPlayer设置监听器setOnCompletionListener监听视频播放完毕,用Handler发送消息再次激活视频播放,从而达到控制播放次数的效果。视频文件foot_2_foot_crunch.mp4请放到assets文件夹下。
主界面代码如下:
activity_main.xml
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:orientation="vertical" 6 tools:context=".MainActivity" > 7 <include 8 android:id="@+id/topbar" 9 layout="@layout/topbar"/> 10 <RelativeLayout 11 android:layout_width="fill_parent" 12 android:layout_height="fill_parent"> 13 <LinearLayout 14 android:id="@+id/linearlayout" 15 android:layout_width="fill_parent" 16 android:layout_height="40dp" 17 android:orientation="horizontal" 18 android:layout_alignParentBottom="true" 19 android:gravity="center" 20 android:background="#4682B4"> 21 <Button 22 android:id="@+id/button_play" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:background="@drawable/play" 26 android:layout_gravity="center" 27 android:layout_marginRight="8dp" 28 android:layout_marginLeft="6dp"/> 29 <RelativeLayout 30 android:layout_width="fill_parent" 31 android:layout_height="fill_parent" 32 android:orientation="horizontal" 33 android:gravity="center"> 34 <TextView 35 android:id="@+id/textview_display_time" 36 android:layout_width="80dp" 37 android:layout_height="fill_parent" 38 android:textSize="16sp" 39 android:text="时间显示" 40 android:textColor="#ffffff" 41 android:gravity="center" 42 android:layout_alignParentRight="true"/> 43 <ProgressBar 44 android:id="@+id/progressbar" 45 android:layout_toLeftOf="@id/textview_display_time" 46 style="@style/pb_vedio" 47 android:layout_width="fill_parent" 48 android:layout_height="20dp" 49 android:layout_centerVertical="true" 50 android:progress="0"/> 51 </RelativeLayout> 52 </LinearLayout> 53 <LinearLayout 54 android:layout_above="@id/linearlayout" 55 android:layout_width="fill_parent" 56 android:layout_height="fill_parent" 57 android:background="#ffffff"> 58 <SurfaceView 59 android:id="@+id/surfaceview_vedio" 60 android:layout_width="wrap_content" 61 android:layout_height="wrap_content"/> 62 </LinearLayout> 63 <RelativeLayout 64 android:id="@+id/relativelayout1" 65 android:layout_above="@id/linearlayout" 66 android:layout_width="fill_parent" 67 android:layout_height="fill_parent"> 68 <TextView 69 android:id="@+id/textview_tip" 70 android:layout_width="fill_parent" 71 android:layout_height="fill_parent" 72 android:textSize="25sp" 73 android:text="提醒" 74 android:textColor="#ffffff" 75 android:gravity="center" 76 android:background="#80696969"/> 77 <LinearLayout 78 android:layout_width="wrap_content" 79 android:layout_height="fill_parent" 80 android:gravity="center"> 81 <Button 82 android:id="@+id/btn_left" 83 android:layout_width="wrap_content" 84 android:layout_height="wrap_content" 85 android:background="@drawable/btn_prev"/> 86 </LinearLayout> 87 <TextView 88 android:id="@+id/textview_count" 89 android:layout_width="wrap_content" 90 android:layout_height="wrap_content" 91 android:textSize="25sp" 92 android:paddingLeft="10dp" 93 android:text="0/30" 94 android:textColor="#000000"/> 95 <LinearLayout 96 android:layout_width="wrap_content" 97 android:layout_height="fill_parent" 98 android:gravity="center" 99 android:layout_alignParentRight="true"> 100 <Button 101 android:id="@+id/btn_right" 102 android:layout_width="wrap_content" 103 android:layout_height="wrap_content" 104 android:background="@drawable/btn_next"/> 105 </LinearLayout> 106 </RelativeLayout> 107 </RelativeLayout> 108 </LinearLayout>
topbar.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="40dp" 5 android:orientation="vertical" > 6 <TextView 7 android:id="@+id/topbar_textview" 8 android:layout_width="fill_parent" 9 android:layout_height="38dp" 10 android:text="加载中..." 11 android:textSize="16sp" 12 android:textColor="#ffffff" 13 android:paddingLeft="6dp" 14 android:gravity="center" 15 android:background="#4682B4"/> 16 <View 17 android:layout_width="fill_parent" 18 android:layout_height="2dp" 19 android:background="#2F4F4F"/> 20 </LinearLayout>
MainActivity.java
1 package com.example.playvediodemo; 2 3 import java.io.IOException; 4 5 import android.media.AudioManager; 6 import android.media.MediaPlayer; 7 import android.os.Bundle; 8 import android.os.Handler; 9 import android.os.Message; 10 import android.view.SurfaceHolder; 11 import android.view.SurfaceView; 12 import android.view.View; 13 import android.view.View.OnClickListener; 14 import android.widget.Button; 15 import android.widget.ProgressBar; 16 import android.widget.TextView; 17 import android.app.Activity; 18 import android.content.res.AssetFileDescriptor; 19 import android.content.res.AssetManager; 20 21 public class MainActivity extends Activity implements SurfaceHolder.Callback{ 22 private MediaPlayer player; 23 private SurfaceView surface; 24 private SurfaceHolder surfaceHolder; 25 private Button button,button_left,button_right; 26 private TextView tv_display_time,tv_tip,tv_count,tv_title; 27 private ProgressBar pb; 28 private Handler handler; 29 private int count;//播放动过个数 30 @Override 31 protected void onCreate(Bundle savedInstanceState) { 32 super.onCreate(savedInstanceState); 33 setContentView(R.layout.activity_main); 34 button = (Button)findViewById(R.id.button_play); 35 surface = (SurfaceView)findViewById(R.id.surfaceview_vedio); 36 tv_display_time = (TextView)findViewById(R.id.textview_display_time); 37 button_left = (Button)findViewById(R.id.btn_left); 38 button_right = (Button)findViewById(R.id.btn_right); 39 tv_title = (TextView)findViewById(R.id.topbar_textview); 40 tv_tip = (TextView)findViewById(R.id.textview_tip); 41 tv_count = (TextView)findViewById(R.id.textview_count); 42 pb = (ProgressBar)findViewById(R.id.progressbar); 43 44 player=new MediaPlayer(); 45 surfaceHolder=surface.getHolder();//SurfaceHolder是SurfaceView的控制接口 46 surfaceHolder.addCallback(this); //因为这个类实现了SurfaceHolder.Callback接口,所以回调参数直接this 47 //surfaceHolder.setFixedSize(720, 480);//显示的分辨率,不设置为视频默认 48 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置SurfaceView自己不管理缓冲区 49 surfaceHolder.setKeepScreenOn(true);//设置播放视频时保持屏幕常亮 50 51 pb.setMax(30); 52 //定义一个Hander实现自动播放N次对应的视频片段 53 handler = new Handler(){ 54 @Override 55 public void handleMessage(Message e){ 56 if(e.what==0x1000){ 57 player.start(); 58 button.setBackgroundResource(R.drawable.pause); 59 pb.setProgress(count); 60 //一项锻炼完成,不用再次播放动画,仅仅为了让进度条可以填满 61 }else if(e.what==0x1001){ 62 pb.setProgress(30); 63 } 64 } 65 }; 66 //监听播放一个视频片段完成 67 player.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){ 68 @Override 69 public void onCompletion(MediaPlayer arg0) { 70 if(count<(30-1)){ 71 handler.sendEmptyMessage(0x1000); 72 count++; 73 tv_count.setText(count+"/"+30); 74 }else{ 75 count=0; 76 handler.sendEmptyMessage(0x1001); 77 button.setBackgroundResource(R.drawable.play); 78 tv_tip.setVisibility(View.VISIBLE); 79 tv_tip.setText(30+"/"+30+" 动作完成."); 80 tv_count.setText(30+"/"+30); 81 } 82 } 83 }); 84 //控制播放暂停的按钮 85 button.setOnClickListener(new OnClickListener(){ 86 @Override 87 public void onClick(View arg0) { 88 if(player.isPlaying()){ 89 player.pause(); 90 button.setBackgroundResource(R.drawable.play); 91 tv_tip.setVisibility(View.VISIBLE); 92 tv_tip.setText("暂停中"); 93 }else{ 94 player.start(); 95 button.setBackgroundResource(R.drawable.pause); 96 tv_tip.setVisibility(View.GONE); 97 } 98 99 } 100 }); 101 //上一个视频 102 button_left.setOnClickListener(new OnClickListener(){ 103 @Override 104 public void onClick(View arg0) { 105 106 } 107 }); 108 //下一个视频 109 button_right.setOnClickListener(new OnClickListener(){ 110 @Override 111 public void onClick(View arg0) { 112 113 } 114 }); 115 } 116 117 @Override 118 public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 119 120 } 121 122 @Override 123 public void surfaceCreated(SurfaceHolder holder) { 124 AssetManager assetManager = this.getAssets(); 125 //必须在surface创建后才能初始化MediaPlayer,否则不会显示图像 126 player.reset(); 127 player.setAudioStreamType(AudioManager.STREAM_MUSIC); 128 player.setDisplay(surfaceHolder); 129 try { 130 AssetFileDescriptor fileDescriptor = assetManager.openFd("foot_2_foot_crunch.mp4"); 131 //设置显示视频显示在SurfaceView上 132 player.setDataSource(fileDescriptor.getFileDescriptor(), 133 fileDescriptor.getStartOffset(), 134 fileDescriptor.getLength()); 135 player.prepare(); 136 player.start(); 137 button.setBackgroundResource(R.drawable.pause); 138 count=0; 139 tv_count.setText(count+"/"+30); 140 tv_tip.setVisibility(View.GONE); 141 } catch (IOException e) { 142 e.printStackTrace(); 143 } 144 } 145 146 @Override 147 public void surfaceDestroyed(SurfaceHolder holder) { 148 149 } 150 @Override 151 protected void onDestroy() { 152 super.onDestroy(); 153 if(player.isPlaying()){ 154 player.stop(); 155 } 156 player.release();//Activity销毁时停止播放,释放资源。不做这个操作,即使退出还是能听到视频播放的声音 157 } 158 }
values文件夹下styles.xml
1 <resources> 2 <style name="pb_vedio" parent="@android:style/Widget.ProgressBar.Horizontal"> 3 <item name="android:maxHeight">50dip</item> 4 <item name="android:minHeight">10dip</item> 5 <item name="android:indeterminateOnly">false</item> 6 <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item> 7 <item name="android:progressDrawable">@drawable/pb_vedio</item> 8 </style> 9 10 </resources>
以下是两个个自定义button和一个自定义progressbar样式的代码,都放在drawable文件夹下
自定义进度条样式
pd_vedio.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 3 4 <item android:id="@android:id/background"> 5 <shape > 6 <!-- corners android:radius="2dip" /--> 7 <gradient 8 android:angle="270" 9 android:centerY="0.75" 10 android:endColor="#AFEEEE" 11 android:startColor="#AFEEEE" /> 12 <stroke 13 android:width="1dp" 14 android:color="#ffffff"/> 15 </shape> 16 </item> 17 18 <item android:id="@android:id/secondaryProgress"> 19 20 <clip > 21 <shape > 22 <!--corners android:radius="2dip" /--> 23 <gradient 24 android:angle="270" 25 android:centerY="0.75" 26 android:endColor="#A04682B4" 27 android:startColor="#A04682B4" /> 28 <stroke 29 android:width="1dp" 30 android:color="#ffffff"/> 31 </shape> 32 </clip> 33 </item> 34 35 <item android:id="@android:id/progress"> 36 37 <clip > 38 <shape > 39 <!--corners android:radius="2dip" /--> 40 <gradient 41 android:angle="270" 42 android:centerY="0.75" 43 android:endColor="#A04682B4" 44 android:startColor="#A04682B4"/> 45 <stroke 46 android:width="1dp" 47 android:color="#ffffff"/> 48 </shape> 49 50 </clip> 51 </item> 52 </layer-list>
btn_next.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android" > 3 <item android:drawable="@drawable/next_pressed" android:state_pressed="true"/> 4 <item android:drawable="@drawable/next" android:state_focused="false" android:state_pressed="false"/> 5 <item android:drawable="@drawable/next_pressed" android:state_focused="true"/> 6 <item android:drawable="@drawable/next" android:state_focused="false"/> 7 </selector>
btn_prev.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android" > 3 <item android:drawable="@drawable/prev_pressed" android:state_pressed="true"/> 4 <item android:drawable="@drawable/prev" android:state_focused="false" android:state_pressed="false"/> 5 <item android:drawable="@drawable/prev_pressed" android:state_focused="true"/> 6 <item android:drawable="@drawable/prev" android:state_focused="false"/> 7 </selector>