【问题标题】:Service with MediaPlayer doesn't stop when closing app - Android关闭应用程序时使用 MediaPlayer 的服务不会停止 - Android
【发布时间】:2013-05-13 18:26:35
【问题描述】:

我正在开发一个简单的游戏,其中 3 个活动(菜单、设置和排名列表)需要一个背景音乐,即使用户离开菜单并进入设置然后返回也应该在后台流畅播放。

为此,我创建了完美运行的服务。只有一个主要问题:当应用程序关闭时(例如用户按下主页按钮),音乐不会停止播放。

我尝试过 onDestroy、onStop、onPause 但问题没有解决。

服务:

package com.android.migame;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;

public class Meni_music extends Service implements OnCompletionListener {

    private static final String TAG = null;
    MediaPlayer player;

    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        player = MediaPlayer.create(this, R.raw.menu);
        player.setLooping(true); // Set looping
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        player.start();
        return 1;
    }

    public IBinder onUnBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onDestroy() {
        player.stop();
        player.release();
        stopSelf();
    }

    @Override
    public void onLowMemory() {
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
    }
}

菜单:

package com.android.migame;

    import android.app.Activity;
    import android.app.ActivityManager;

    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.ImageView;

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;

    public class Meni extends Activity {

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            setContentView(R.layout.meni);

            startService(new Intent(Meni.this,Meni_music.class));

        }

        @Override
        protected void onPause() {
            super.onPause();
        }

        @Override
        protected void onResume() {
            super.onResume();
        }

}

【问题讨论】:

  • onPause(),在activity中,调用service中的一个方法告诉它停止播放。类似于您服务中的OnDestroy()
  • onPause 每次我去另一个活动(如设置)时都会被调用。我创建服务是因为我希望音乐在多个服务中流畅播放。
  • 你说得对。将它添加到主页按钮可能吗?因此,当按下键并且在家时,停止。
  • 我不认为你可以玩弄主页按钮。 stackoverflow.com/questions/4783960/…
  • onDestroy(){ stopService(new Intent(Meni.this,Meni_music.class)) }

标签: android android-music-player


【解决方案1】:

我认为通过创建您自己的应用程序类可以最合乎逻辑地解决这种行为。使用以下方法在清单中注册此类:

<application
    android:name="MyApplication"

MyApplication 类看起来像这样:

public class MyApplication extends Application
    implements ActivityLifecycleCallbacks, Runnable
{
    private Handler h;

    @Override public void onCreate()
    {
        h = new Handler();
        registerActivityLifecycleCallbacks(this);
    }

    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { }
    public void onActivityStarted(Activity activity) { }
    public void onActivityStopped(Activity activity) { }
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) { }
    public void onActivityDestroyed(Activity activity) { }

    public void onActivityResumed(Activity activity)
    {
        h.removeCallbacks(this);
        startService(new Intent(this, Meni_music.class));
    }

    public void onActivityPaused(Activity activity);
    {
        h.postDelayed(this, 500);
    }

    public void run()
    {
        stopService(new Intent(this, Meni_music.class));
    }
}

【讨论】:

    【解决方案2】:

    试试这个,它会起作用。创建一个 ActivityLifecycleCallback 类来检查你的应用程序是在后台还是在运行。在 onActivityStopped 调用时停止你的服务。

        public class MyLifecycleHandler implements ActivityLifecycleCallbacks {
        private int resumed;
        private int paused;
    
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        }
    
        public void onActivityDestroyed(Activity activity) {
        }
    
        public void onActivityResumed(Activity activity) {
            ++resumed;
        }
    
        public void onActivityPaused(Activity activity) {
            ++paused
            if(resumed == paused)
            stopService(new Intent(this, Meni_music.class));
        }
    
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        }
    
        public void onActivityStarted(Activity activity) {
        }
    
        public void onActivityStopped(Activity activity) {
    
        }
    
    }
    

    注册你的回调类 -

        registerActivityLifecycleCallbacks(new MyLifecycleHandler());
    

    【讨论】:

      【解决方案3】:

      我也有类似的需求,我是这样解决的:

      • 创建一个实现Application.ActivityLifecycleCallbacks 的类,并让您的应用程序在其onCreate 方法中使用registerActivityLifecycleCallbacks 注册它。每次活动暂停或恢复时都会通知此类。

      • 让此类维护活动活动的计数 - 从 0 开始,为每个恢复的活动加一,为每个暂停的活动减一。实际上,您的计数器将始终为零或一。

      • 在您的onActivityPaused 方法中,递减计数器后,检查计数是否为零。请注意,当您在活动之间转换时,一个活动被暂停和下一个活动恢复之间有很短的时间,在此期间计数将为零。如果从 onActivityPaused 等待一段合理的时间后,您的计数仍然为零,那么您的应用程序已完全进入后台,您应该停止服务。

      【讨论】:

        【解决方案4】:

        这是你可以做的,

        创建一个静态帮助类,在其中添加一个静态变量msActivityCount,并在其中添加以下2个方法。

        increaseActivityCount() - 增加msActivityCount 值。如果msActivityCount == 1 启动服务。从每个活动的onStart() 调用此函数。

        decreaseActivityCount() - 减少msActivityCount 的值。如果msActivityCount == 0 停止服务。从每个活动的onStop() 调用此函数。

        这应该可以毫无问题地解决您的问题。

        【讨论】:

          【解决方案5】:

          简单的解决方案:

          1. 只需使用一项活动!为您正在显示的每个屏幕使用片段。

          2. 使用静态计数器。调用 startActivity() 时增加计数器。减少所有活动的计数器 onPause()。当一个活动暂停并且你的计数器为 0 时,停止音乐。

          【讨论】:

            【解决方案6】:

            在菜单活动恢复时启动您的服务,并在活动停止时停止它。所以菜单活动应该是这样的:

            package com.android.migame;
            
                import android.app.Activity;
                import android.app.ActivityManager;
            
                import android.content.Context;
                import android.content.Intent;
                import android.os.Bundle;
                import android.util.Log;
                import android.view.View;
                import android.view.Window;
                import android.view.WindowManager;
                import android.widget.ImageView;
            
                import java.io.BufferedReader;
                import java.io.File;
                import java.io.FileReader;
            
                public class Meni extends Activity {
            
                    @Override
                    public void onCreate(Bundle savedInstanceState) {
                        super.onCreate(savedInstanceState);
            
                        requestWindowFeature(Window.FEATURE_NO_TITLE);
                        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                        setContentView(R.layout.meni);
                    }
            
                    @Override
                    protected void onPause() {
                        super.onPause();
                        stopService(new Intent(Meni.this,Meni_music.class));
                    }
            
                    @Override
                    protected void onResume() {
                        super.onResume();
                        startService(new Intent(Meni.this,Meni_music.class));
                    }
            }
            

            【讨论】:

            • 如果我这样做,当我进入另一个活动(如设置)时,音乐将停止。我创建服务是因为我希望音乐能够在多个服务中流畅播放。
            【解决方案7】:

            您在活动类的函数外部声明您的Intent 并在该类内部停止服务,调用 stop 或 ondestroy 像这样:

             public class Meni extends Activity {
                 private Intent i=new Intent();
            
              @Override
              protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             requestWindowFeature(Window.FEATURE_NO_TITLE);
                 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                 WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                 setContentView(R.layout.meni);
                 i=new Intent(Meni.this,Meni_music.class);
                 startService(i);
             }
            
              @Override
              protected void onDestroy() {
                stopService(i);
                super.onDestroy();
            }
            
             @Override
             protected void onStop() {
            stopService(i);
            super.onStop();
             }
            }
            

            【讨论】:

              【解决方案8】:

              【讨论】:

                猜你喜欢
                • 2013-05-15
                • 1970-01-01
                • 1970-01-01
                • 2015-06-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多