我的Android进阶之旅------>Android MediaPlayer播放网络音频的实例--网络mp3播放器
2023-09-27 14:29:34 时间
上一篇写了个简单的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. */ @Override public 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{ @Override public 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() { @Override public 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"); @Override public void onCompletion(MediaPlayer arg0) { Log.e("mediaPlayer", "onCompletion"); @Override public 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 implements android.media.MediaPlayer.OnPreparedListener { private int playPosition; public MyPreparedListener(int playPosition) { this.playPosition = playPosition; @Override public 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 /manifestStep 5: 运行效果如下,一首动听的Avril Lavigne - Complicated.mp3在播放...
![](http://img.my.csdn.net/uploads/201304/09/1365503057_8383.jpg)
Android音频架构 我们上面介绍的四个层面的音频API实现均在Framework层,其他各层音频相关有哪些功能?当我们调用某一API时最终是怎么驱动硬件工作的呢?下面我们先看看系统各层音频相关模块及功能。
Android音频API MediaRecorder与MediaPlayer并不能算完整意义的音频API,它们只是系统音频API的封装,除了采集/播放,他们集成了编码/解码、复用/解复用等能力。它们在最底层还是调用了AudioRecorder、AudioTrack。下面主要介绍它们的几个主要的配置项。
字节卷动 You will never know how excellent you are unless you impel yourself once.
相关文章
- Android 监听wifi广播的两种方式
- 2021大厂Android面试经验,成功入职腾讯
- android屏幕适配原理,2021年Android面经分享,吐血整理
- 我的Android进阶之旅------>Android中android:windowSoftInputMode的使用方法
- Ubuntu 16.04下为Android编译OpenCV 3.2.0 Manager
- Android NDK调试出错Unknown Application ABI, Unable to detect application ABI's的解决方式
- [Android开发学习] day07 & day08
- Android Retrofit2&OkHttp3添加统一的请求头Header
- Android 5.0+ 自定义普通按钮的ripple波纹效果
- android一些小技巧
- Centos系统下部署Android打包生成APK
- 我的Android进阶之旅------>解决错误: java.util.regex.PatternSyntaxException: Incorrect Unicode property
- 我的Android进阶之旅------>android如何将List<NameValuePair>请求参数列表转换为json格式
- 我的Android进阶之旅------>android:drawableLeft的用法
- 我的Android进阶之旅------>Ubuntu下不能识别Android设备的解决方法
- 我的Android进阶之旅------>Android KeyCode列表
- 我的Android进阶之旅------>Android自定义窗口标题实例
- Android系统移植与调试之------->如何修改开机动画的两种方式剖析
- 我的Android进阶之旅------>Android Gusture 手势识别小案例