如何通过App在后台连续播放音乐?

Posted

技术标签:

【中文标题】如何通过App在后台连续播放音乐?【英文标题】:How to play music in the background through out the App continuously? 【发布时间】:2014-04-17 06:58:48 【问题描述】:

我的 android 应用程序中有 4 个活动。创建第一个活动时,它会在后台播放音乐。现在,当用户从第一个活动转到第二个活动时,我希望歌曲继续播放而不会中断。只有当用户离开应用程序时,歌曲才会停止。

现在音乐在我退出一项活动时停止,并在下一项活动中从头开始。

【问题讨论】:

我会使用本地绑定服务:developer.android.com/guide/components/services.html 那么你必须实现一个Service并从那里控制MediaPlayer实例 Android background music service的可能重复 @KenWolf 我认为您不应该使用 bindService。当您解除绑定时,它将被销毁。您可以更好地使用 startService(然后绑定到它)。 @RvdK 从技术上讲,它仍然是一个绑定服务,因为您绑定到它并调用公共方法。你只是没有通过绑定启动它。但我同意你的看法:) 【参考方案1】:

将播放器作为静态参考保持在后台。然后让它知道您是在应用程序内还是在应用程序外移动。这是我将如何做到的。为此,我使用了一个名为 DJ 的类。

public class DJ  
private static MediaPlayer player;
private static boolean keepMusicOn;

public static void iAmIn(Context context)
if (player == null)
player = MediaPlayer.create(context, R.raw.music1);
player.setLooping(true);

try
player.prepare();

catch (IllegalStateException e)
catch (IOException e)


if(!player.isPlaying())
player.start();


keepMusicOn= false;


public static void keepMusicOn()
keepMusicOn= true;


public static void iAmLeaving()

if(!keepMusicOn)
player.pause();



现在从你的活动中像这样给 DJ 打电话。(让他知道你是否想继续播放音乐)

public void onPause() 
super.onPause();
DJ.iAmLeaving();


public void onResume()
super.onResume();
DJ.iAmIn(this); 


public void buttonOnClick(View view)
DJ.keepMusicOn();
Intent intent = new Intent(this, TheOtherActivity.class);
startActivity(intent);

【讨论】:

【参考方案2】:

我是这样做的,我对结果很满意:

第一次创建服务:

public class LocalService extends Service

    // This is the object that receives interactions from clients. See RemoteService for a more complete example.
    private final IBinder mBinder = new LocalBinder();
    private MediaPlayer player;

    /**
     * Class for clients to access. Because we know this service always runs in
     * the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder
    
        LocalService getService()
        
            return LocalService.this;
        
    

    @Override
    public void onCreate()
    

    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    
        // We want this service to continue running until it is explicitly stopped, so return sticky.
        return START_STICKY;
    

    @Override
    public void onDestroy()
    
        destroy();
    

    @Override
    public IBinder onBind(Intent intent)
    
        return mBinder;
    


    public void play(int res)
    
        try
        
            player = MediaPlayer.create(this, res);
            player.setLooping(true);
            player.setVolume(0.1f, 0.1f);
            player.start();
        
        catch(Exception e)
        
            e.printStackTrace();
        
    


    public void pause()
    
        if(null != player && player.isPlaying())
        
            player.pause();
            player.seekTo(0);
        
    


    public void resume()
    
        try
        
            if(null != player && !player.isPlaying())
            
                player.start();
            
        
        catch(Exception e)
        
            e.printStackTrace();
        
    


    public void destroy()
    
        if(null != player)
        
            if(player.isPlaying())
            
                player.stop();
            

            player.release();
            player = null;
        
    


第 2 次​​strong>,创建一个基础活动,并在你希望从中播放背景音乐的女巫中扩展所有活动:

public class ActivityBase extends Activity

    private Context context = ActivityBase.this;
    private final int [] background_sound =  R.raw.azilum_2, R.raw.bg_sound_5 ;
    private LocalService mBoundService;
    private boolean mIsBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    
        super.onCreate(savedInstanceState);
        doBindService();
    

    @Override
    protected void onStart()
    
        super.onStart();

        try
        
            if(null != mBoundService)
            
                Random rand = new Random();
                int what = background_sound[rand.nextInt(background_sound.length)];
                mBoundService.play(what);
            
        
        catch(Exception e)
        
            e.printStackTrace();
        
    

    @Override
    protected void onStop()
    
        super.onStop();
        basePause();
    



    protected void baseResume()
    
        try
        
            if(null != mBoundService)
            
                mBoundService.resume();
            
        
        catch(Exception e)
        
            e.printStackTrace();
        
    


    protected void basePause()
    
        try
        
            if(null != mBoundService)
            
                mBoundService.pause();
            
        
        catch(Exception e)
        
            e.printStackTrace();
        
    



    private ServiceConnection mConnection = new ServiceConnection()
    
        public void onServiceConnected(ComponentName className, IBinder service)
        
            // This is called when the connection with the service has been
            // established, giving us the service object we can use to
            // interact with the service. Because we have bound to a explicit
            // service that we know is running in our own process, we can
            // cast its IBinder to a concrete class and directly access it.
            mBoundService = ((LocalService.LocalBinder) service).getService();

            if(null != mBoundService)
            
                Random rand = new Random();
                int what = background_sound[rand.nextInt(background_sound.length)];
                mBoundService.play(what);
            
        

        public void onServiceDisconnected(ComponentName className)
        
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            // Because it is running in our same process, we should never
            // see this happen.
            mBoundService = null;

            if(null != mBoundService)
            
                mBoundService.destroy();
            
        
    ;

    private void doBindService()
    
        // Establish a connection with the service. We use an explicit
        // class name because we want a specific service implementation that
        // we know will be running in our own process (and thus won't be
        // supporting component replacement by other applications).

        Intent i = new Intent(getApplicationContext(), LocalService.class);
        bindService(i, mConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
    

    private void doUnbindService()
    
        if (mIsBound)
        
            // Detach our existing connection.
            unbindService(mConnection);
            mIsBound = false;
        
    


    @Override
    protected void onDestroy()
    
        super.onDestroy();
        doUnbindService();
    

就是这样,现在您在从 ActivityBase 扩展的所有活动中都有背景声音了。

您甚至可以通过调用 basePause()/baseResume() 来控制暂停/恢复功能。

不要忘记在清单中声明服务:

<service android:name="com.gga.screaming.speech.LocalService" />

【讨论】:

【参考方案3】:

这个想法是您不应该播放活动本身的音乐。在 Android 上,活动和其他上下文具有生命周期。这意味着他们将活着……然后死去。而当他们死了,他们就不能再做任何事了。

因此,如果您想让音乐的寿命更长,就必须找到生命周期不止一个活动的东西。

最简单的解决方案是 Android 服务。你可以在这里找到一个好帖子:Android background music service

【讨论】:

以上是关于如何通过App在后台连续播放音乐?的主要内容,如果未能解决你的问题,请参考以下文章

iOS音乐后台播放锁屏封面及播放控制

iOS音乐后台播放锁屏封面及播放控制

微信小程序播放背景音乐

IOS后台运行 之 后台播放音乐

后台播放音乐

微信小程序音频播放之音乐播放器