MasterofProject

[Android] music player of the service service design

2612 people read comment(4) Collection report
Classification:

Learning Android have more than a month, after reading the first line of code, as well as the Mars teacher's first video through the music player small project to deepen the understanding of the point of view of knowledge. From the beginning of this paper, the detailed introduction of a simple imitation of more than a meter music player to achieve, as well as network analysis of data access to Baidu music, the latest music and download.

        Function is described as follows:    

        1, get a list of local songs, songs play function.
2, the use of jsoup analysis of Web data, from the network to obtain a list of songs, while the realization of songs and lyrics downloaded to the local mobile phone functions.
3, the notification bar to remind, to achieve the QQ music player notification bar function.
     

       Involved in the technology:
1, jsoup analysis of web pages, so as to obtain the required data
2, Android access to the network, access to the file to the local network technology, as well as to download the file to the local implementation of the breakpoint Download
3, thread pool
4, image cache
5, service has been running in the background
6, Activity and Fragment between the switch and communication
7, notification notification bar design
8, custom broadcast
9, Android system file tube

       Music player ideas and source download:[Android] the design idea of music player

This article mainly talks about all aspects of music player service design. The main use of the two service services: one for the playback of music PlayService; another for the download of the song DownLoadService. Using the service of the two ways: startservice () start mode and bindservice () start mode (want to deeply understand the two start mode can refer to the blog post:Deep understanding of startservice's Android and bindservice).

We can use the startservice () start service in the application class, startservice () way to start will not destroy the service with the content, unless the call stopservice () to stop service. The benefit of doing so is to improve the service priority so that the service can be run in the background. According to the above description is very easy to implement application class:

Class App extends Application{public
Static Context sContext public;
Static int sScreenWidth public;
Static int sScreenHeight public;
	
@Override
Void onCreate public () {
Super.onCreate ();
SContext = getApplicationContext ();
		
StartService (Intent new (this, PlayService.class));
StartService (Intent new (this, DownloadService.class));
		
WM = (WindowManager) getSystemService (Context.WINDOW_SERVICE) WindowManager ();
DM DisplayMetrics = DisplayMetrics new ();
Wm.getDefaultDisplay ().GetMetrics (DM);
SScreenWidth = dm.widthPixels;
SScreenHeight = dm.heightPixels;
}
}

Start classes in the application class with two service services: Playservice and DownloadService. Code than the larger, small series here is not one by one analysis! General about ~), forgive me forgive me!!! First look at the PlayService after the start of the initial work:

Void onCreate public () {
Super.onCreate ();

MusicUtils.initMusicList ();
MPlayingPosition = (Integer) SpUtils.get (this, Constants.PLAY_POS, 0);
MPlayer = MediaPlayer new ();
MPlayer.setOnCompletionListener (this);
		
/ / to update the progress of threads
MProgressUpdatedListener.execute (mPublishProgressRunnable);
		
If (MusicUtils.sMusicList.size () = 0)
{
StartNotification ();
ReadyNotification = true;
}
}
Code at a glance, the completion of the main work is as follows:

(1) calling the MusicUtil class InitMusic () method to read the.Mp3 file and the sdcard file from the specified location to the.Lrc, and load the data into the ArrayList array to populate the local music list.

(2) to create a MediaPlayer and set the listener.

(3) call startNotification () to initialize the notification bar, and in theStartNotification () method of registering the server to listen to the notification bar of the click event.

(4) through the callback interface to achieve the Service and Activity interface song playback progress, and a series of updates.

First posted on the notice board to compare the important point of the code bar, PlayService display with the function of the text after bingService () will be further analyzed:

Void startNotification private () {
/ * *
* the method is obsolete, but it is a common method!
* /
PendingIntent PendingIntent = PendingIntent
.getActivity (PlayService.this,
0, Intent new (PlayService.this, PlayActivity.class), 0 ();
RemoteViews = RemoteViews new (getPackageName),
R.layout.play_notification);
Notification = Notification new (R.drawable.icon,
"The song is playing," System.currentTimeMillis ();
Notification.contentIntent = pendingIntent;
Notification.contentView = remoteViews;
/ / mark bit, the notification bar has been set
=Notification.FLAG_ONGOING_EVENT notification.flags;
		
Intent Intent = Intent new (PlayService.class.getSimpleName ());
Intent.putExtra ("BUTTON_NOTI", 1);
PreIntent PendingIntent = PendingIntent.getBroadcast (
PlayService.this,
1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews.setOnClickPendingIntent (
R.id.music_play_pre, preIntent);
		
Intent.putExtra ("BUTTON_NOTI", 2);
PauseIntent PendingIntent = PendingIntent.getBroadcast (
PlayService.this,
2, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews.setOnClickPendingIntent (
R.id.music_play_pause, pauseIntent);
		
Intent.putExtra ("BUTTON_NOTI", 3);
NextIntent PendingIntent = PendingIntent.getBroadcast
(PlayService.this,
3, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews.setOnClickPendingIntent (
R.id.music_play_next, nextIntent);
		
Intent.putExtra ("BUTTON_NOTI", 4);
Exit PendingIntent = PendingIntent.getBroadcast (PlayService.this,
4, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews.setOnClickPendingIntent (
R.id.music_play_notifi_exit, exit);
		
NotificationManager = (NotificationManager)
GetSystemService (NOTIFICATION_SERVICE);
SetRemoteViews ();
		
/ * *
* registered broadcast receiver
* function:
* listen to the notification bar button click event
* /
Filter IntentFilter = IntentFilter new (
PlayService.class.getSimpleName ());
Receiver MyBroadCastReceiver = MyBroadCastReceiver new ();
RegisterReceiver (receiver, filter);
}
Void setRemoteViews public () {
L.l (TAG, "entry -" setRemoteViews ());
RemoteViews.setTextViewText (R.id.music_name,
MusicUtils.sMusicList.get (
GetPlayingPosition ()).GetTitle () ();
RemoteViews.setTextViewText (R.id.music_author,
MusicUtils.sMusicList.get (
GetPlayingPosition ()).GetArtist () ();
Icon Bitmap =.Load () MusicIconLoader.getInstance ()
MusicUtils.sMusicList.get (
GetPlayingPosition ()).GetImage () ();
RemoteViews.setImageViewBitmap (R.id.music_icon, icon = null
ImageTools.scaleBitmap (R.drawable.icon)
ImageTools
.scaleBitmap (icon);
If (isPlaying ()) {
RemoteViews.setImageViewResource (R.id.music_play_pause,
R.drawable.btn_notification_player_stop_normal);
}else {
RemoteViews.setImageViewResource (R.id.music_play_pause,
R.drawable.btn_notification_player_play_normal);
}
/ / update notification bar
NotificationManager.notify (5, notification);
}

Class MyBroadCastReceiver extends BroadcastReceiver{private
@Override
Void onReceive public (context Context, intent Intent) {
If (intent.getAction ().Equals () ()
{PlayService.class.getSimpleName ()) {
L.l (TAG, "MyBroadCastReceiver class -" onReceive ());
L.l (TAG, "button_noti-->"
+intent.getIntExtra ("BUTTON_NOTI", 0);
Switch (intent.getIntExtra ("BUTTON_NOTI", 0)) {
1: case
(pre);
Break;
2: case
If (isPlaying ()) {
(pause); / / pause
{else} {
(resume); / / play
}
Break;
3: case
Next ();
Break;
4: case
If (isPlaying ()) {
Pause ();
}
/ / cancel notification bar
(5)取消NotificationManager;
打破;
违约:
打破;
}
}
如果(mlistener!=空){
mlistener onchange(getplayingposition());
}
}
}
为了读者思路的连贯性(~!~一方面也因为下载服务初始化确实你们没做啥工作…),我就继续将playservice的bindservice()方式也一并分析了再说下载服务吧,见谅见谅!!!!~·~!

本地列表localfragment在创建时调用了onstart()方法调用的活动中的bindservice()方法实现绑定服务,同理在销毁的时候调用onstop()方法调用活动中的unbindservice()方法销毁服务,这种启动方式会随着内容的销毁而销毁服务:

“重写”
onstart() { public void
onstart()超;
mactivity。allowbindservice();
}
	
“重写”
onstop() { public void
onstop()超;
mactivity。allowunbindservice();
}
* * * *
*片段的观加载完成后回调
*
allowbindservice() { public void
bindService(新的意图(这playservice。类),mplayserviceconnection,
背景bind_auto_create);
}
私人serviceconnection mplayserviceconnection =新serviceconnection() {

“重写”
public void onServiceConnected(componentname arg0,IBinder服务){
/ /待办事项自动生成方法存根
mplayservice =((playservice。playbinder)服务getservice());
mplayservice setonmusiceventlistener(mmusiceventlistener);
onchange(mplayservice。getplayingposition());
}

“重写”
公共无效onservicedisconnected(componentname arg0){
mplayservice = null;
			
}
		
};
同理,在playactivity也是通过这种方式实现绑定服务,在localfragment以及playactivity中通过各自界面的监听事件调用服务中的想过方法实现音乐的播放、暂停、下一首、上一首以及通过回调函数实现播放进度的更新等一系列功能,部分代码代码如下:

* * * *
*播放
* @param位置音乐列表的位置
* @返回当前播放的位置
*
public int玩(国际地位){
如果(位置< 0)位置= 0;
如果(位置> = musicutils。smusiclist。size())位置= musicutils。smusiclist size() - 1;
		
尝试{
reset() MPlayer;
			
MPlayer。设置数据来源(musicutils。smusiclist。得到(位置)。geturi());
prepare() MPlayer;
			
start();
如果(mlistener!= null)mlistener onchange(位置);
(例外情况){
E. printstacktrace();
}
		
mplayingposition =位置;
sputils放(constants.play_pos,mplayingposition);
如果(!readynotification){
startnotification();
{ }
setremoteviews();
}
返回mplayingposition;
}

start() { private void
start() MPlayer;
}
	
* * * *
*是否正在播放
* @返回
*
公共布尔isplaying() {
返回Mplayer!= null && isplaying() MPlayer;
}
	
* * * *
*继续播放
* @返回当前播放的位置默认为0
*
公共resume() { int
如果(isplaying()){
返回- 1;
} else if(mplayingposition <= 0 | | mplayingposition > = musicutils。smusiclist。size()){
mplayingposition = 0;
玩(mplayingposition);
setremoteviews();
返回mplayingposition;
{ }
start() MPlayer;
setremoteviews();
返回mplayingposition;
}
}
	
* * * *
*暂停播放
* @返回当前播放的位置
*
public int(){
如果(!isplaying())返回1;
MPlayer的。();
setremoteviews();
返回mplayingposition;
}
	
* * * *
*下一曲
* @返回当前播放的位置
*
公共next() { int
如果(mplayingposition > = musicutils。smusiclist。size() - 1){
返回游戏(0);
}
setremoteviews();
回放(mplayingposition + 1);
}
	
* * * *
*上一曲
* @返回当前播放的位置
*
公共pre() { int
如果(mplayingposition <= 0){
回放(musicutils。smusiclist。size() - 1);
}
setremoteviews();
回放(mplayingposition - 1);
}
马上来看下代码分析下载服务:

公开课的下载服务延伸服务{
私人sparsearray <下载> mdownloads =新sparsearray <下载>();
私人remoteviews mremoteviews;
	
公共课downloadbinder延伸粘结剂{
公共的下载服务getservice() {
返回downloadservice.this;
}
}
	
“重写”
公共IBinder onBind(意向书){
返回新的downloadbinder();
}
	
“重写”
oncreate() { public void
oncreate()超;
}
	
公共无效下载(final int ID字符串的URL,最后,最终的字符串名称){
1.1(“下载”,URL);
下载a下载新的(ID的URL,musicutils。getmusicdir() +姓名);
d.setondownloadlistener(mdownloadlistener)开始(假);
mdownloads放(ID,D);
}
	
refreshremoteview() { private void
“suppresswarnings(“贬低”)
通知通知=新通知(
android.r.drawable.stat_sys_download,”,
currenttimemillis())系统;
mremoteviews =新remoteviews(getpackagename(),
r.layout download_remote_layout);
notification.contentview = mremoteviews;
	    
StringBuilder建造新的stringbuilder();
为(int i = 0,大小为mdownloads。size();我<大小;i++){
建设者。追加(mdownloads。得到(mdownloads。keyat(我))
getlocalfilename());
建造者(“,”);
}
		
mremoteviews settextviewtext(r.id.tv_download_name,
建设者。substring(0,建设者。字符串(“、”)));
	    
startforeground(r.drawable.icon,通知);
}
	
ondownloadcomplete private void(int downloadid){
mdownloads删除(downloadid);
如果(mdownloads。size() = = 0){
stopforeground(真的);
返回;
}
		
refreshremoteview();
}
	
* * * *
*发送广播,通知系统扫描指定的文件
*
scansdcard() { private void
		
如果(build.version.sdk_int > =建造。version_codes。奇巧){
/ /判断SDK版本是不是4.4或者高于4.4
[ [ ] [ ] [ ] [ ] [ ] [ [ ] [ ] [ ] [ ] [ ]
环境。getexternalstoragedirectory() tostring() };
mediascannerconnection。扫描文件(这个路径,null,null);
{ }
意图意图=新的意图(intent。action_media_mounted);
意图。setclassname(“COM。Android。供应商。媒体”,
“COM。Android。供应商。媒体。mediascannerreceiver”);
意图。SetData(URI。解析(“文件:/ /”+ musicutils。getmusicdir()));
sendBroadcast(意图);
}
}
	
私人download.ondownloadlistener mdownloadlistener =
新的下载。ondownloadlistener() {
		
“重写”
public void(int会在downloadid){
1.1(“下载”、“成功”);
maketext(downloadservice.this干杯,
mdownloads。得到(downloadid)。getlocalfilename() +“下载完成”,
烤面包。length_short show());
ondownloadcomplete(downloadid);
scansdcard();
}
		
“重写”
public void onStart(int downloadid,长文件大小){
1.1(“下载”、“开始”);
refreshremoteview();
烤面包。maketext(downloadservice.this,“开始下载”+
mdownloads。得到getlocalfilename()(downloadid),
烤面包。length_short show());
}
		
“重写”
公共无效onpublish(int downloadid,长径){
/ / 1.1(“下载”、“发布”+大小);
}
		
“重写”
public void onPause(int downloadid){
1.1(“下载”、“暂停”);
}
		
“重写”
公共无效ongoon(int downloadid,长localsize){
1.1(“下载”、“打手”);
}
		
“重写”
public void OnError(int downloadid){
1.1(“下载”、“错误”);
maketext(downloadservice.this干杯,
mdownloads。得到(downloadid)。getlocalfilename() +“下载失败”,
烤面包。length_short show());
ondownloadcomplete(downloadid);
}
		
“重写”
public void OnCancel(int downloadid){
1.1(“下载”、“取消”);
ondownloadcomplete(downloadid);
}
};
}
相信你看完playservice代码后一定觉得下载服务相当的简单,主要结合下载类实现真正的下载音乐的功能,以及通过回掉接口传递数据更新的功能就不多做分析了~·~ UI!!!。

另外,小编想说移植用模拟器也没有观察锁屏后服务服务是否会停止,不过,即使服务被销毁姐姐办法也是很简单很简单:只要在启动服务的时候获取电源琐,在服务被注销的时候释放电源琐就应该可以,感兴趣的亲可以试试~!~。哈哈哈








猜你在找
查看评论
* the above user comments only represent their personal views, does not represent the views or position of the CSDN website