上一篇写了个简单的MP3播放器 ,这次写一个可以播放网络音频资源的播放器

本实例可以实现音乐播放器除了来电的时候会暂停播放,通话结束后恢复播放外,打开其他的Activity都可以继续播放音乐,享受一边听音乐一边做其他的事情。该播放器可以实现进度条的显示,拖动进度条,可以调节播放进度。

Step 1 :新建一个Android工程,命名为AudioNetPlayer

Step 2: 设计UI布局,在main.xml里放入4个ImageButton,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_height="fill_parent" android:layout_width="fill_parent"><LinearLayout android:layout_height="wrap_content"android:layout_width="fill_parent" android:orientation="vertical"android:layout_gravity="top"><TextView android:layout_width="wrap_content"android:layout_height="40dp" android:text="@string/file_name"android:id="@+id/tips" /><EditText android:layout_width="fill_parent"android:layout_height="wrap_content" android:id="@+id/file_name"android:text="http://192.168.153.50:8080/Hello/Complicated.mp3" /><LinearLayout android:orientation="horizontal"android:layout_gravity="center_horizontal" android:layout_marginTop="4.0dip"android:layout_height="wrap_content" android:layout_width="wrap_content"><Button android:layout_width="80dip"android:layout_height="wrap_content" android:id="@+id/btnPlayUrl"android:text="@string/button_play"></Button><Button android:layout_height="wrap_content" android:id="@+id/btnPause"android:text="@string/button_pause" android:layout_width="80dip"></Button><Button android:layout_height="wrap_content"android:layout_width="80dip" android:text="@string/button_stop"android:id="@+id/btnStop"></Button><Button android:layout_height="wrap_content"android:layout_width="80dip" android:text="@string/button_replay"android:id="@+id/btnReplay"></Button></LinearLayout><LinearLayout android:orientation="horizontal"android:layout_width="fill_parent" android:layout_height="wrap_content"android:layout_marginBottom="20dip"><SeekBar android:paddingRight="10dip" android:layout_gravity="center_vertical"android:paddingLeft="10dip" android:layout_weight="1.0"android:layout_height="wrap_content" android:layout_width="wrap_content"android:id="@+id/skbProgress" android:max="100"></SeekBar></LinearLayout></LinearLayout>
</FrameLayout> 

Step 3 :主控制程序MainActivity.java的实现,代码如下:

package cn.roco.netaudio.player;import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.TextView;public class MainActivity extends Activity {private Button btnPause, btnPlayUrl, btnStop,btnReplay;private SeekBar skbProgress;private Player player;private EditText file_name_text;private TextView tipsView;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);this.setTitle("在线音乐播放---ouyangpeng编写");  btnPlayUrl = (Button) this.findViewById(R.id.btnPlayUrl);  btnPlayUrl.setOnClickListener(new ClickEvent());  btnPause = (Button) this.findViewById(R.id.btnPause);  btnPause.setOnClickListener(new ClickEvent());  btnStop = (Button) this.findViewById(R.id.btnStop);  btnStop.setOnClickListener(new ClickEvent());  btnReplay = (Button) this.findViewById(R.id.btnReplay);  btnReplay.setOnClickListener(new ClickEvent());  file_name_text=(EditText) this.findViewById(R.id.file_name);tipsView=(TextView) this.findViewById(R.id.tips);skbProgress = (SeekBar) this.findViewById(R.id.skbProgress);  skbProgress.setOnSeekBarChangeListener(new SeekBarChangeEvent());  String url=file_name_text.getText().toString();player = new Player(url,skbProgress);  TelephonyManager telephonyManager=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);telephonyManager.listen(new MyPhoneListener(), PhoneStateListener.LISTEN_CALL_STATE);}/*** 只有电话来了之后才暂停音乐的播放*/private final class MyPhoneListener extends android.telephony.PhoneStateListener{@Overridepublic void onCallStateChanged(int state, String incomingNumber) {switch (state) {case TelephonyManager.CALL_STATE_RINGING://电话来了player.callIsComing();break;case TelephonyManager.CALL_STATE_IDLE: //通话结束player.callIsDown();break;}}}class ClickEvent implements OnClickListener {  @Override  public void onClick(View arg0) {  if (arg0 == btnPause) {  boolean pause=player.pause();  if (pause) {btnPause.setText("继续");tipsView.setText("音乐暂停播放...");  }else{btnPause.setText("暂停");tipsView.setText("音乐继续播放...");  }} else if (arg0 == btnPlayUrl) {  player.play();tipsView.setText("音乐开始播放...");} else if (arg0 == btnStop) {  player.stop();  tipsView.setText("音乐停止播放...");  } else if (arg0==btnReplay) {player.replay();tipsView.setText("音乐重新播放...");  }}  }  class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {  int progress;  @Override  public void onProgressChanged(SeekBar seekBar, int progress,  boolean fromUser) {  // 原本是(progress/seekBar.getMax())*player.mediaPlayer.getDuration()  this.progress = progress * player.mediaPlayer.getDuration()  / seekBar.getMax();  }  @Override  public void onStartTrackingTouch(SeekBar seekBar) {  }  @Override  public void onStopTrackingTouch(SeekBar seekBar) {  // seekTo()的参数是相对与影片时间的数字,而不是与seekBar.getMax()相对的数字  player.mediaPlayer.seekTo(progress);  }  }  }

播放器实现功能如下:

package cn.roco.netaudio.player;import java.util.Timer;
import java.util.TimerTask;import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.SeekBar;public class Player implements OnBufferingUpdateListener, OnCompletionListener,MediaPlayer.OnPreparedListener {public MediaPlayer mediaPlayer;private SeekBar skbProgress;private Timer mTimer = new Timer();private String videoUrl;private boolean pause;private int playPosition;public Player(String videoUrl, SeekBar skbProgress) {this.skbProgress = skbProgress;this.videoUrl = videoUrl;try {mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setOnBufferingUpdateListener(this);mediaPlayer.setOnPreparedListener(this);} catch (Exception e) {Log.e("mediaPlayer", "error", e);}mTimer.schedule(mTimerTask, 0, 1000);}/******************************************************** 通过定时器和Handler来更新进度条******************************************************/TimerTask mTimerTask = new TimerTask() {@Overridepublic void run() {if (mediaPlayer == null)return;if (mediaPlayer.isPlaying() && skbProgress.isPressed() == false) {handleProgress.sendEmptyMessage(0);}}};Handler handleProgress = new Handler() {public void handleMessage(Message msg) {int position = mediaPlayer.getCurrentPosition();int duration = mediaPlayer.getDuration();if (duration > 0) {long pos = skbProgress.getMax() * position / duration;skbProgress.setProgress((int) pos);}};};/*** 来电话了*/public void callIsComing() {if (mediaPlayer.isPlaying()) {playPosition = mediaPlayer.getCurrentPosition();// 获得当前播放位置mediaPlayer.stop();}}/*** 通话结束*/public void callIsDown() {if (playPosition > 0) {playNet(playPosition);playPosition = 0;}}/*** 播放*/public void play() {playNet(0);}/*** 重播*/public void replay() {if (mediaPlayer.isPlaying()) {mediaPlayer.seekTo(0);// 从开始位置开始播放音乐} else {playNet(0);}}/*** 暂停*/public boolean pause() {if (mediaPlayer.isPlaying()) {// 如果正在播放mediaPlayer.pause();// 暂停pause = true;} else {if (pause) {// 如果处于暂停状态mediaPlayer.start();// 继续播放pause = false;}}return pause;}/*** 停止*/public void stop() {if (mediaPlayer != null && mediaPlayer.isPlaying()) {mediaPlayer.stop();}}@Override/**  * 通过onPrepared播放  */public void onPrepared(MediaPlayer arg0) {arg0.start();Log.e("mediaPlayer", "onPrepared");}@Overridepublic void onCompletion(MediaPlayer arg0) {Log.e("mediaPlayer", "onCompletion");}@Overridepublic void onBufferingUpdate(MediaPlayer arg0, int bufferingProgress) {skbProgress.setSecondaryProgress(bufferingProgress);int currentProgress = skbProgress.getMax()* mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration();Log.e(currentProgress + "% play", bufferingProgress + "% buffer");}/*** 播放音乐* * @param playPosition*/private void playNet(int playPosition) {try {mediaPlayer.reset();// 把各项参数恢复到初始状态/*** 通过MediaPlayer.setDataSource()* 的方法,将URL或文件路径以字符串的方式传入.使用setDataSource ()方法时,要注意以下三点:* 1.构建完成的MediaPlayer 必须实现Null 对像的检查.* 2.必须实现接收IllegalArgumentException 与IOException* 等异常,在很多情况下,你所用的文件当下并不存在. 3.若使用URL 来播放在线媒体文件,该文件应该要能支持pragressive* 下载.*/mediaPlayer.setDataSource(videoUrl);mediaPlayer.prepare();// 进行缓冲mediaPlayer.setOnPreparedListener(new MyPreparedListener(playPosition));} catch (Exception e) {e.printStackTrace();}}private final class MyPreparedListener implementsandroid.media.MediaPlayer.OnPreparedListener {private int playPosition;public MyPreparedListener(int playPosition) {this.playPosition = playPosition;}@Overridepublic void onPrepared(MediaPlayer mp) {mediaPlayer.start();// 开始播放if (playPosition > 0) {mediaPlayer.seekTo(playPosition);}}}}

Step 4:由于加入了监听电话的功能,所以要在AndroidManifest.xml中配置权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="cn.roco.netaudio.player" android:versionCode="1"android:versionName="1.0"><uses-sdk android:minSdkVersion="8" /><uses-permission android:name="android.permission.INTERNET" /><!-- 注意:这里要加入一个监听电话的权限 --><uses-permission android:name="android.permission.READ_PHONE_STATE"/><application android:icon="@drawable/icon" android:label="@string/app_name"><activity android:name="MainActivity" android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest>

Step 5: 运行效果如下,一首动听的Avril Lavigne - Complicated.mp3在播放...

==================================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

==================================================================================================


转载于:https://www.cnblogs.com/ouyangpeng/archive/2013/04/09/8538413.html

我的Android进阶之旅------Android MediaPlayer播放网络音频的实例--网络mp3播放器相关推荐

  1. 我的Android进阶之旅------Android MediaPlayer播放mp3的实例--简易mp3播放器

    大家好我们今天研究的是Android中很重要也最为复杂的媒体播放器---MediaPlayer. Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上 ...

  2. 我的Android进阶之旅------Android利用Sensor(传感器)实现水平仪功能的小例

    这里介绍的水平仪,指的是比较传统的气泡水平仪,在一个透明圆盘内充满液体,液体中留有一个气泡,当一端翘起时,该气泡就会浮向翘起的一端.    利用方向传感器返回的第一个参数,实现了一个指南针小应用.   ...

  3. 我的Android进阶之旅------Android利用温度传感器实现带动画效果的电子温度计

    要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...

  4. android服务进阶,我的Android进阶之旅------Android服务的生命周期回调方法

    先引用一段官网上的文字 ======================================================================================== ...

  5. 我的Android进阶之旅------Android自定义View来实现解析lrc歌词并同步滚动、上下拖动、缩放歌词的功能...

    前言 一LRC歌词文件简介 1什么是LRC歌词文件 2LRC歌词文件的格式 LRC歌词文件的标签类型 1标识标签 2时间标签 二解析LRC歌词 1读取出歌词文件 2解析得到的歌词内容 1表示每行歌词内 ...

  6. 我的Android进阶之旅------Android二级ListView列表的实现

    实现如下图所示的二级列表效果 首先是在布局文件中,布局两个ListView,代码如下: <LinearLayout xmlns:android="http://schemas.andr ...

  7. 我的Android进阶之旅------Android嵌入图像InsetDrawable的用法

    面试题:为一个充满整个屏幕的LinearLayout布局指定背景图,是否可以让背景图不充满屏幕?请用代码描述实现过程. 解决此题,可以使用嵌入(Inset)图像资源来指定图像,然后像使用普通图像资源一 ...

  8. 我的Android进阶之旅------Android项目目录结构分析

    此文章来自"博客园"博主,仅在此借鉴,学习 1.HelloWorld项目的目录结构 1.1.src文件夹 1.2.gen文件夹 1.3.Android 2.1文件夹 1.4.ass ...

  9. 我的Android进阶之旅------android Matrix图片随意的放大缩小,拖动(转)

    step1:新建一个项目DragAndZoom,并准备一张照片放在res/drawable-hdpi目录下,如下图所示: step2: 设置应用的UI界面,在main.xml中设置: [html] v ...

最新文章

  1. sourcetree管理git
  2. Linux那些事儿之我是Sysfs(1)sysfs初探
  3. 页面GBK,用jquery.post乱码问题
  4. python爬虫教程下载-Python爬虫文件下载图文教程
  5. JS不同类型之间运算与转换
  6. 怎样判断ios app 第一次启动
  7. linux cna12.dll,攻击 MySQL 服务器传播 GandCrab 勒索软件
  8. 北京玉渊潭开启春节模式 五大版块吸引游客
  9. Python使用matplotlib可视化环形图
  10. RootKit检测工具
  11. 计算机的ps快捷键,PHOTOSHOP常用快捷键大全
  12. whose size is larger than the fetch size
  13. getchar 使用
  14. Image Enhancement
  15. python求一个数所有因数
  16. 00后php团队,00后学霸团队自制视频脱口秀走红:不想做网红
  17. 已解决,软件V2报错 failed to read response header > websocket: close 1005 (no status)问题
  18. java+selenium自动化抓取51la数据
  19. C#反射的实现原理及简单应用
  20. 3D Slicer中文教程

热门文章

  1. awk文本工具按列计算和
  2. [Array]217.Contains Duplicate
  3. Spring对JNDI的支持方法
  4. 在Linux下编译安装Apache2(2)
  5. 设计模式---读书笔记
  6. shell命令总结3
  7. Flink的scala+python的shell模式实验记录汇总
  8. git commit时避免填写Commit Message
  9. hive中的数据库与mysql中的hive数据库的关系
  10. Ubuntu16.04下面spyder切换虚拟环境下面的python版本