关闭应用程序时,MediaPlayer的服务不会停止 - Android

时间:2013-05-18 20:05:09

标签: android android-music-player

我正在开发一个简单的游戏,其中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();
        }

}

8 个答案:

答案 0 :(得分:3)

我认为通过创建自己的应用程序类来解决这种行为。使用以下命令在清单中注册此类:

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

答案 1 :(得分:3)

试试这个它会起作用。制作一个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());

答案 2 :(得分:2)

我有类似的要求,这就是我如何解决它:

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

  • 让此类保持活动活动数的计数 - 从0开始,为每个恢复的活动添加一个,并为每个暂停的活动减去一个。在实践中,您的计数器将始终为零或一。

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

答案 3 :(得分:2)

这是你可以做的,

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

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

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

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

答案 4 :(得分:1)

菜单活动恢复时启动服务,并在活动停止时停止服务。所以Menu活动看起来像这样:

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

答案 5 :(得分:1)

你在活动类的函数外面声明你的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();
 }
}

答案 6 :(得分:1)

简易解决方案:

  1. 只需使用一项活动!对要显示的每个屏幕使用片段。

  2. 使用静态计数器。调用startActivity()时递增计数器。减少所有活动的计数器onPause()。当某项活动暂停,您的计数器为0时,请停止播放音乐。

答案 7 :(得分:1)