2017-07-18 29 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

也許你可以讓你的服務在其onStartCommand()函數中返回START_STICKY,以便OS啓動服務。 – 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方法中,只解除綁定服務。我以前的方法可以工作,但會在某些設備上崩潰。