2017-01-18 20 views
0

Я передаю музыку в фоновом режиме. Все работает отлично, за исключением случаев, когда я удаляю приложение из недавнего списка приложений, который был разрушен службой. Подход, который я использовал, чтобы заставить службу работать как липкую работу, отлично, когда нет медиаплеера. Вот мой кодСлужба Android с медиаплеером уничтожена, когда приложение отключено от вдовы

public class StreamListenerService extends Service implements MediaPlayer.OnPreparedListener, 
     MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener { 

    public static MediaPlayer mMediaPlayer; 
    private String streamUrl; 
    public static boolean isPlaying = false; 


    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     streamUrl = intent.getStringExtra("streamUrl"); 



     mMediaPlayer = new MediaPlayer(); 
     mMediaPlayer.reset(); 
     mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 


     try { 
      mMediaPlayer.setDataSource(streamUrl); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 


     mMediaPlayer.setOnPreparedListener(this); 
     mMediaPlayer.setOnErrorListener(this); 
     mMediaPlayer.prepareAsync(); 
     mMediaPlayer.setOnCompletionListener(this); 

     isPlaying = true; 

     return Service.START_STICKY_COMPATIBILITY; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @Override 
    public void onDestroy() { 
     Log.d("StreamListenerService", "onDestroy"); 
     if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { 
      mMediaPlayer.stop(); 
      mMediaPlayer.reset(); 
      isPlaying = false; 
     } 
     super.onDestroy(); 

    } 


    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onPrepared(MediaPlayer mediaPlayer) { 
     mMediaPlayer.start(); 
     isPlaying = true; 
    } 

    @Override 
    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) { 

     Toast.makeText(this, R.string.text_problem_in_playing_audio_stream, Toast.LENGTH_SHORT).show(); 

     mMediaPlayer.stop(); 
     mMediaPlayer.reset(); 

     //Toast.makeText(this, R.string.text_problem_in_playing_stream,Toast.LENGTH_SHORT).show(); 

     this.onDestroy(); 
     return false; 
    } 


    @Override 
    public void onCompletion(MediaPlayer mp) { 
     Toast.makeText(this, R.string.text_stream_finished, Toast.LENGTH_SHORT).show(); 
     mMediaPlayer = mp; 
     mMediaPlayer.stop(); 
     mMediaPlayer.reset(); 
     this.onDestroy(); 
    } 
} 
+1

Насколько я знаю, когда вы удаляете приложение в списке адресов, оно может убить все, что связано с вашим приложением. Сюда входят любые услуги. См. Здесь: http://stackoverflow.com/questions/30936888/differentiate-between-android-killing-the-app-and-user-swiping-it-off-on-the-rec – FrankR

ответ

2

Вы должны указать, что служба работает в своем собственном процессе в вашем приложении манифеста, добавив атрибут android:process=":whatever" тэгу службы. Это гарантирует, что служба не будет убита, когда основной процесс вашего приложения будет, т. Е. Когда приложение будет удалено из списка приложений.

Если вы хотите запустить сервис до тех пор, пока пользователь не остановится, запустите его как службу переднего плана. Вы делаете это, позвонив в какой-то момент startForeground. Вам необходимо передать идентификатор уведомления (целое по своему усмотрению) и Уведомление на startForeground. Уведомление останется в панели задач, пока пользователь не остановит службу. Разумеется, вы должны предоставить PendingIntent, чтобы остановить службу в уведомлении или в одном из действий уведомления.

1

Когда ваше приложение будет уничтожено, любые ваши услуги также прекратятся. Проблема в том, что вы, вероятно, запустите свой сервис только с startService и остановите его с помощью stopService. Что вам нужно сделать, это начать свой сервис с помощью метода startForeground внутри onStartCommand в вашем классе обслуживания.

@Override 
    public int onStartCommand(Intent i, int flags, int startId) { 

     Intent resultIntent = new Intent(SOME_INTENT_ACTION); 
     PendingIntent resultPendingIntent = PendingIntent.getBroadcast(this, 0, resultIntent, 0); 

     Notification noti = new Notification.Builder(getApplicationContext()) 
       .setContentTitle(TITLE) 
       .setContentText(CONTENT_TEXT) 
       .setSmallIcon(R.mipmap.ic_launcher) 
       .setContentIntent(resultPendingIntent) 
       .build(); 

     startForeground(12345, noti); 

     return Service.START_STICKY; 
    } 

Тогда ваша служба будет работать в другой ветке и будет работать, даже если ваше приложение будет убито. Важно, чтобы вы показывали локальное уведомление для пользователя, указывающее на то, что работает некоторая фоновая служба.