2013-09-07 3 views
1

내 모든 활동에서 배경 음악이 필요합니다. 응용 프로그램이 포 그라운드가 아닌 경우 중지되어야합니다. 2.3 용으로 개발할 때 ActivityLifeCycleCallBacks 클래스를 사용할 수 없습니다. Checking if an Android application is running in the background에서 솔루션을 구현 한 다음 미디어 플 레이어를 싱글 톤으로 만들어 서비스에 사용하기로 결정했습니다.Android mediaplayer 싱글 톤 서비스가 중지되지 않습니다.

모든 것이 잘 작동하고 집에서 누르면 메뉴에서 종료를 선택하거나 응용 프로그램이 소리가 멈추는 어떤 방식 으로든 돌아가도록합니다 ... 임의의 시간이 지나면 내가 다른 것을 할 때 또는 심지어 때 화면이 꺼지면 음악이 파란색에서 다시 시작됩니다. 작업 관리자에서 응용 프로그램을 종료해도 나중에 다시 시작됩니다.

이것은 내 첫 싱글턴이며 처음으로 서비스를 즐기기 때문에 나는 정말 기본적인 것을 놓치고 있다고 생각합니다. 나는 내가 서비스를 닫고있다라고 생각한다. 그러나 명백하게 나는 그렇지 않다. 여기 코드입니다 :

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

     } 
    } 



} 

답변

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을 확인하면 문제가 될 수 있습니다.

+0

해 주셔서 감사합니다. 여전히 코드가하는 일을 제대로 이해할 수는 없지만 제대로 작동합니다. StopPlayer() 대신에 작업을 일시 중지하고 onStop()을 호출 할 때만 중지하기로했습니다. 몇 번이라도 한 라인 씩 솔루션을 설명하겠습니까? 나는 약간의 인터넷 검색을 시도했다. 그러나 나는 아직도 길을 잃는다. – pinolo

+0

@ pinolo, 여기는 front activity를 찾고 있습니다. 내 앱 화면이 전면에 있지 않으면 내 앱에서 사용자가 퇴장했음을 의미합니다. 나는 이것을 ActivityManager에서 얻을 수있다. 실행 작업 목록을 줄 것이다. 나는'taskInfo.get (0) .topActivity'에서 앞쪽 Activity를 얻을 수있다. 그럼 난 그냥 내 애플 리케이션의 활동과 비교. 일치하지 않는 경우 응용 프로그램이 닫힙니다. 당신이 그것을 얻을 희망! –

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()이 호출되고 음악이 재생되기 시작합니다.

+0

나는 해결책과 @geet의 해결책도 구현하기로 결정했다. onStop()에서 if (mBound)를 구현했습니다. { unbindService (mConnection); mBound = false; } – pinolo

관련 문제