我有一个可以播放单个实时mp3广播流的应用。它将音频作为服务播放,以便可以在后台运行。该应用程序只有一个按钮可以打开/关闭流。
如何在主要活动运行时从其访问服务对象,以便确定播放/暂停按钮应执行的操作。
基本上我想做if service.isPlaying -> stopService (and be a Play button) -> else -> startService (and be a pause button)
到目前为止,每当我尝试访问该服务以检查service.isplaying()
时,我只会返回空错误。如果我尝试if (service != null)
,它也总是返回null。
这是我的服务
public class StreamService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
public static final String ACTION_PLAY = "com.example.action.PLAY";
private static final String TEST_URL = "https://www.nasa.gov/mp3/586447main_JFKwechoosemoonspeech.mp3";
MainActivity mainActivity;
MediaPlayer mediaPlayer = null;
WifiManager.WifiLock wifiLock;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public class LocalBinder extends Binder {
public StreamService getServiceInstance() {
return StreamService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(ACTION_PLAY)) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
wifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "mylock");
wifiLock.acquire();
try {
// Set the stream URL location
mediaPlayer.setDataSource(TEST_URL);
// prepareAsync must be called after setAudioStreamType and setOnPreparedListener
mediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
return START_STICKY;
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// ... react appropriately ...
// The MediaPlayer has moved to the Error state, must be reset!
return false;
}
void switchButton() {
mainActivity.checkPlaying(!mediaPlayer.isPlaying());
}
public boolean play() {
if (mediaPlayer != null) {
//switchButton();
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
return false;
} else {
mediaPlayer.start();
return true;
}
}
return false;
}
public void stop() {
try {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
/** Called when MediaPlayer is ready */
public void onPrepared(MediaPlayer player) {
player.start();
}
@Override
public void onDestroy() {
super.onDestroy();
if( wifiLock != null) wifiLock.release();
if (mediaPlayer != null) mediaPlayer.release();
}
public void registerClient(MainActivity activity) {
mainActivity = activity;
}
public boolean isplaying() {
return mediaPlayer == null ? false : mediaPlayer.isPlaying();
}
}
和我的ActivityMain
public class MainActivity extends AppCompatActivity {
private ImageButton btn; // Play | Pause toggle button
private ImageView img; // Radio tower image that alternates between on and off
StreamService service;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Bind the view buttons to local variables
btn = findViewById(R.id.playPause);
img = findViewById(R.id.radioTower);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startStream();
checkPlaying(true);
}
});
}
public void startStream() {
Intent serviceIntent = new Intent(MainActivity.this, StreamService.class);
serviceIntent.setAction(StreamService.ACTION_PLAY);
startService(serviceIntent);
bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
}
public void stopStream() {
if (service != null) {
try {
service.stop();
unbindService(mConnection);
stopService(new Intent(MainActivity.this, service.getClass()));
service = null;
} catch (IllegalArgumentException ex) {
stopService(new Intent(MainActivity.this, service.getClass()));
service = null;
ex.printStackTrace();
}
}
}
public void checkPlaying(Boolean isPlaying) {
if (isPlaying) {
btn.setBackgroundResource(R.drawable.ic_rounded_pause_button);
img.setImageResource(R.drawable.ic_toweron);
img.setAlpha(1.0f);
} else {
btn.setBackgroundResource(R.drawable.ic_play_button);
img.setImageResource(R.drawable.ic_toweroff);
img.setAlpha(0.3f);
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder _service) {
StreamService.LocalBinder binder = (StreamService.LocalBinder) _service;
service = binder.getServiceInstance(); //Get instance of your service!
service.registerClient(MainActivity.this); //Activity register in the service as client for callabcks!
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
}
};
}