绑定服务后台播放音频的简单示例
1.服务
当应用程序不再位于前台且没有正在使用它的活动的时候,为了确保音频继续播放,我们需要创建一个服务。服务是安卓应用程序的一个组件,其用于在后台运行任务,而无须与用户交互。
2. 本地服务与远程服务
安卓中存在几个可用的不同服务类。本地服务(Local Service):作为特定应用程序的一部分存在,而且只能通过该应用程序访问和控制。远程服务(Remote Service):是另一种类型的服务,它们可以与其他应用程序进行通信,由其他应用程序访问和控制。在此,仅介绍使用一个本地服务提供音频播放的功能。
3.本地服务
服务类需要继承android.app.Service类。该类是抽象类,所以为了扩展它,必须实现onBind方法。
-
public IBinder onBind(Intent intent)
-
{
-
// TODO Auto-generated method stub
-
return msBinder;//*
-
}
还有三个表示服务生命周期的方法,onCreate和onDestroy就不用说了,重点说说onStartCommand。每当利用一个匹配服务的意图调用startService时,就会调用onStartCommand方法,因此可能会多次调用它。onStartCommand方法将返回一个整数值,其表示如果结束该服务,那么操作系统应该如何执行操作。可以使用START_STICKY表明如果结束服务,那么将重新启动该服务。
-
public int onStartCommand(Intent intent, int flags, int startId)
-
{
-
// TODO Auto-generated method stub
-
Log.v(TAG,"onStartCommand");
-
if(!mediaPlayer.isPlaying())
-
{
-
mediaPlayer.start();
-
}
-
return START_STICKY;
-
//return super.onStartCommand(intent, flags, startId);
-
}
插一句:从android2.0中引入了onStartCommand方法,在此之前使用的是onStart方法。onStart方法的参数是一个意图和一个表示startId的整数。它不包括int类型的flags参数,而且没有返回值。如果目标电话在2.0之前运行,那么需要使用onStart方法。
注意,别忘了在清单文件中加入一个条目指定该服务。
下一步,我们还希望能够通过活动来控制服务中的MediaPlayer,而发出命令则显得更为复杂。为了控制MediaPlayer,需要利用bindService方法把该活动与服务绑定在一起(解绑定则使用unbindService)。一旦这样做了,由于活动与服务在相同的进程中运行,因此可以直接调用服务中的方法。如果正在创建一个远程服务,那么必须采取更深入一步的步骤。
-
//启动音乐服务
-
playMusicServiceIntent=new Intent(this,MusicService.class);
-
startService(playMusicServiceIntent);
-
//serviceConnection是一个ServiceConnection类型的对象,它是一个接口,用于监控所绑定服务的状态
-
serviceConnection=new ServiceConnection()
-
{
-
-
@Override
-
public void onServiceDisconnected(ComponentName name)
-
{
-
// TODO Auto-generated method stub
-
musicService=null;
-
}
-
//注意该方法传入了一个IBinder对象,其实际上是由服务本身创建并提交的
-
@Override
-
public void onServiceConnected(ComponentName name, IBinder service)
-
{
-
// TODO Auto-generated method stub
-
musicService=((MusicService.MusicServiceBinder)service).getService();
-
}
-
};
-
-
//绑定服务时,需要传入intent和serviceConnection
-
bindService(playMusicServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
-
public class MusicServiceBinder extends Binder//*
-
{
-
MusicService getService()
-
{
-
return MusicService.this;
-
}
-
}
现在就搭好了基础,可以向服务中添加任何喜欢的功能,同时通过绑定服务,可以直接调用服务中定义的各种方法。如果不绑定服务的话,那么除了启动和停止服务之外,我们将不能做任何其他的事情。
完整代码示例:
活动中的代码:
-
//启动音乐服务
-
playMusicServiceIntent=new Intent(this,MusicService.class);
-
startService(playMusicServiceIntent);
-
-
serviceConnection=new ServiceConnection()
-
{
-
-
@Override
-
public void onServiceDisconnected(ComponentName name)
-
{
-
// TODO Auto-generated method stub
-
musicService=null;
-
}
-
-
@Override
-
public void onServiceConnected(ComponentName name, IBinder service)
-
{
-
// TODO Auto-generated method stub
-
musicService=((MusicService.MusicServiceBinder)service).getService();
-
}
-
};
-
-
//绑定服务
-
bindService(playMusicServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
-
//控制音乐服务的按钮
-
Musicbtn=(Button) findViewById(R.id.musicOn);
-
Musicbtn.setBackgroundResource(R.drawable.musicon);
-
Musicbtn.setOnClickListener(new OnClickListener()
-
{
-
-
@Override
-
public void onClick(View v)
-
{
-
// TODO Auto-generated method stub
-
if(musicService.IsPlayNow())
-
{
-
Musicbtn.setBackgroundResource(R.drawable.musicoff);
-
musicService.PauseMusic();
-
}
-
else
-
{
-
Musicbtn.setBackgroundResource(R.drawable.musicon);
-
musicService.ResumeMusic();
-
}
-
-
}
-
-
});
-
public class MusicService extends Service implements OnCompletionListener
-
{
-
static final String TAG="PLAYERSERVICE";
-
MediaPlayer mediaPlayer;
-
private final IBinder msBinder=new MusicServiceBinder();//*
-
-
public class MusicServiceBinder extends Binder//*
-
{
-
MusicService getService()
-
{
-
return MusicService.this;
-
}
-
}
-
@Override
-
public void onCreate()
-
{
-
// TODO Auto-generated method stub
-
//super.onCreate();
-
Log.v(TAG,"onCreate");
-
mediaPlayer=MediaPlayer.create(this,R.raw.music);
-
mediaPlayer.setOnCompletionListener(this);
-
}
-
-
@Override
-
public void onDestroy()
-
{
-
// TODO Auto-generated method stub
-
if(mediaPlayer.isPlaying())
-
{
-
mediaPlayer.stop();
-
}
-
mediaPlayer.release();
-
Log.v(TAG,"onDestroy");
-
//super.onDestroy();
-
}
-
-
@Override
-
public int onStartCommand(Intent intent, int flags, int startId)
-
{
-
// TODO Auto-generated method stub
-
Log.v(TAG,"onStartCommand");
-
if(!mediaPlayer.isPlaying())
-
{
-
mediaPlayer.start();
-
}
-
return START_STICKY;
-
//return super.onStartCommand(intent, flags, startId);
-
}
-
-
@Override
-
public IBinder onBind(Intent intent)
-
{
-
// TODO Auto-generated method stub
-
return msBinder;//*
-
}
-
-
@Override
-
public void onCompletion(MediaPlayer mediaPlayer)
-
{
-
// TODO Auto-generated method stub
-
//stopSelf();
-
mediaPlayer.start();
-
}
-
-
public void PauseMusic()
-
{
-
if(mediaPlayer.isPlaying())
-
{
-
mediaPlayer.pause();
-
}
-
}
-
-
public void ResumeMusic()
-
{
-
if(!mediaPlayer.isPlaying())
-
{
-
mediaPlayer.start();
-
}
-
}
-
-
public boolean IsPlayNow()
-
{
-
return mediaPlayer.isPlaying();
-
}
-
}
文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。
原文链接:panda1234lee.blog.csdn.net/article/details/8763294
- 点赞
- 收藏
- 关注作者
评论(0)