Fixed handling Bluetooth intents while Ultrasonic isn't running
This commit is contained in:
parent
c805005b02
commit
75a9c60889
|
@ -126,14 +126,6 @@
|
|||
android:name=".service.MediaPlayerService"
|
||||
android:label="Ultrasonic Download Service"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="org.moire.ultrasonic.CMD_TOGGLEPAUSE"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_PLAY"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_PAUSE"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_NEXT"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_PREVIOUS"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_STOP"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<receiver android:name=".receiver.MediaButtonIntentReceiver">
|
||||
|
@ -141,6 +133,17 @@
|
|||
<action android:name="android.intent.action.MEDIA_BUTTON"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receiver.UltrasonicIntentReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="org.moire.ultrasonic.CMD_TOGGLEPAUSE"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_PLAY"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_RESUME_OR_PLAY"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_PAUSE"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_NEXT"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_PREVIOUS"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_STOP"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receiver.BluetoothIntentReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.bluetooth.device.action.ACL_CONNECTED"/>
|
||||
|
|
|
@ -94,13 +94,13 @@ public class BluetoothIntentReceiver extends BroadcastReceiver
|
|||
if (resume)
|
||||
{
|
||||
Log.i(TAG, String.format("Connected to Bluetooth device %s address %s, resuming playback.", name, address));
|
||||
context.sendBroadcast(new Intent(Constants.CMD_PLAY));
|
||||
context.sendBroadcast(new Intent(Constants.CMD_RESUME_OR_PLAY).setPackage(context.getPackageName()));
|
||||
}
|
||||
|
||||
if (pause)
|
||||
{
|
||||
Log.i(TAG, String.format("Disconnected from Bluetooth device %s address %s, requesting pause.", name, address));
|
||||
context.sendBroadcast(new Intent(Constants.CMD_PAUSE));
|
||||
context.sendBroadcast(new Intent(Constants.CMD_PAUSE).setPackage(context.getPackageName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package org.moire.ultrasonic.receiver;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport;
|
||||
|
||||
import kotlin.Lazy;
|
||||
|
||||
import static org.koin.java.KoinJavaComponent.inject;
|
||||
|
||||
public class UltrasonicIntentReceiver extends BroadcastReceiver
|
||||
{
|
||||
private static final String TAG = UltrasonicIntentReceiver.class.getSimpleName();
|
||||
private Lazy<MediaPlayerLifecycleSupport> lifecycleSupport = inject(MediaPlayerLifecycleSupport.class);
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
String intentAction = intent.getAction();
|
||||
Log.i(TAG, String.format("Received Ultrasonic Intent: %s", intentAction));
|
||||
|
||||
try
|
||||
{
|
||||
lifecycleSupport.getValue().receiveIntent(intent);
|
||||
|
||||
if (isOrderedBroadcast())
|
||||
{
|
||||
abortBroadcast();
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
// Ignored.
|
||||
}
|
||||
}
|
||||
}
|
|
@ -89,7 +89,7 @@ public class Downloader
|
|||
|
||||
public void stop()
|
||||
{
|
||||
executorService.shutdown();
|
||||
if (executorService != null) executorService.shutdown();
|
||||
Log.i(TAG, "Downloader stopped");
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,16 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
|||
});
|
||||
}
|
||||
|
||||
public synchronized void resumeOrPlay()
|
||||
{
|
||||
MediaPlayerService.executeOnStartedMediaPlayerService(context, new Consumer<MediaPlayerService>() {
|
||||
@Override
|
||||
public void accept(MediaPlayerService mediaPlayerService) {
|
||||
mediaPlayerService.resumeOrPlay();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void togglePlayPause()
|
||||
{
|
||||
|
|
|
@ -81,17 +81,6 @@ public class MediaPlayerLifecycleSupport
|
|||
// React to media buttons.
|
||||
Util.registerMediaButtonEventReceiver(context, true);
|
||||
|
||||
// Register the handler for outside intents.
|
||||
IntentFilter commandFilter = new IntentFilter();
|
||||
commandFilter.addAction(Constants.CMD_PLAY);
|
||||
commandFilter.addAction(Constants.CMD_TOGGLEPAUSE);
|
||||
commandFilter.addAction(Constants.CMD_PAUSE);
|
||||
commandFilter.addAction(Constants.CMD_STOP);
|
||||
commandFilter.addAction(Constants.CMD_PREVIOUS);
|
||||
commandFilter.addAction(Constants.CMD_NEXT);
|
||||
commandFilter.addAction(Constants.CMD_PROCESS_KEYCODE);
|
||||
context.registerReceiver(intentReceiver, commandFilter);
|
||||
|
||||
mediaPlayerController.onCreate();
|
||||
if (autoPlay) mediaPlayerController.preload();
|
||||
|
||||
|
@ -120,7 +109,6 @@ public class MediaPlayerLifecycleSupport
|
|||
downloader.getCurrentPlayingIndex(), mediaPlayerController.getPlayerPosition());
|
||||
mediaPlayerController.clear(false);
|
||||
context.unregisterReceiver(headsetEventReceiver);
|
||||
context.unregisterReceiver(intentReceiver);
|
||||
mediaPlayerController.onDestroy();
|
||||
created = false;
|
||||
Log.i(TAG, "LifecycleSupport destroyed");
|
||||
|
@ -128,19 +116,33 @@ public class MediaPlayerLifecycleSupport
|
|||
|
||||
public void receiveIntent(Intent intent)
|
||||
{
|
||||
Log.i(TAG, "Received intent");
|
||||
if (intent != null && intent.getExtras() != null)
|
||||
{
|
||||
KeyEvent event = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT);
|
||||
if (event != null)
|
||||
{
|
||||
handleKeyEvent(event);
|
||||
if (intent == null) return;
|
||||
String intentAction = intent.getAction();
|
||||
if (intentAction == null || intentAction.isEmpty()) return;
|
||||
|
||||
Log.i(TAG, String.format("Received intent: %s", intentAction));
|
||||
|
||||
if (intentAction.equals(Constants.CMD_PROCESS_KEYCODE)) {
|
||||
if (intent.getExtras() != null) {
|
||||
KeyEvent event = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT);
|
||||
if (event != null) {
|
||||
handleKeyEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handleUltrasonicIntent(intentAction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Headset Intent Receiver is responsible for resuming playback when a headset is inserted
|
||||
* and pausing it when it is removed.
|
||||
* Unfortunately this Intent can't be registered in the AndroidManifest, so it works only
|
||||
* while Ultrasonic is running.
|
||||
*/
|
||||
private void registerHeadsetReceiver() {
|
||||
// Pause when headset is unplugged.
|
||||
final SharedPreferences sp = Util.getPreferences(context);
|
||||
final String spKey = context
|
||||
.getString(R.string.settings_playback_resume_play_on_headphones_plug);
|
||||
|
@ -255,43 +257,53 @@ public class MediaPlayerLifecycleSupport
|
|||
}
|
||||
|
||||
/**
|
||||
* This receiver manages the intent that could come from other applications.
|
||||
* This function processes the intent that could come from other applications.
|
||||
*/
|
||||
private BroadcastReceiver intentReceiver = new BroadcastReceiver()
|
||||
private void handleUltrasonicIntent(final String intentAction)
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
String action = intent.getAction();
|
||||
if (action == null) return;
|
||||
Log.i(TAG, "intentReceiver.onReceive: " + action);
|
||||
final boolean isRunning = created;
|
||||
// If Ultrasonic is not running, do nothing to stop or pause
|
||||
if (!isRunning && (intentAction.equals(Constants.CMD_PAUSE) ||
|
||||
intentAction.equals(Constants.CMD_STOP))) return;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case Constants.CMD_PLAY:
|
||||
mediaPlayerController.play();
|
||||
break;
|
||||
case Constants.CMD_NEXT:
|
||||
mediaPlayerController.next();
|
||||
break;
|
||||
case Constants.CMD_PREVIOUS:
|
||||
mediaPlayerController.previous();
|
||||
break;
|
||||
case Constants.CMD_TOGGLEPAUSE:
|
||||
mediaPlayerController.togglePlayPause();
|
||||
break;
|
||||
case Constants.CMD_STOP:
|
||||
// TODO: There is a stop() function, shouldn't we use that?
|
||||
mediaPlayerController.pause();
|
||||
mediaPlayerController.seekTo(0);
|
||||
break;
|
||||
case Constants.CMD_PAUSE:
|
||||
mediaPlayerController.pause();
|
||||
break;
|
||||
case Constants.CMD_PROCESS_KEYCODE:
|
||||
receiveIntent(intent);
|
||||
break;
|
||||
boolean autoStart = (intentAction.equals(Constants.CMD_PLAY) ||
|
||||
intentAction.equals(Constants.CMD_RESUME_OR_PLAY) ||
|
||||
intentAction.equals(Constants.CMD_TOGGLEPAUSE) ||
|
||||
intentAction.equals(Constants.CMD_PREVIOUS) ||
|
||||
intentAction.equals(Constants.CMD_NEXT));
|
||||
|
||||
// We can receive intents when everything is stopped, so we need to start
|
||||
onCreate(autoStart, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch(intentAction)
|
||||
{
|
||||
case Constants.CMD_PLAY:
|
||||
mediaPlayerController.play();
|
||||
break;
|
||||
case Constants.CMD_RESUME_OR_PLAY:
|
||||
// If Ultrasonic wasn't running, the autoStart is enough to resume, no need to call anything
|
||||
if (isRunning) mediaPlayerController.resumeOrPlay();
|
||||
break;
|
||||
case Constants.CMD_NEXT:
|
||||
mediaPlayerController.next();
|
||||
break;
|
||||
case Constants.CMD_PREVIOUS:
|
||||
mediaPlayerController.previous();
|
||||
break;
|
||||
case Constants.CMD_TOGGLEPAUSE:
|
||||
mediaPlayerController.togglePlayPause();
|
||||
break;
|
||||
case Constants.CMD_STOP:
|
||||
// TODO: There is a stop() function, shouldn't we use that?
|
||||
mediaPlayerController.pause();
|
||||
mediaPlayerController.seekTo(0);
|
||||
break;
|
||||
case Constants.CMD_PAUSE:
|
||||
mediaPlayerController.pause();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
|
@ -361,6 +361,18 @@ public class MediaPlayerService extends Service
|
|||
}
|
||||
}
|
||||
|
||||
public synchronized void resumeOrPlay()
|
||||
{
|
||||
if (localMediaPlayer.playerState == PAUSED || localMediaPlayer.playerState == COMPLETED || localMediaPlayer.playerState == STOPPED)
|
||||
{
|
||||
start();
|
||||
}
|
||||
else if (localMediaPlayer.playerState == IDLE)
|
||||
{
|
||||
play();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays either the current song (resume) or the first/next one in queue.
|
||||
*/
|
||||
|
|
|
@ -63,6 +63,7 @@ public final class Constants
|
|||
// Names for Intent Actions
|
||||
public static final String CMD_PROCESS_KEYCODE = "org.moire.ultrasonic.CMD_PROCESS_KEYCODE";
|
||||
public static final String CMD_PLAY = "org.moire.ultrasonic.CMD_PLAY";
|
||||
public static final String CMD_RESUME_OR_PLAY = "org.moire.ultrasonic.CMD_RESUME_OR_PLAY";
|
||||
public static final String CMD_TOGGLEPAUSE = "org.moire.ultrasonic.CMD_TOGGLEPAUSE";
|
||||
public static final String CMD_PAUSE = "org.moire.ultrasonic.CMD_PAUSE";
|
||||
public static final String CMD_STOP = "org.moire.ultrasonic.CMD_STOP";
|
||||
|
|
Loading…
Reference in New Issue