zoukankan      html  css  js  c++  java
  • 绑定服务后台播放音频的简单示例

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


  • 相关阅读:
    2016华中农业大学预赛 E 想法题
    2016华中农业大学预赛 B 数学
    render()
    钩子函数
    redirect_uri域名与后台配置不一致,错误码:10003
    群发次数
    表名
    intval()函数
    render()
    $this->autoRender = false
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3002648.html
Copyright © 2011-2022 走看看