3

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

}
4

8 回答 8

3

Try this it will work .Make a ActivityLifecycleCallback class that will check if your application is in background or running.On onActivityStopped call stop your service.

    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) {

    }

}

register your callback class -

    registerActivityLifecycleCallbacks(new MyLifecycleHandler());
于 2013-06-01T02:52:14.847 回答
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));
    }
}
于 2013-05-30T01:51:45.220 回答
2

我有类似的要求,这是我解决它的方法:

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

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

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

于 2013-05-28T01:35:08.860 回答
2

这是你可以做的,

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

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

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

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

于 2013-05-31T20:54:56.797 回答
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));
        }
}
于 2013-05-18T20:12:33.340 回答
1

简单的解决方案:

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

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

于 2013-06-01T01:29:25.263 回答
1

不使用服务的背景音乐:

http://www.rbgrn.net/content/307-light-racer-20-days-61-64-completion

于 2013-06-01T11:21:11.920 回答
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();
 }
}
于 2013-05-29T03:05:30.193 回答