У меня есть приложение, которое воспроизводит один прямой эфир в формате mp3. Он воспроизводит этот звук как сервис, чтобы он мог работать в фоновом режиме. Приложение имеет только одну кнопку, которая включает / выключает поток.
Как я могу получить доступ к сервисному объекту из моего основного действия во время его работы, чтобы я мог определить, какое действие должна выполнить кнопка воспроизведения / паузы.
По сути, я хочу сделать if service.isPlaying -> stopService (and be a Play button) -> else -> startService (and be a pause button)
До сих пор, когда я пытаюсь получить доступ к сервису, например, чтобы проверить service.isplaying()
, я просто возвращаю нулевые ошибки. Если я пытаюсь if (service != 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) {
}
};
}