音乐播放器和视频播放器的使用
2015-10-26 20:05
309 查看
player.setOnPreparedListener();//当资源准备完成的时候就能够开始播放
mediaPlayerP只有播放中的状态,程序进行处理的时候,需要检测下player的各种状态;使用成员变量标识
音乐播放以及MediaPlayer的使用:
service的使用:
MusicService的使用:
播放视频的部分:
自定义VideoView;
两个布局文件:
mediaPlayerP只有播放中的状态,程序进行处理的时候,需要检测下player的各种状态;使用成员变量标识
音乐播放以及MediaPlayer的使用:
package com.bluezhang.standerdcompuse; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; import com.bluezhang.standerdcompuse.service.MusicService; public class MainActivity extends AppCompatActivity { private BroadcastReceiver progressRcciver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent != null) { String[] urls = intent.getStringArrayExtra("urls"); if (urls.length == 0) { if (BuildConfig.DEBUG) Log.d("MainActivity", "URLS长度为0"); }else{ StringBuilder sb = new StringBuilder(); for (int i = 0; i < urls.length; i++) { sb.append(urls[i]); sb.append('\n'); } txtInfo.setText(sb.toString()); } } } }; private TextView txtInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtInfo = (TextView)findViewById(R.id.progress_info); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @Override protected void onResume() { super.onResume(); IntentFilter intentFilter = new IntentFilter(Constants.ACTION_PROGRESS_UPDATE); registerReceiver(progressRcciver,intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(progressRcciver); } public void btnAddRequest(View view) { Intent service = new Intent(Constants.ACTION_DARA_FETCH); service.putExtra("action",0);//0 代表添加请求 service.putExtra("url","http://www.baidu.com/"); service.setPackage(getPackageName()); startService(service); } public void btnGetProgress(View view) { Intent service = new Intent(Constants.ACTION_DARA_FETCH); service.putExtra("action",1);//0 代表添加请求 service.setPackage(getPackageName()); startService(service); } public void removeProgress(View view) { Intent service = new Intent(Constants.ACTION_DARA_FETCH); service.putExtra("action", 1);//0 代表添加请求 service.setPackage(getPackageName()); startService(service); } /** * 启动服务播放音乐 * * @param view */ public void btnPlayClick(View view) { Intent intent = new Intent(this, MusicService.class); intent.putExtra("action",0); intent.putExtra("url","http://10.10.60.18:8080/nobody.mp3"); startService(intent); } public void btnPauseMusic(View view) { Intent intent = new Intent(this, MusicService.class); intent.putExtra("action",1); intent.putExtra("url", "http://10.10.60.18:8080/nobody.mp3"); } @Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ } return super.onTouchEvent(event); } }
service的使用:
package com.bluezhang.standerdcompuse.service; import android.content.Intent; import android.os.IBinder; import android.util.Log; import com.bluezhang.standerdcompuse.BuildConfig; import com.bluezhang.standerdcompuse.Constants; import java.util.LinkedList; import java.util.Queue; /** * 创建之后会自动在清单配置文件中创建Service的配置 * 配置隐式意图,intent_filter 隐式起动 Service * 数据加载服务 * 如果是启动服务和进程的生命周期是相同的 * 1、第一个生命周期是onCreat()(进行资源的初始化数据) * 所有的on开头的方法都是在主线程执行的 * 2、onStartCommend(intent,int flag,int id): * 第一个参数用于传递参数, * 这个方法在主线程执行,同时Intent需要多传递一些参数,不要只传递一个extra * Intent可以传递一些int类型的参数用于区分service内部的操作 */ public class DataFetchService extends android.app.Service implements Runnable { private Queue<String> urls; public DataFetchService() { if (BuildConfig.DEBUG) Log.d("DataFetchService", "构造"); } private Thread downloadThread; //控制县城时候继续运行 private boolean running; /** * @param intent * @return */ @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. if (BuildConfig.DEBUG) Log.d("DataFetchService", "onBind"); return null; } /** * 在对象的存活期间只会执行一次, * 用于初始化数据、对象 * 通常都是启动线程; */ @Override public void onCreate() { super.onCreate(); if (BuildConfig.DEBUG) Log.d("DataFetchService", "onCreat()"); urls = new LinkedList<>(); //启动线程 downloadThread = new Thread(this); downloadThread.start(); } @Override public void onDestroy() { super.onDestroy(); if (BuildConfig.DEBUG) Log.d("DataFetchService", "onDestory"); running = false; downloadThread.interrupt(); //urls 关闭 urls.clear(); urls = null; } /** * @param intent * @param flags * @param startId * @return int 返回int类型代表的是意外终止的情况下,服务应该怎么恢复 */ @Override public int onStartCommand(Intent intent, int flags, int startId) { //如果调用的是super,那么启动的服务就是粘性的,进程终止,服务重新启动 //但是 intent 为null //如果intent 不是空 if (BuildConfig.DEBUG) Log.d("DataFetchService", "onStartCommend " + flags); if (intent != null) { int action = intent.getIntExtra("action", -1); if (BuildConfig.DEBUG) Log.d("DataFetchService", "onStartCommend action = " + action); switch (action) { case 0: // 0 代表添加网址开始下载 processDownload(intent); break; case 1: //1 代表获取下载进度 getProgress(intent); break; case 2: //2 删除现在任务 removeDownloadRequest(intent); break; } } return super.onStartCommand(intent, flags, startId); } //--------------------------------------------- /** * 处理地址下载的操作 * * @param intent */ private void processDownload(Intent intent) { if (intent != null) { String url = intent.getStringExtra("url"); if (urls != null) { urls.offer(url); } } } //-------------------------------------------------- /** * 获取下载的进度 ,利用广播获取 * * @param intent */ private void getProgress(Intent intent) { //因为要获取进度,服务在没有绑定的情况下,要使用广播完成进度的更新 sendUpdateBroadcast(); } private void sendUpdateBroadcast() { Intent boardcast = new Intent(Constants.ACTION_PROGRESS_UPDATE); String[] strs = new String[urls.size()]; urls.toArray(strs); boardcast.putExtra("urls", strs); sendBroadcast(boardcast); } //-------------------------------- /** * 删除下载的任务 * * @param intent */ private void removeDownloadRequest(Intent intent) { if (!urls.isEmpty()) { //删除第一个 urls.poll(); } } @Override public void run() { running = true; try { while (running) { String url = urls.poll(); if (url != null) { //TODO 模拟网络下载 Thread.sleep(3000); sendUpdateBroadcast(); } Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } }
MusicService的使用:
package com.bluezhang.standerdcompuse.service; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.IBinder; import java.io.IOException; import java.util.Vector; public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener { //确保服务唯一性 private MediaPlayer player; //创建状态 public static final int STATE_CREATED = 0; //destoy 的状态 public static final int STATE_DESTORY = 1; //准备中的状态 private static final int STATE_PREPARING = 2; //播放中 private static final int STATE_START = 3; //暂停的状态 private static final int STATE_POUSE = 4; private static final int STATE_PLAYER_STOP =5 ; /** * 代表播放器的状态 */ private int playerState; /** * 是否继续下一首 * */ private boolean configAutoNext; /** * 播放列表 */ private Vector<String> playList; private int currentPosition = 0; public MusicService() {} @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw null; } @Override public void onCreate() { super.onCreate(); playList = new Vector<>(); player = new MediaPlayer(); //当准备完成的时候就会回掉 player.setOnPreparedListener(this); //播放结束的时候做的接口 player.setOnCompletionListener(this); playerState = STATE_CREATED; } @Override public void onDestroy() { super.onDestroy(); try { playerState = STATE_DESTORY; if (player.isPlaying()) { player.stop(); } player.release(); }catch (Exception e){ //因为player的操作可能出现状态的错误 } player = null; playList .clear(); playList = null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) { int action = intent.getIntExtra("action",-1); //http://10.10.60.18:8080/nobody.mp3 switch(action){ case 0://播放指定网址的声音 playMusic(intent); break; case 1: pauseMusic(intent); case 2: continueMusic(intent); break; case 3://重新设置播放列表0 设置播放列表,可以添加自动播放功能 break; } } return super.onStartCommand(intent, flags, startId); } private void pauseMusic(Intent intent) { try { if (playerState == STATE_START && player.isPlaying()) { player.pause(); playerState = STATE_POUSE; } }catch (Exception e){ e.printStackTrace(); } } private void continueMusic(Intent intent){ if (player.isPlaying() && playerState == STATE_POUSE){ player.start(); playerState = STATE_START; }else{ } } /** * 播放intent中的网址 * @param intent */ private void playMusic(Intent intent) { if (intent != null) { String url = intent.getStringExtra("url"); playMusic(url); } } private void playMusic(String url) { if (url != null) { resetPlayer(); try { player.setDataSource(url); player.prepareAsync(); playerState = STATE_PREPARING; } catch (IOException e) { e.printStackTrace(); } } } /** * 如果正在播放,那么停止,并且重置mediaplayer * 准备下次播放 */ private void resetPlayer(){ try { player.stop(); }catch(Exception e){ } player.reset(); } @Override public void onPrepared(MediaPlayer mp) { player.start(); playerState = STATE_START; } @Override public void onCompletion(MediaPlayer mp) { playerState = STATE_PLAYER_STOP; if(playList != null && configAutoNext){ int size = playList.size(); if(currentPosition +1 >= size){ //TODO 不再播放 }else{ //下一首 String url = playList.get(currentPosition + 1); playMusic(url); currentPosition++; } } } }
播放视频的部分:
package com.bluezhang.standerdcompuse; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.MotionEvent; import android.view.View; import android.widget.*; /** * videoView 怎么扩充全屏 视频的尺寸影响了Vise哦VIew的尺寸的计算; * VideoView中的onMeasure()方法,根据视频的尺寸进行了计算 ; * 3)MeasureSpec 一个参数包含两个信息 ,size 、mode * <p/> * 4)size 就是容器的最大的剩余空间VideoView就应该充满: */ public class PlayerActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, Runnable, SeekBar.OnSeekBarChangeListener { private VideoView videoView; private SeekBar seekBar; private Thread thread; private boolean running; private RelativeLayout relativeLayout; private LinearLayout linearLayout; private boolean isShowing = true; private android.os.Handler handler = new Handler() { @Override public void handleMessage(Message msg) { int what = msg.what; if (what == 998) { seekBar.setMax(msg.arg1); seekBar.setProgress(msg.arg2); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_player); relativeLayout = (RelativeLayout) findViewById(R.id.player_title_container); linearLayout = (LinearLayout) findViewById(R.id.player_down_container); button = (Button) findViewById(R.id.btn_stop); videoView = (VideoView) findViewById(R.id.vidio_view); seekBar = (SeekBar) findViewById(R.id.mc_seek_bar); seekBar.setOnSeekBarChangeListener(this); //本地 手机 网络 // videoView.setVideoURI(Uri.parse("http://10.10.60.18:8080/video_test.3gp")); videoView.setVideoURI(Uri.parse("http://10.10.60.18:8080/video_test.3gp")); videoView.setVideoPath("mnt/sdcard/Download/a.3gp"); videoView.setOnPreparedListener(this); thread = new Thread(this); thread.start(); //加上前进后退的控制器 //videoView.setMediaController(new MediaController(this)); } @Override protected void onDestroy() { super.onDestroy(); videoView.stopPlayback(); running = false; thread.interrupt(); } @Override public void onPrepared(MediaPlayer mp) { videoView.start(); } @Override public void run() { running = true; try { while (running) { if (videoView != null && videoView.isPlaying()) { int currentPosition = videoView.getCurrentPosition(); int duration = videoView.getDuration(); Message message = handler.obtainMessage(998); message.arg1 = duration; message.arg2 = currentPosition; handler.sendMessage(message); } Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { //使用seekBar进行拖拽处理 if (fromUser) { //用户处理才操作 videoView.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } GoneThread goneThread = new GoneThread(); @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (isShowing) { if(!goneThread.isAlive()) goneThread.start(); } else { relativeLayout.setVisibility(View.VISIBLE); linearLayout.setVisibility(View.VISIBLE); isShowing = !isShowing; } } return super.onTouchEvent(event); } private Handler myHandle = new Handler(); private Button button; public void btnStopMove(View view) { button.setBackgroundResource(android.R.drawable.ic_media_pause); try { if (videoView.isPlaying()) { videoView.pause(); } else { videoView.start(); } } catch (Exception e) { e.printStackTrace(); } } class GoneThread extends Thread { @Override public void run() { try { while (true) { Thread.sleep(3000); if(isShowing) { handler.post(new Runnable() { @Override public void run() { relativeLayout.setVisibility(View.GONE); linearLayout.setVisibility(View.GONE); isShowing = !isShowing; } }); } } } catch (InterruptedException e) { e.printStackTrace(); } } } }
自定义VideoView;
package com.bluezhang.standerdcompuse; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.MotionEvent; import android.view.View; import android.widget.*; /** * videoView 怎么扩充全屏 视频的尺寸影响了Vise哦VIew的尺寸的计算; * VideoView中的onMeasure()方法,根据视频的尺寸进行了计算 ; * 3)MeasureSpec 一个参数包含两个信息 ,size 、mode * <p/> * 4)size 就是容器的最大的剩余空间VideoView就应该充满: */ public class PlayerActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, Runnable, SeekBar.OnSeekBarChangeListener { private VideoView videoView; private SeekBar seekBar; private Thread thread; private boolean running; private RelativeLayout relativeLayout; private LinearLayout linearLayout; private boolean isShowing = true; private android.os.Handler handler = new Handler() { @Override public void handleMessage(Message msg) { int what = msg.what; if (what == 998) { seekBar.setMax(msg.arg1); seekBar.setProgress(msg.arg2); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_player); relativeLayout = (RelativeLayout) findViewById(R.id.player_title_container); linearLayout = (LinearLayout) findViewById(R.id.player_down_container); button = (Button) findViewById(R.id.btn_stop); videoView = (VideoView) findViewById(R.id.vidio_view); seekBar = (SeekBar) findViewById(R.id.mc_seek_bar); seekBar.setOnSeekBarChangeListener(this); //本地 手机 网络 // videoView.setVideoURI(Uri.parse("http://10.10.60.18:8080/video_test.3gp")); videoView.setVideoURI(Uri.parse("http://10.10.60.18:8080/video_test.3gp")); videoView.setVideoPath("mnt/sdcard/Download/a.3gp"); videoView.setOnPreparedListener(this); thread = new Thread(this); thread.start(); //加上前进后退的控制器 //videoView.setMediaController(new MediaController(this)); } @Override protected void onDestroy() { super.onDestroy(); videoView.stopPlayback(); running = false; thread.interrupt(); } @Override public void onPrepared(MediaPlayer mp) { videoView.start(); } @Override public void run() { running = true; try { while (running) { if (videoView != null && videoView.isPlaying()) { int currentPosition = videoView.getCurrentPosition(); int duration = videoView.getDuration(); Message message = handler.obtainMessage(998); message.arg1 = duration; message.arg2 = currentPosition; handler.sendMessage(message); } Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { //使用seekBar进行拖拽处理 if (fromUser) { //用户处理才操作 videoView.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } GoneThread goneThread = new GoneThread(); @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (isShowing) { if(!goneThread.isAlive()) goneThread.start(); } else { relativeLayout.setVisibility(View.VISIBLE); linearLayout.setVisibility(View.VISIBLE); isShowing = !isShowing; } } return super.onTouchEvent(event); } private Handler myHandle = new Handler(); private Button button; public void btnStopMove(View view) { button.setBackgroundResource(android.R.drawable.ic_media_pause); try { if (videoView.isPlaying()) { videoView.pause(); } else { videoView.start(); } } catch (Exception e) { e.printStackTrace(); } } class GoneThread extends Thread { @Override public void run() { try { while (true) { Thread.sleep(3000); if(isShowing) { handler.post(new Runnable() { @Override public void run() { relativeLayout.setVisibility(View.GONE); linearLayout.setVisibility(View.GONE); isShowing = !isShowing; } }); } } } catch (InterruptedException e) { e.printStackTrace(); } } } }
两个布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="btnPlayClick" android:text="播放" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="btnPauseMusic" android:text="暂停" /> <TextView android:id="@+id/progress_info" android:text="Hello World!" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:onClick="btnAddRequest" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="添加网址下载任务" /> <Button android:onClick="btnGetProgress" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="获取进度" /> <Button android:onClick="removeProgress" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="取消下载" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context="com.bluezhang.standerdcompuse.PlayerActivity"> <com.bluezhang.standerdcompuse.widgecs.FullVedioView android:id="@+id/vidio_view" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <RelativeLayout android:id="@+id/player_title_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#c999" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="back" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="share" /> </RelativeLayout> <LinearLayout android:id="@+id/player_down_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_gravity="bottom" android:background="#c666" android:gravity="center_vertical" > <Button android:layout_width="20dp" android:layout_height="20dp" android:background="@android:drawable/ic_media_previous" /> <Button android:id="@+id/btn_stop" android:layout_width="20dp" android:layout_height="20dp" android:onClick="btnStopMove" android:background="@android:drawable/ic_media_play" /> <Button android:layout_width="20dp" android:layout_height="20dp" android:background="@android:drawable/ic_media_next" /> <SeekBar android:id="@+id/mc_seek_bar" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="00:00" android:textColor="@android:color/white" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:text="/" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:text="15:00" /> </LinearLayout> </FrameLayout>
相关文章推荐
- linux 批量重命名文件
- linux下编译bib、tex生成pdf文件
- java21
- java20
- iOS RTMP 视频直播开发笔记(3)- 了解 H.264 编码
- Linux 函数库设计
- ACM2001Java实现两个点之间的距离
- js拼接字符串传值,子窗口传值
- iOS RTMP 视频直播开发笔记(2) – 了解 MP4 文件格式
- Java Swing 之Timer配合JProgressBar的使用
- android开机启动无界面后台程序
- django 微信企业号 返回text消息
- 如何在运行时更改虚拟机配置
- Java Swing 之Timer配合JProgressBar的使用
- jsonString 转字典
- 小随记
- django 微信企业号 返回text消息
- Light OJ 1033 - Generating Palindromes(区间DP)
- php form表单get传值
- 【剑指offer】C语言:实现函数可以将一个字符串转换为对应的整数,如+1234输出1234