2017-01-18 3 views
0

私はバックグラウンドサービスで音楽をストリーミングしています。最近のアプリリストからサービスを削除したときを除いて、すべて正常に動作します。 mediaplayerがないときに私がサービスをスティッキーな仕事として実行するために私が使ったアプローチは、うまくいきます。ここに私のコードはアプリがwidowから切り離されたときにメディアプレイヤーが破壊された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

私が知っている限り、recentsリストのアプリをスワイプすると、あなたのアプリに関連するすべてを殺すことができます。これにはあらゆるサービスが含まれます。こちらをご覧ください: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と呼ぶことで行います。通知ID(自分が選択した整数)と通知をstartForegroundに渡す必要があります。通知は、ユーザーがサービスを停止するまでタスクバーに残ります。もちろん、通知または通知の処理の1つでサービスを停止するには、PendingIntentを提供する必要があります。

1

アプリケーションが破壊されると、サービスも停止します。問題はおそらくstartServiceでサービスを開始し、それをstopServiceで停止するということです。あなたのサービスクラスにメソッド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; 
    } 

次に、あなたのサービスが別のスレッドで実行するために起こっているとアプリケーションが殺された場合でも動作します。一部のバックグラウンドサービスが実行されていることをユーザーが指摘するためのローカル通知を表示することが重要です。

関連する問題