1.服务

当应用程序不再位于前台且没有正在使用它的活动的时候,为了确保音频继续播放,我们需要创建一个服务。服务是安卓应用程序的一个组件,其用于在后台运行任务,而无须与用户交互。

2. 本地服务与远程服务

安卓中存在几个可用的不同服务类。本地服务(Local Service):作为特定应用程序的一部分存在,而且只能通过该应用程序访问和控制。远程服务(Remote Service):是另一种类型的服务,它们可以与其他应用程序进行通信,由其他应用程序访问和控制。在此,仅介绍使用一个本地服务提供音频播放的功能。

3.本地服务

服务类需要继承android.app.Service类。该类是抽象类,所以为了扩展它,必须实现onBind方法。

public IBinder onBind(Intent intent)
{
// TODO Auto-generated method stub
return msBinder;//*
}
通常如果只是实现简单服务,并不实现“绑定”的话,可以选择return null。

还有三个表示服务生命周期的方法,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);
我们在服务类中创建了一个私有内部类,其继承自Binder类,在活动中请求连接服务时,用于返回服务本身

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();
}
}


更多相关文章

  1. 检查ArrayList是否只包含null值的方法。
  2. 不同Android版本设备正确获取屏幕分辨率的通用方法
  3. studio更新时候,不小心点了ignore,无法更新的解决方法
  4. android之发送短信的方法研究
  5. SQLite的Android光标在方法调用时崩溃
  6. android 2D 游戏的开发的方法
  7. 在Skobbler中完成导航时,确定“街边”的最佳方法是什么?
  8. 【Camera】Android平台Camera实时滤镜实现方法
  9. Fragment的setUserVisibleHint方法实现视频音频播放暂停

随机推荐

  1. android -- 多级目录创建
  2. Android(安卓)按键消息path
  3. 使用Android系统自带的icon图标
  4. android [1_ManagingProjects]
  5. Android requires compiler compliance l
  6. 快手Android
  7. Android 知识总结
  8. android 实现button的背景改变
  9. 史上最全selector和shape使用方法 Androi
  10. Android剪切图片