1

我的所有活动都需要有背景音乐。当应用程序不是前台时,它应该停止。当我为 2.3 开发时,我不能使用 ActivityLifeCycleCallBacks 类。我在检查 Android 应用程序是否在后台运行时实现了解决方案,然后决定将媒体播放器设为单例并在服务中使用它。

一切正常,如果我按主页,从菜单中选择退出,或者我让应用程序以任何声音停止的方式进入后台,但是......在我做其他事情时随机时间之后,甚至当屏幕关闭时音乐将重新开始。即使我从任务管理器中终止应用程序,稍后也会再次启动。

这是我的第一个单身人士,也是我第一次玩服务,所以我想我错过了一些非常基本的东西。我想我正在关闭服务,但显然我没有。这是代码:

播放音频.java

import ...
public class PlayAudio extends Service{
    private static final Intent Intent = null;
    MediaPlayer objPlayer;
    private int length = 0;
    boolean mIsPlayerRelease = true;
    private static PlayAudio uniqueIstance; //the singleton
    static PlayAudio mService;
    static boolean mBound = false; // boolean to check if the service containing this singleton is binded to some activity
    public static boolean activityVisible; // boolean to check if the activity using the player is foreground or not

//My attempt to make a singleton
public static PlayAudio getUniqueIstance(){
    if (uniqueIstance == null) {
        uniqueIstance = new PlayAudio();
    }
    return uniqueIstance;
}
public static boolean isActivityVisible() {
    return activityVisible;
  }  

  public static void activityResumed() {
    activityVisible = true;
  }

  public static void activityPaused() {
    activityVisible = false;
  }
static public ServiceConnection mConnection = new ServiceConnection() {// helper for the activity

    public void onServiceConnected(ComponentName className,
            IBinder service) {
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};
public static Intent createIntent (Context context) { //helper for the activity using the player
    Intent intent = new Intent(context, PlayAudio.class);
    return intent;
}
private final IBinder mBinder = new LocalBinder();

public class LocalBinder extends Binder {
    PlayAudio getService() {
        // Return this instance so clients can call public methods
        return PlayAudio.this;
    }
}
@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}
public void onCreate(){
    super.onCreate();
    Log.d(LOGCAT, "Service Started!");
    objPlayer = MediaPlayer.create(this,R.raw.kickstarterreduced);
    objPlayer.setLooping(true);
    mIsPlayerRelease = false;
}

public int onStartCommand(Intent intent, int flags, int startId){
    objPlayer.start();
    Log.d(LOGCAT, "Media Player started!");
    if(objPlayer.isLooping() != true){
        Log.d(LOGCAT, "Problem in Playing Audio");
    }
    return 1;
}

public void onStop(){
    objPlayer.setLooping(false);
    objPlayer.stop();
    objPlayer.release();
    mIsPlayerRelease = true;
}

public void onPause(){
    if(objPlayer.isPlaying())
    {
        objPlayer.pause();
        length=objPlayer.getCurrentPosition(); // save the position in order to be able to resume from here
    }   
}
public void resumeMusic() // if length is 0 the player just start from zero
{   if (mIsPlayerRelease == true) {
    objPlayer = MediaPlayer.create(this,R.raw.kickstarterreduced);
    mIsPlayerRelease = false;
}
    if(objPlayer.isPlaying()==false )
    {
        if (length != 0) objPlayer.seekTo(length);
        objPlayer.start();
    }
}

}

这是我在每个活动的类中实现的方法

SharedPreferences sharedPrefs;
PlayAudio playerIstanced;
public static boolean activityVisible;
@Override
public void onStart() {
    super.onStart();
    sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); 
   }
@Override
public void onResume() {
       super.onResume();
       playerIstanced= PlayAudio.getUniqueIstance(); //call singleton
       bindService(PlayAudio.createIntent(this), playerIstanced.mConnection, Context.BIND_AUTO_CREATE); // create the service
       if (sharedPrefs.getBoolean("sound", true) == true) {// if sound is enabled in option it will start the service
           startService(PlayAudio.createIntent(this));
           playerIstanced.mService.activityResumed();
           if (playerIstanced.mBound == true) {
           playerIstanced.mService.resumeMusic();
           }
       }

   }
   @Override
   public void onPause() {
       super.onPause();
       playerIstanced.mService.activityPaused();
       final Handler handler = new Handler();
       handler.postDelayed(new Runnable() {
         public void run() {
           //If the phone lags when changing activity (between onPause() and the other activity onResume() the music won't stop. If after 500ms onResume() is not called it means the activity went background...Am I messing with service here?
             if (playerIstanced.mService.isActivityVisible() != true) {
                 playerIstanced.mService.onPause();
             }
         }
       }, 500);

}
   @Override
   public void onStop(){
       super.onStop();
       // Unbind from the service
       if (playerIstanced.mService.mBound) {
           playerIstanced.mService.mBound = false;
           unbindService(playerIstanced.mService.mConnection);

       }
   }



}
4

3 回答 3

2

用户退出应用时自动停止音乐

这部分必须在每个活动的 onPause 中:

public void onPause(){
    super.onPause();
        Context context = getApplicationContext();
                ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
                List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
                if (!taskInfo.isEmpty()) {
                  ComponentName topActivity = taskInfo.get(0).topActivity; 
                  if (!topActivity.getPackageName().equals(context.getPackageName())) {
                   StopPlayer();
                    Toast.makeText(xYourClassNamex.this, "YOU LEFT YOUR APP. MUSIC STOP", Toast.LENGTH_SHORT).show();
                  }
                }
      }

这部分必须在每个活动的 onResume 中:

用户恢复应用时自动播放音乐

Public void onResume()
    {
       super.onResume();
     StartPlayer();
    }

希望能帮助到你!!您可以根据此主题查看我的答案,它可能会解决您的问题。

于 2013-09-07T04:21:59.653 回答
2

您需要使用 Context.stopService() 或 stopSelf() 手动停止服务。请参阅http://developer.android.com/reference/android/app/Service.html的服务生命周期部分。

服务生命周期

系统可以运行服务有两个原因。如果有人调用 Context.startService() ,那么系统将检索服务(创建它并在需要时调用其 onCreate() 方法),然后使用客户端提供的参数调用其 onStartCommand(Intent, int, int) 方法。此时服务将继续运行,直到调用 Context.stopService() 或 stopSelf()。请注意,对 Context.startService() 的多次调用不会嵌套(尽管它们确实会导致对 onStartCommand() 的多次相应调用),因此无论启动多少次服务都将停止一次 Context.stopService() 或 stopSelf () 叫做; 但是,服务可以使用它们的 stopSelf(int) 方法来确保在处理启动的意图之前不会停止服务。

我相信您可以简单地将 playerIstanced.stopSelf() 放入每个活动的 onStop() 调用中。

我的理解是,在您的应用程序停止后,该服务会继续安静地运行。一段时间后,系统会终止服务以释放资源,然后再过一段时间,当资源可用时,它会重新启动服务。当服务重新启动时,它的 onResume() 被调用并且音乐开始播放。

于 2013-09-07T04:50:37.223 回答
0

它帮助我停止了媒体播放器。使用 Handler(getMainLooper()) 来启动和停止 MediaPlayer。

final Handler handler = new Handler(getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
   mediaPlayer.start();
}
});

handler.postDelayed(new Runnable() {
@Override
public void run() {
if (mediaPlayer.isPlaying()) {
     mediaPlayer.stop();
}
}
, 30 * 1000);
于 2019-01-24T22:55:31.030 回答