2017-07-18 19 views
0

Android Wearでバックグラウンドサービスが必要なアプリを作っています。私はそれをバックグラウンドで実行することができました。別のアプリに行くか、ホームボタンをクリックしてもサービスは停止しませんが、MainActivityを右にスワイプすると、アプリとアクティビティが停止します。これはウォッチフェイスに戻るための明白な方法ですので、スワイプを無効にしたくありません。このアクションを無効にする方法はありますか?着用アプリをスワイプする方法を無効にする

編集:ここに私のコードです。提案通りにSTART_STICKYを追加しましたが、違いは見られませんでした。

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

private MediaPlayer player; 
private List<Song> songs; 
private int songIndex; 
private final IBinder musicBind = new MusicBinder(); 
private AudioManager audioManager; 

public void onCreate() { 
    // Create the service 
    super.onCreate(); 
    songIndex = 0; 
    player = new MediaPlayer(); 

    initMusicPlayer(); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    String mediaFile = ""; 
    try { 
     //An audio file is passed to the service through putExtra(); 
     mediaFile = songs.get(songIndex).uri; 
    } catch (NullPointerException e) { 
     stopSelf(); 
    } 

    //Request audio focus 
    if (requestAudioFocus() == false) { 
     //Could not gain focus 
     stopSelf(); 
    } 

    if (mediaFile != null && mediaFile != "") 
     initMusicPlayer(); 
    return super.onStartCommand(intent, flags, START_STICKY); 
} 

public void initMusicPlayer() { 
    // Set player properties 
    player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK); 
    player.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    player.setOnPreparedListener(this); 
    player.setOnCompletionListener(this); 
    player.setOnErrorListener(this); 
} 
public void setSong(int songIndex) { 
    this.songIndex = songIndex; 
} 

public void setList(List<Song> songs) { 
    this.songs = songs; 
} 

public class MusicBinder extends Binder { 
    MusicService getService() { 
     return MusicService.this; 
    } 
} 

@Override 
public boolean onInfo(MediaPlayer mediaPlayer, int i, int i1) { 
    return false; 
} 

@Override 
public void onAudioFocusChange(int focusState) { 
    switch (focusState) { 
     case AudioManager.AUDIOFOCUS_GAIN: 
      // resume playback 
      if (player == null) initMusicPlayer(); 
      else if (!player.isPlaying()) player.start(); 
      player.setVolume(1.0f, 1.0f); 
      break; 
     case AudioManager.AUDIOFOCUS_LOSS: 
      // Lost focus for an unbounded amount of time: stop playback and release media player 
      if (player.isPlaying()) player.stop(); 
      player.release(); 
      player = null; 
      break; 
     case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 
      // Lost focus for a short time, but we have to stop 
      // playback. We don't release the media player because playback 
      // is likely to resume 
      if (player.isPlaying()) player.pause(); 
      break; 
     case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 
      // Lost focus for a short time, but it's ok to keep playing 
      // at an attenuated level 
      if (player.isPlaying()) player.setVolume(0.1f, 0.1f); 
      break; 
    } 
} 

private boolean requestAudioFocus() { 
    audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 
    int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); 
    if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { 
     //Focus gained 
     return true; 
    } 
    //Could not gain focus 
    return false; 
} 

private boolean removeAudioFocus() { 
    return AudioManager.AUDIOFOCUS_REQUEST_GRANTED == 
      audioManager.abandonAudioFocus(this); 
} 

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

@Override 
public boolean onUnbind(Intent intent) { 
    player.stop(); 
    player.release(); 
    return false; 
} 

@Override 
public void onCompletion(MediaPlayer mediaPlayer) { 

} 



@Override 
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) { 
    return false; 
} 

@Override 
public void onPrepared(MediaPlayer mediaPlayer) { 
    mediaPlayer.start(); 
} 

public void playSong() { 
    player.reset(); 
    Song playSong = songs.get(songIndex); 
    Uri trackUri = Uri.parse(playSong.uri); 

    try { 
     player.setDataSource(getApplicationContext(), trackUri); 
     player.prepareAsync(); 
    } catch (Exception ex) { 
     Log.e("Music Service", "Error setting data source", ex); 
    } 
} 
} 
+0

OSがサービスを開始するように、サービスがonStartCommand()でSTART_STICKYを返すようにすることができます。 – ZeekHuge

+0

私はSTART_STICKYで試しましたが、違いは見られませんでした。多分私のコードに何かがあります。私は行方不明です。私は 'unbindService(musicConnection);' onDestroy'を主なアクティビティでも使用していますが、これを取り除くだけでスローとエラーが発生します。 "mediaplayerは未処理のイベントで終了しました" –

+0

データを送信する意図を使用している場合は、 'START_REDELIVER_INTENT' – ZeekHuge

答えて

0

基本的には、音楽を再生する前にオーディオのフォーカスを要求する関数を追加する必要がありました。興味のある方は、このチュートリアルに従いました: https://www.sitepoint.com/a-step-by-step-guide-to-building-an-android-audio-player-app/ サービスのonDestroy機能では、音楽を続けるためにremoveAudioFocusの行を外してください。

編集:より良い方法はチュートリアルに従っているようですが、主なアクティビティのonDestroyメソッドではサービスのバインドを解除するだけです。私の以前の方法では動作しますが、一部のデバイスでクラッシュします。