滑动磨损应用程序的覆盖方法
Overriding method to swipe away wear app
我正在制作一个需要 Android Wear 后台服务的应用程序。我能够在后台将其设置为 运行。转到其他应用程序或单击主页按钮不会停止服务,但在 MainActivity 上向右滑动会停止应用程序和 activity。这是返回表盘的明显方式,所以我不想禁用滑动。有没有办法覆盖此操作?
编辑:这是我的代码。我按照建议添加了 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);
}
}
}
基本上我必须添加一个函数来在播放音乐之前请求音频焦点。对于任何感兴趣的人,我正在关注本教程:
https://www.sitepoint.com/a-step-by-step-guide-to-building-an-android-audio-player-app/
然后在服务的onDestroy
函数中,去掉removeAudioFocus
这一行让音乐继续。
编辑:一个更好的方法似乎是按照教程,但是在主要activity的onDestroy方法中,只解除绑定服务。我以前的方法可行,但在某些设备上会崩溃。
我正在制作一个需要 Android Wear 后台服务的应用程序。我能够在后台将其设置为 运行。转到其他应用程序或单击主页按钮不会停止服务,但在 MainActivity 上向右滑动会停止应用程序和 activity。这是返回表盘的明显方式,所以我不想禁用滑动。有没有办法覆盖此操作?
编辑:这是我的代码。我按照建议添加了 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);
}
}
}
基本上我必须添加一个函数来在播放音乐之前请求音频焦点。对于任何感兴趣的人,我正在关注本教程:
https://www.sitepoint.com/a-step-by-step-guide-to-building-an-android-audio-player-app/
然后在服务的onDestroy
函数中,去掉removeAudioFocus
这一行让音乐继续。
编辑:一个更好的方法似乎是按照教程,但是在主要activity的onDestroy方法中,只解除绑定服务。我以前的方法可行,但在某些设备上会崩溃。