2017-07-28 1 views
0

みんな、URLから音楽を再生するAndroidフォアグラウンドサービスを実装しようとしています。 MediaPlayerは正常に起動して曲を再生しますが、しばらくすると曲が終了していないときにonCompletion()を呼び出します。私は私がやっていることAndroid MediaPlayerはすでに完成前にonCompletionを呼び出します

... onErrorListenerを設定するが、それが呼び出されていない:

  1. はURLへの接続をチェック> OK
  2. チェック歌の期間> OK
  3. は、部分的な航跡を実装しましたロック>?

アプリケーションがクラッシュしない場合、MediaPlayerはonCompletionを呼び出すだけで何をすべきかわかりません。ここにはサービスとアクティビティのコードがあります。事前のおかげで:

サービス:

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

//FILTER FOR BROADCASTS 
public final static String ACTION_FILTER = "ACTION_HHGROUPS"; 

//MEDIA ACTIONS: 
public final static String ACTION_PLAY_ONE = "ACTION_PLAY_ONE"; 

//FOREGROUND: 
public static boolean IS_FOREGROUND = false; 
public final static int FOREGROUND_SERVICE = 101; 
public final static String ACTION_START_FOREGROUND = "ACTION_START_FOREGROUND"; 
public final static String ACTION_STOP_FOREGROUND = "ACTION_STOP_FOREGROUND"; 

//EXTRAS: 
public final static String EXTRA_URL = "EXTRA_URL"; 

private MediaPlayer mPlayer; 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    switch (intent.getAction()) { 
     case ACTION_START_FOREGROUND: 
      Log.v("SERVICIO", "ACTION_START_FOREGROUND"); 
      IS_FOREGROUND = true; 
      showNotification(); 
      break; 
     case ACTION_PLAY_ONE: 
      Log.v("SERVICIO", "ACTION_PLAY_ONE"); 
      initializeMediaPlayer(
       intent.getStringExtra(MusicService.EXTRA_URL); 
      break; 
     case ACTION_STOP_FOREGROUND: 
      Log.v("SERVICIO", "ACTION_STOP_FOREGROUND"); 
      IS_FOREGROUND = false; 
      stopForeground(true); 
      stopSelf(); 
      break; 
    } 
    return Service.START_STICKY; 
} 

public void initializePlayer(String url) { 
    if(mPlayer == null) { 
     mPlayer = new MediaPlayer(); 
     mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK); 
     mPlayer.setOnPreparedListener(this); 
     mPlayer.setOnCompletionListener(this); 
     mPlayer.setOnErrorListener(this); 
     if(url != null && !url.isEmpty()) { 
      try { 
       mPlayer.setDataSource(url); 
       mPlayer.prepareAsync(); 
      } catch (IOException e) { 
       Log.v("SERVICIO-MEDIA", "IOException"); 
       e.printStackTrace(); 
      } 
     } 
    } else { 
     try { 
      mPlayer.reset(); 
      mPlayer.setDataSource(url); 
      mPlayer.prepareAsync(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

@Override 
public void onTaskRemoved(Intent rootIntent) { 
    Log.e("SERVICIO", "OnTaskRemoved"); 
    if(IS_FOREGROUND) 
     stopForeground(true); 
    stopSelf(); 
} 

@Override 
public void onCompletion(MediaPlayer mediaPlayer) { 
    Log.v("SERVICIO", "onCompletion"); 
} 

@Override 
public void onPrepared(MediaPlayer mediaPlayer) { 
    mediaPlayer.start(); 
    Log.v("SERVICIO-MEDIA", "onPrepared. Duration: " + mediaPlayer.getDuration()); 
} 

@Override 
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) { 
    Log.v("SERVICIO", "onError"); 
    return true; 
} 

private void showNotification() { 
    Intent notificationIntent = new Intent(this, PruebaActivity.class); 
    notificationIntent.setAction(ACTION_NOTIFICATION_MAIN); 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, 
      notificationIntent, 0); 

    Intent previousIntent = new Intent(this, MusicService.class); 
    previousIntent.setAction(ACTION_NOTIFICATION_PREV); 
    PendingIntent ppreviousIntent = PendingIntent.getService(this, 0, 
      previousIntent, 0); 

    Intent playIntent = new Intent(this, MusicService.class); 
    playIntent.setAction(ACTION_NOTIFICATION_PLAY); 
    PendingIntent pplayIntent = PendingIntent.getService(this, 0, 
      playIntent, 0); 

    Intent nextIntent = new Intent(this, MusicService.class); 
    nextIntent.setAction(ACTION_NOTIFICATION_NEXT); 
    PendingIntent pnextIntent = PendingIntent.getService(this, 0, 
      nextIntent, 0); 

    Intent deleteIntent = new Intent(this, MusicService.class); 
    PendingIntent pdeleteIntent = PendingIntent.getService(this, 666,deleteIntent, 
      PendingIntent.FLAG_CANCEL_CURRENT); 

    Notification notification = new NotificationCompat.Builder(this) 
      .setContentTitle("Content title") 
      .setTicker("This is a Ticker...") 
      .setContentText("Context text") 
      .setSmallIcon(R.drawable.ic_launcher_background) 
      .setContentIntent(pendingIntent) 
      .setOngoing(true) 
      .addAction(android.R.drawable.ic_media_previous, "Prev", 
        ppreviousIntent) 
      .addAction(android.R.drawable.ic_media_play, "Play", 
        pplayIntent) 
      .addAction(android.R.drawable.ic_media_next, "Next", 
        pnextIntent).build(); 
    startForeground(FOREGROUND_SERVICE, notification); 
} 
} 

活動:

public class PruebaActivity extends AppCompatActivity implements View.OnClickListener { 

String url = "http://stream.hhgroups.com/1-Ey7w3haY2RtcqiutMX1SylvqnvkP1oFuKo4765uI6Dc-Isusko%20y%20Sbrv%20-%20Marionetas%20(Adelanto)%20-%20www.HHGroups.com/"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_prueba); 

    findViewById(R.id.btnPlaySong).setOnClickListener(this); 
    Button btnForeground = findViewById(R.id.btnStartForeground); 
    btnForeground.setOnClickListener(this); 
    if(MusicService.IS_FOREGROUND) 
     btnForeground.setText("STOP FOREGROUND"); 
    else 
     btnForeground.setText("START FOREGROUND"); 
} 

@SuppressLint("SetTextI18n") 
@Override 
public void onClick(View view) { 
    switch(view.getId()) { 
     case R.id.btnStartForeground: 
      if(MusicService.IS_FOREGROUND) { 
       Toast.makeText(PruebaActivity.this, "STOPPING FOREGROUND", Toast.LENGTH_SHORT).show(); 
       startService(new Intent(PruebaActivity.this, MusicService.class) 
         .setAction(MusicService.ACTION_STOP_FOREGROUND)); 
       ((Button)view).setText("START FOREGROUND"); 
      } else { 
       Toast.makeText(PruebaActivity.this, "SETTING FOREGROUND", Toast.LENGTH_SHORT).show(); 
       startService(new Intent(PruebaActivity.this, MusicService.class) 
         .setAction(MusicService.ACTION_START_FOREGROUND)); 
       ((Button)view).setText("STOP FOREGROUND"); 
      } 
      break; 
     case R.id.btnPlaySong: 
      if(MusicService.IS_FOREGROUND) { 
       Log.v("SERVICIO-ACTIVITY", "btnPlaySong -> Foreground ON"); 
       Toast.makeText(PruebaActivity.this, "PLAYING SONG", Toast.LENGTH_SHORT).show(); 
       startService(new Intent(PruebaActivity.this, MusicService.class) 
         .setAction(MusicService.ACTION_PLAY_ONE) 
         .putExtra(MusicService.EXTRA_URL, url)); 
      } else { 
       Log.v("SERVICIO-ACTIVITY", "btnPlaySong -> Foreground OFF"); 
       Toast.makeText(PruebaActivity.this, "SETTING FOREGROUND", Toast.LENGTH_SHORT).show(); 
       startService(new Intent(PruebaActivity.this, MusicService.class) 
         .setAction(MusicService.ACTION_START_FOREGROUND)); 
       Toast.makeText(PruebaActivity.this, "PLAYING SONG", Toast.LENGTH_SHORT).show(); 
       startService(new Intent(PruebaActivity.this, MusicService.class) 
         .setAction(MusicService.ACTION_PLAY_ONE) 
         .putExtra(MusicService.EXTRA_URL, url)); 
      } 
      break; 
    } 
} 
} 

任意のヘルプ?

答えて

1

サーバー側の問題のようです。あなたのテストURLは "Content-Disposition:inline;"レスポンスヘッダには、ストリーミングではないダウンロードを意味します。

HTTP/1.1 200 OK 
Date: Fri, 28 Jul 2017 18:20:20 GMT 
Server: Apache 
Cache-Control: max-age=2678400 
Content-Length: 10562918 
Content-Disposition: inline; filename="540b4a08d51bc718f1e7f30313af9526.mp3" 
Keep-Alive: timeout=10, max=800 
Connection: Keep-Alive 
Content-Type: audio/mpeg 

テストURLを変更してください。

+0

ありがとう、私はアクセスしているウェブは私のものではありません。そのような種類のURLからストリームを送信する可能性はありますか? – Kace

関連する問題