我需要在所有活动中都有背景音乐。它应该在应用程序不是前台时停止。在我为2.3开发时,我无法使用ActivityLifeCycleCallBacks类。我在Checking if an Android application is running in the background实施了解决方案,然后决定让媒体播放器成为单身人士并在服务中使用它。
一切正常,如果我按回家,请从菜单中选择退出,或者让应用程序以声音停止的任何方式运行背景,但...... 经过一些随机时间后,我正在做其他事情或者即使屏幕关闭,音乐也会重新开始。即使我从任务管理器中删除了应用程序,也会在稍后再次启动。
这是我的第一次单身人士,也是我第一次玩服务,所以我想我错过了一些非常基本的东西。我想我已经关闭了服务,但显然我不是。 这是代码:
PlayAudio.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);
}
}
}
答案 0 :(得分: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();
}
希望它有所帮助!! 您可以根据此主题检查my answer是否可以解决您的问题。
答案 1 :(得分: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()被调用并且音乐开始播放。
答案 2 :(得分: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);