2013-05-18 2 views
2

Je développe un jeu simple où 3 activités (menu, paramètres et liste de classement) ont besoin d'une musique de fond qui devrait jouer doucement en arrière-plan, même si par exemple l'utilisateur quitte menu et va dans les paramètres, puis de retour.Service avec MediaPlayer ne s'arrête pas lors de la fermeture de l'application - Android

Pour cela j'ai créé un service qui fonctionne parfaitement. Il n'y a qu'un problème majeur: lorsque l'application est fermée (l'utilisateur appuie sur le bouton d'accueil par exemple), la musique n'arrête pas de jouer.

J'ai essayé avec onDestroy, onStop, onPause mais le problème n'est pas résolu.

Service:

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

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

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

     } 

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

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

} 
+0

Dans le 'OnPause()', l'activité, appelez une méthode service pour lui dire d'arrêter de jouer. Semblable à votre 'OnDestroy()' dans votre service. – Doomsknight

+0

onPause est appelée chaque fois que je vais à une autre activité comme les paramètres. J'ai créé le service parce que je veux que la musique joue doucement sur plusieurs services. – Soriyyx

+0

Vous avez raison. Ajoutez-le à la touche du bouton d'accueil peut-être? Donc, lorsque la touche enfoncée, et est à la maison, arrêtez. – Doomsknight

Répondre

1

solutions faciles:

  1. Il suffit d'utiliser une activité! Utilisez Fragments pour chaque écran que vous affichez.

  2. Utilisez un compteur statique. Incrémentez le compteur lorsque vous appelez startActivity(). Décrémentez le compteur onPause() de toutes les activités. Lorsqu'une activité s'arrête et que votre compteur est 0, arrêtez la musique.

1

Démarrez votre service lorsque l'activité de menu reprend et arrêter quand l'arrêt de l'activité. Ainsi, l'activité de menu devrait ressembler à quelque chose comme ceci:

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

Si je fais que la musique s'arrête quand je vais à une autre activité comme les réglages. J'ai créé le service parce que je veux que la musique joue doucement sur plusieurs services. – Soriyyx

2

J'ai eu une exigence similaire, et voici comment je l'ai résolu:

  • Créer une classe qui implémente Application.ActivityLifecycleCallbacks, et votre registre d'application avec la méthode onCreate. Cette classe sera notifiée chaque fois qu'une activité est mise en pause ou reprise. Cette classe maintient un compte du nombre d'activités actives - commencez à 0, ajoutez-en une pour chaque activité reprise et soustrayez-en une pour chaque activité mise en pause. En pratique, votre compteur sera toujours égal à zéro ou un. Dans votre méthode onActivityPaused, après avoir décrémenté le compteur, vérifiez si le nombre est zéro. Notez qu'il existe une courte période entre la suspension d'une activité et la reprise de la suivante lorsque vous effectuez une transition entre les activités, au cours de laquelle le compte sera nul. Si, après avoir attendu un certain temps depuis l'onActivityPaused, votre compte est toujours à zéro, votre application a été complètement mise en arrière-plan et vous devez arrêter votre service.

1

Vous déclarez votre Intent en dehors de la fonction en classe activité et arrêter le service à l'intérieur de cette classe, appelez arrêter ou OnDestroy comme ceci:

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

Je pense que ce comportement est le plus logiquement abordé en créant votre propre classe d'application. Enregistrez-vous cette classe dans votre manifeste en utilisant:

<application 
    android:name="MyApplication" 

Laissez-la-ce quelque chose comme look classe 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

Voici ce que vous pouvez faire,

Créer une classe d'aide statique, ajoutez un La variable statique msActivityCount contient les deux méthodes suivantes.

increaseActivityCount() - incrémenter la valeur msActivityCount. Si msActivityCount == 1 démarrez le service. Appelez cette fonction du onStart() de chaque activité.

decreaseActivityCount() - décrémentez la valeur msActivityCount. Si msActivityCount == 0 arrête le service. Appelez cette fonction depuis onStop() de chaque activité.

Cela devrait résoudre votre problème sans aucun problème.

3

Essayez cela, il fonctionnera .Make une classe ActivityLifecycleCallback qui vérifiera si votre application est en arrière-plan ou running.On onActivityStopped appeler arrêter votre 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) { 

    } 

} 

enregistrer votre classe de rappel -

registerActivityLifecycleCallbacks(new MyLifecycleHandler()); 
Questions connexes