我的Android进阶之旅------>Android MediaPlayer播放网络音频的实例--网络mp3播放器

简介: 上一篇写了个简单的MP3播放器 ,这次写一个可以播放网络音频资源的播放器 本实例可以实现音乐播放器除了来电的时候会暂停播放,通话结束后恢复播放外,打开其他的Activity都可以继续播放音乐,享受一边听音乐一边做其他的事情。

上一篇写了个简单的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>
</manifest>
Step 5: 运行效果如下,一首动听的Avril Lavigne - Complicated.mp3在播放...



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

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

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

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


相关文章
|
4月前
|
Android开发
【Android App】蓝牙的设备配对、音频传输、点对点通信的讲解及实战(附源码和演示 超详细)
【Android App】蓝牙的设备配对、音频传输、点对点通信的讲解及实战(附源码和演示 超详细)
77 0
|
4月前
|
Java 关系型数据库 数据库
Android App连接真机步骤与APP的开发语言和工程结构讲解以及运行实例(超详细必看)
Android App连接真机步骤与APP的开发语言和工程结构讲解以及运行实例(超详细必看)
34 0
|
6月前
|
数据采集 JSON API
C#网络爬虫实例:使用RestSharp获取Reddit首页的JSON数据并解析
C#网络爬虫实例:使用RestSharp获取Reddit首页的JSON数据并解析
|
4月前
|
XML Java Android开发
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
72 0
|
4月前
|
XML 编解码 算法
Android开发音效中录制WAV音频和录制MP3音频的讲解及实战(超详细 附源码)
Android开发音效中录制WAV音频和录制MP3音频的讲解及实战(超详细 附源码)
61 0
|
21天前
|
机器学习/深度学习 PyTorch 算法框架/工具
卷积神经元网络中常用卷积核理解及基于Pytorch的实例应用(附完整代码)
卷积神经元网络中常用卷积核理解及基于Pytorch的实例应用(附完整代码)
18 0
|
2月前
|
弹性计算 大数据 测试技术
2024年阿里云服务器价格购买价格表(实例配置价格+磁盘价格+网络宽带价格)
2024年阿里云服务器价格购买价格表来了!2024年阿里云服务器租用费用,轻量应用服务器和云服务器ECS优惠价格表,云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年,轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核4G服务器30元3个月,幻兽帕鲁4核16G和8核32G服务器配置,云服务器ECS可以选择经济型e实例、通用算力u1实例、ECS计算型c7、通用型g7、c8i、g8i等企业级实例规格。今天分享阿里云服务器租用费用最新报价:
60 2
|
3月前
|
Shell Android开发 数据安全/隐私保护
安卓逆向 -- Frida环境搭建(HOOK实例)
安卓逆向 -- Frida环境搭建(HOOK实例)
35 0
|
4月前
|
网络协议 网络虚拟化 网络架构
网络之路25:VLAN进阶实验-Super VLAN
网络之路25:VLAN进阶实验-Super VLAN
35 0
|
4月前
|
XML Java Android开发
Android 开发中原始音频的录播和和自定义音频控制条的讲解及实战(超详细 附源码)
Android 开发中原始音频的录播和和自定义音频控制条的讲解及实战(超详细 附源码)
27 0