android-音乐播放器实现及源码下载(一)

从本文开始,详细讲述一个音乐播放器的实现,以及从网络解析数据获取最新推荐歌曲以及歌曲下载的功能。
功能介绍如下:
1、获取本地歌曲列表,实现歌曲播放功能。
2、利用硬件加速感应器,摇动手机实现切换歌曲的功能
3、利用jsoup解析网页数据,从网络获取歌曲列表,同时实现歌曲和歌词下载到手机本地的功能。
4、通知栏提醒,实现仿QQ音乐播放器的通知栏功能.
涉及的技术有:
1、jsoup解析网络网页,从而获取需要的数据
2、android中访问网络,获取文件到本地的网络请求技术,以及下载文件到本地实现断点下载
3、线程池
4、图片缓存
5、service一直在后台运行
6、手机硬件加速器
7、notification通知栏设计
8、自定义广播
9、android系统文件管理
主要技术是这些,其中,利用jsoup解析网络网页,从而获取需要的数据,请参考我的博文: android中使用JSOUP如何解析网页数据详述

下面是最终结果展示:
这里写图片描述
图一 本地歌曲列表

这里写图片描述
图二 网络歌曲列表

这里写图片描述
图三 播放歌曲界面

这里写图片描述
图四 播放界面歌词显示部分

这里写图片描述
图五 通知栏展示 播放和下载时的展示

在本地歌曲列表界面长按菜单键可以显示菜单:
这里写图片描述
在网络歌曲列表中,点击歌曲,可以显示下载和取消菜单项:
这里写图片描述

基本的界面就是上面的图所展示的。大家觉得还可以的话,就给留个言~~_【握手】

下面就开始详细讲述实现细节。首先提一点,播放器中获取的网络歌曲部分,请参看我的博文:android中使用JSOUP如何解析网页数据详述
网络歌曲列表的获取就是利用jsoup从网页抓取数据进行展示的。关于这部分的东西,在本系列博文中不再详细说明了。

关于音乐播放器部分,需要使用到service服务,总共需要两个,一个是音乐播放的service,一个是歌曲下载的service,关于service一直在后台运行的问题,请参考我的博文:实现音乐播放器后台Service服务一直存在的解决思路

根据这篇博文的说明,很容易设计application类的实现,application类实现代码如下:

/**
 * 2015年8月15日 16:34:37
 * 博文地址:http://blog.csdn.net/u010156024
 */
public class App extends Application {
	public static Context sContext;
	public static int sScreenWidth;
	public static int sScreenHeight;
	
	@Override
	public void onCreate() {
		super.onCreate();
		sContext = getApplicationContext();
		
		startService(new Intent(this, PlayService.class));
		startService(new Intent(this, DownloadService.class));
		
		WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics dm = new DisplayMetrics();
		wm.getDefaultDisplay().getMetrics(dm);
		sScreenWidth = dm.widthPixels;
		sScreenHeight = dm.heightPixels;
	}
	
}

application类中启动了上面的两个service服务,同时获取了手机屏幕的宽和高。手机宽和高是为了后i面设计界面使用的。
有了application之后就可以设计Activity类,首先设计BaseActivity类,把复用的代码放在基类中,子类覆盖或重写BaseActivity中的方法,代码如下:

/**
 * 2015年8月15日 16:34:37
 * 博文地址:http://blog.csdn.net/u010156024
 */
public abstract class BaseActivity extends FragmentActivity {
	protected PlayService mPlayService;
	protected DownloadService mDownloadService;
	private final String TAG = BaseActivity.class.getSimpleName();
	
	private ServiceConnection mPlayServiceConnection = new ServiceConnection() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
			L.l(TAG, "play--->onServiceDisconnected");
			mPlayService = null;
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mPlayService = ((PlayService.PlayBinder) service).getService();
			mPlayService.setOnMusicEventListener(mMusicEventListener);
			onChange(mPlayService.getPlayingPosition());
		}
	};
	
	private ServiceConnection mDownloadServiceConnection = new ServiceConnection() {
		@Override
		public void onServiceDisconnected(ComponentName name) {
			L.l(TAG, "download--->onServiceDisconnected");
			mDownloadService = null;
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mDownloadService = ((DownloadService.DownloadBinder) service).getService();
		}
	};
	
	/**
	 * 音乐播放服务回调接口的实现类
	 */
	private PlayService.OnMusicEventListener mMusicEventListener = 
			new PlayService.OnMusicEventListener() {
		@Override
		public void onPublish(int progress) {
			BaseActivity.this.onPublish(progress);
		}

		@Override
		public void onChange(int position) {
			BaseActivity.this.onChange(position);
		}
	};
	
	/**
	 * Fragment的view加载完成后回调
	 * 
	 * 注意:
	 * allowBindService()使用绑定的方式启动歌曲播放的服务
	 * allowUnbindService()方法解除绑定
	 * 
	 * 在SplashActivity.java中使用startService()方法启动过该音乐播放服务了
	 * 那么大家需要注意的事,该服务不会因为调用allowUnbindService()方法解除绑定
	 * 而停止。
	 */
	public void allowBindService() {
		getApplicationContext().bindService(new Intent(this, PlayService.class),
				mPlayServiceConnection,
				Context.BIND_AUTO_CREATE);
	}
	
	/**
	 * fragment的view消失后回调
	 */
	public void allowUnbindService() {
		getApplicationContext().unbindService(mPlayServiceConnection);
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//绑定下载服务
		bindService(new Intent(this, DownloadService.class),
				mDownloadServiceConnection,
				Context.BIND_AUTO_CREATE);
	}

	@Override
	protected void onDestroy() {
		unbindService(mDownloadServiceConnection);
		super.onDestroy();
	}

	public DownloadService getDownloadService() {
		return mDownloadService;
	}
	
	/**
	 * 更新进度
	 * 抽象方法由子类实现
	 * 实现service与主界面通信
	 * @param progress 进度
	 */
	public abstract void onPublish(int progress);
	/**
	 * 切换歌曲
	 * 抽象方法由子类实现
	 * 实现service与主界面通信
	 * @param position 歌曲在list中的位置
	 */
	public abstract void onChange(int position);
}

下面给出启动界面,启动界面非常简单,延时2秒进入主界面,代码如下:

/**
 * 2015年8月15日 16:34:37
 * 博文地址:http://blog.csdn.net/u010156024
 */
public class SplashActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// no title
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		// 全屏
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.splash_layout);
		
		// 2s跳转到主界面
		new Handler().postDelayed(new Runnable() {
			@Override
			public void run() {
				startActivity(new Intent(SplashActivity.this, MainActivity.class));
				finish();
			}
		}, 2000);
	}
}

以上算是准备工作,有了上面的准备,可以设计主界面和主机面中的两个Fragment了。下面一篇博文讲述主界面的实现。

想要源代码的同学,给我发邮件吧(nyyin@qq.com)


PS:
代码已更新,本地手机没有MP3文件的话,也不会出现崩溃。

评论 212
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值