mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-17 01:32:23 +03:00
Merge pull request #318 from nitehu/feature/bluetooth_connection_settings
Implemented Bluetooth connection settings
This commit is contained in:
commit
60b6a5dbde
@ -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,12 +133,24 @@
|
||||
<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"/>
|
||||
<action android:name="org.moire.ultrasonic.CMD_PROCESS_KEYCODE"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receiver.BluetoothIntentReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.bluetooth.device.action.ACL_CONNECTED"/>
|
||||
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/>
|
||||
<action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED"/>
|
||||
<action android:name="android.bluetooth.a2dp.action.SINK_STATE_CHANGED"/>
|
||||
<action android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.moire.ultrasonic.fragment;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
@ -7,6 +9,8 @@ import android.os.Bundle;
|
||||
import android.preference.*;
|
||||
import android.provider.SearchRecentSuggestions;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
@ -19,6 +23,7 @@ import org.moire.ultrasonic.featureflags.FeatureStorage;
|
||||
import org.moire.ultrasonic.filepicker.FilePickerDialog;
|
||||
import org.moire.ultrasonic.filepicker.OnFileSelectedListener;
|
||||
import org.moire.ultrasonic.provider.SearchSuggestionProvider;
|
||||
import org.moire.ultrasonic.service.Consumer;
|
||||
import org.moire.ultrasonic.service.MediaPlayerController;
|
||||
import org.moire.ultrasonic.util.*;
|
||||
|
||||
@ -64,6 +69,8 @@ public class SettingsFragment extends PreferenceFragment
|
||||
private EditTextPreference sharingDefaultGreeting;
|
||||
private TimeSpanPreference sharingDefaultExpiration;
|
||||
private PreferenceCategory serversCategory;
|
||||
private Preference resumeOnBluetoothDevice;
|
||||
private Preference pauseOnBluetoothDevice;
|
||||
|
||||
private SharedPreferences settings;
|
||||
|
||||
@ -110,12 +117,15 @@ public class SettingsFragment extends PreferenceFragment
|
||||
sharingDefaultGreeting = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_GREETING);
|
||||
sharingDefaultExpiration = (TimeSpanPreference) findPreference(Constants.PREFERENCES_KEY_DEFAULT_SHARE_EXPIRATION);
|
||||
serversCategory = (PreferenceCategory) findPreference(Constants.PREFERENCES_KEY_SERVERS_KEY);
|
||||
resumeOnBluetoothDevice = findPreference(Constants.PREFERENCES_KEY_RESUME_ON_BLUETOOTH_DEVICE);
|
||||
pauseOnBluetoothDevice = findPreference(Constants.PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE);
|
||||
|
||||
sharingDefaultGreeting.setText(Util.getShareGreeting(getActivity()));
|
||||
setupClearSearchPreference();
|
||||
setupGaplessControlSettingsV14();
|
||||
setupFeatureFlagsPreferences();
|
||||
setupCacheLocationPreference();
|
||||
setupBluetoothDevicePreferences();
|
||||
|
||||
// After API26 foreground services must be used for music playback, and they must have a notification
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
@ -199,6 +209,87 @@ public class SettingsFragment extends PreferenceFragment
|
||||
});
|
||||
}
|
||||
|
||||
private void setupBluetoothDevicePreferences() {
|
||||
final int resumeSetting = Util.getResumeOnBluetoothDevice(getActivity());
|
||||
final int pauseSetting = Util.getPauseOnBluetoothDevice(getActivity());
|
||||
|
||||
resumeOnBluetoothDevice.setSummary(bluetoothDevicePreferenceToString(resumeSetting));
|
||||
pauseOnBluetoothDevice.setSummary(bluetoothDevicePreferenceToString(pauseSetting));
|
||||
|
||||
resumeOnBluetoothDevice.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
showBluetoothDevicePreferenceDialog(
|
||||
R.string.settings_playback_resume_on_bluetooth_device,
|
||||
Util.getResumeOnBluetoothDevice(getActivity()),
|
||||
new Consumer<Integer>() {
|
||||
@Override
|
||||
public void accept(Integer choice) {
|
||||
SharedPreferences.Editor editor = resumeOnBluetoothDevice.getEditor();
|
||||
editor.putInt(Constants.PREFERENCES_KEY_RESUME_ON_BLUETOOTH_DEVICE, choice);
|
||||
editor.commit();
|
||||
resumeOnBluetoothDevice.setSummary(bluetoothDevicePreferenceToString(choice));
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
pauseOnBluetoothDevice.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
showBluetoothDevicePreferenceDialog(
|
||||
R.string.settings_playback_pause_on_bluetooth_device,
|
||||
Util.getPauseOnBluetoothDevice(getActivity()),
|
||||
new Consumer<Integer>() {
|
||||
@Override
|
||||
public void accept(Integer choice) {
|
||||
SharedPreferences.Editor editor = pauseOnBluetoothDevice.getEditor();
|
||||
editor.putInt(Constants.PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE, choice);
|
||||
editor.commit();
|
||||
pauseOnBluetoothDevice.setSummary(bluetoothDevicePreferenceToString(choice));
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showBluetoothDevicePreferenceDialog(@StringRes int title, int defaultChoice, final Consumer<Integer> onChosen) {
|
||||
final int[] choice = {defaultChoice};
|
||||
new AlertDialog.Builder(getActivity()).setTitle(title)
|
||||
.setSingleChoiceItems(R.array.bluetoothDeviceSettingNames, defaultChoice,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
choice[0] = i;
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.common_cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
dialogInterface.cancel();
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
onChosen.accept(choice[0]);
|
||||
dialogInterface.dismiss();
|
||||
}
|
||||
})
|
||||
.create().show();
|
||||
}
|
||||
|
||||
private String bluetoothDevicePreferenceToString(int preferenceValue) {
|
||||
switch (preferenceValue) {
|
||||
case Constants.PREFERENCE_VALUE_ALL: return getString(R.string.settings_playback_bluetooth_all);
|
||||
case Constants.PREFERENCE_VALUE_A2DP: return getString(R.string.settings_playback_bluetooth_a2dp);
|
||||
case Constants.PREFERENCE_VALUE_DISABLED: return getString(R.string.settings_playback_bluetooth_disabled);
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
private void setupClearSearchPreference() {
|
||||
Preference clearSearchPreference = findPreference(Constants.PREFERENCES_KEY_CLEAR_SEARCH_HISTORY);
|
||||
|
||||
|
@ -19,17 +19,10 @@ public class A2dpIntentReceiver extends BroadcastReceiver
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
if (mediaPlayerControllerLazy.getValue().getCurrentPlaying() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (mediaPlayerControllerLazy.getValue().getCurrentPlaying() == null) return;
|
||||
|
||||
Entry song = mediaPlayerControllerLazy.getValue().getCurrentPlaying().getSong();
|
||||
|
||||
if (song == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (song == null) return;
|
||||
|
||||
Intent avrcpIntent = new Intent(PLAYSTATUS_RESPONSE);
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.moire.ultrasonic.receiver;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -34,44 +35,72 @@ import org.moire.ultrasonic.util.Util;
|
||||
*/
|
||||
public class BluetoothIntentReceiver extends BroadcastReceiver
|
||||
{
|
||||
|
||||
private static final String TAG = BluetoothIntentReceiver.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
int state = intent.getIntExtra("android.bluetooth.a2dp.extra.SINK_STATE", -1);
|
||||
int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
String action = intent.getAction();
|
||||
String name = device != null ? device.getName() : "None";
|
||||
String name = device != null ? device.getName() : "Unknown";
|
||||
String address = device != null ? device.getAddress() : "Unknown";
|
||||
|
||||
Log.d(TAG, String.format("Sink State: %d; Action: %s; Device: %s", state, action, name));
|
||||
Log.d(TAG, String.format("A2DP State: %d; Action: %s; Device: %s; Address: %s", state, action, name, address));
|
||||
|
||||
boolean actionConnected = false;
|
||||
boolean actionDisconnected = false;
|
||||
boolean actionBluetoothDeviceConnected = false;
|
||||
boolean actionBluetoothDeviceDisconnected = false;
|
||||
boolean actionA2dpConnected = false;
|
||||
boolean actionA2dpDisconnected = false;
|
||||
|
||||
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action))
|
||||
{
|
||||
actionConnected = true;
|
||||
actionBluetoothDeviceConnected = true;
|
||||
}
|
||||
else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action) || BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action))
|
||||
{
|
||||
actionDisconnected = true;
|
||||
actionBluetoothDeviceDisconnected = true;
|
||||
}
|
||||
|
||||
boolean connected = state == android.bluetooth.BluetoothA2dp.STATE_CONNECTED || actionConnected;
|
||||
boolean disconnected = state == android.bluetooth.BluetoothA2dp.STATE_DISCONNECTED || actionDisconnected;
|
||||
if (state == android.bluetooth.BluetoothA2dp.STATE_CONNECTED) actionA2dpConnected = true;
|
||||
else if (state == android.bluetooth.BluetoothA2dp.STATE_DISCONNECTED) actionA2dpDisconnected = true;
|
||||
|
||||
boolean connected = actionA2dpConnected || actionBluetoothDeviceConnected;
|
||||
boolean resume = false;
|
||||
boolean pause = false;
|
||||
|
||||
switch (Util.getResumeOnBluetoothDevice(context))
|
||||
{
|
||||
case Constants.PREFERENCE_VALUE_ALL: resume = actionA2dpConnected || actionBluetoothDeviceConnected;
|
||||
break;
|
||||
case Constants.PREFERENCE_VALUE_A2DP: resume = actionA2dpConnected;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Util.getPauseOnBluetoothDevice(context))
|
||||
{
|
||||
case Constants.PREFERENCE_VALUE_ALL: pause = actionA2dpDisconnected || actionBluetoothDeviceDisconnected;
|
||||
break;
|
||||
case Constants.PREFERENCE_VALUE_A2DP: pause = actionA2dpDisconnected;
|
||||
break;
|
||||
}
|
||||
|
||||
if (connected)
|
||||
{
|
||||
Log.i(TAG, "Connected to Bluetooth device, requesting media button focus.");
|
||||
Log.i(TAG, String.format("Connected to Bluetooth device %s address %s, requesting media button focus.", name, address));
|
||||
Util.registerMediaButtonEventReceiver(context, false);
|
||||
}
|
||||
|
||||
if (disconnected)
|
||||
if (resume)
|
||||
{
|
||||
Log.i(TAG, "Disconnected from Bluetooth device, requesting pause.");
|
||||
context.sendBroadcast(new Intent(Constants.CMD_PAUSE));
|
||||
Log.i(TAG, String.format("Connected to Bluetooth device %s address %s, resuming playback.", name, address));
|
||||
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).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";
|
||||
@ -131,6 +132,12 @@ public final class Constants
|
||||
public static final String PREFERENCES_KEY_USE_FIVE_STAR_RATING = "use_five_star_rating";
|
||||
public static final String PREFERENCES_KEY_CATEGORY_NOTIFICATIONS = "notificationsCategory";
|
||||
public static final String PREFERENCES_KEY_FIRST_RUN_EXECUTED = "firstRunExecuted";
|
||||
public static final String PREFERENCES_KEY_RESUME_ON_BLUETOOTH_DEVICE = "resumeOnBluetoothDevice";
|
||||
public static final String PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE = "pauseOnBluetoothDevice";
|
||||
|
||||
public static final int PREFERENCE_VALUE_ALL = 0;
|
||||
public static final int PREFERENCE_VALUE_A2DP = 1;
|
||||
public static final int PREFERENCE_VALUE_DISABLED = 2;
|
||||
|
||||
// Number of free trial days for non-licensed servers.
|
||||
public static final int FREE_TRIAL_DAYS = 30;
|
||||
|
@ -1447,4 +1447,16 @@ public class Util
|
||||
editor.apply();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int getResumeOnBluetoothDevice(Context context)
|
||||
{
|
||||
SharedPreferences preferences = getPreferences(context);
|
||||
return preferences.getInt(Constants.PREFERENCES_KEY_RESUME_ON_BLUETOOTH_DEVICE, Constants.PREFERENCE_VALUE_DISABLED);
|
||||
}
|
||||
|
||||
public static int getPauseOnBluetoothDevice(Context context)
|
||||
{
|
||||
SharedPreferences preferences = getPreferences(context);
|
||||
return preferences.getInt(Constants.PREFERENCES_KEY_PAUSE_ON_BLUETOOTH_DEVICE, Constants.PREFERENCE_VALUE_A2DP);
|
||||
}
|
||||
}
|
||||
|
@ -396,6 +396,12 @@
|
||||
<string name="settings.image_loader_concurrency_12">12</string>
|
||||
<string name="albumArt">Album Cover</string>
|
||||
<string name="common_multiple_years">Mehrere Jahre</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Resume when a Bluetooth device is connected</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Pause when a Bluetooth device is disconnected</string>
|
||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||
|
||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||
<string name="permissions.message_box_title">Warning</string>
|
||||
<string name="permissions.permission_missing">Ultrasonic needs read/write permission to the music cache directory. Cache directory was reset to its default value.</string>
|
||||
|
@ -397,6 +397,12 @@
|
||||
<string name="settings.image_loader_concurrency_12">12</string>
|
||||
<string name="albumArt">Caratula del Álbum</string>
|
||||
<string name="common_multiple_years">Múltiples años</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Reanudar al conectar un dispositivo Bluetooth</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Pausar al desconectar un dispositivo Bluetooth</string>
|
||||
<string name="settings.playback.bluetooth_all">Todos los dispositivos Bluetooth</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Solo dispositivos de audio (A2DP)</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Deshabilitado</string>
|
||||
|
||||
<string name="permissions.access_error">Ultrasonic no puede acceder a la caché de los ficheros de música. La ubicación de la caché se restableció a la ruta predeterminada.</string>
|
||||
<string name="permissions.message_box_title">Atención</string>
|
||||
<string name="permissions.permission_missing">Ultrasonic necesita permiso de lectura / escritura para el directorio caché de música. El directorio caché se restableció a su valor predeterminado.</string>
|
||||
|
@ -397,6 +397,12 @@
|
||||
<string name="settings.image_loader_concurrency_12">12</string>
|
||||
<string name="albumArt">albumArt</string>
|
||||
<string name="common_multiple_years">Multiple Years</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Resume when a Bluetooth device is connected</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Pause when a Bluetooth device is disconnected</string>
|
||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||
|
||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||
<string name="permissions.message_box_title">Warning</string>
|
||||
<string name="permissions.permission_missing">Ultrasonic needs read/write permission to the music cache directory. Cache directory was reset to its default value.</string>
|
||||
|
@ -229,7 +229,7 @@
|
||||
<string name="settings.max_bitrate_unlimited">Korlátlan</string>
|
||||
<string name="settings.max_bitrate_wifi">Max. bitráta - Wi-Fi kapcsolat</string>
|
||||
<string name="settings.max_songs">Dalok max. találati száma</string>
|
||||
<string name="settings.media_button_summary">Telefon irányítása a bluetooth eszköz, vagy a fülhallgató vezérlőgombjaival.</string>
|
||||
<string name="settings.media_button_summary">Telefon irányítása a Bluetooth eszköz, vagy a fülhallgató vezérlőgombjaival.</string>
|
||||
<string name="settings.media_button_title">Média vezérlőgombok</string>
|
||||
<string name="settings.network_timeout">Hálózati időtúllépés</string>
|
||||
<string name="settings.network_timeout_105000">105 másodperc</string>
|
||||
@ -396,7 +396,13 @@
|
||||
<string name="settings.image_loader_concurrency_11">11</string>
|
||||
<string name="settings.image_loader_concurrency_12">12</string>
|
||||
<string name="albumArt">albumArt</string>
|
||||
<string name="common_multiple_years">Multiple Years</string>
|
||||
<string name="common_multiple_years">Több év</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Folytatás Bluetooth eszköz csatlakozásakor</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Szünet Bluetooth eszköz kikapcsolásakor</string>
|
||||
<string name="settings.playback.bluetooth_all">Minden Bluetooth eszköz</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Csak audio (A2DP) eszközök</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Kikapcsolva</string>
|
||||
|
||||
<string name="permissions.access_error">Az Ultrasonic nem éri el a zenei fájl gyorsítótárat. A gyorsítótár helye visszaállítva az alapbeállításra.</string>
|
||||
<string name="permissions.message_box_title">Figyelem</string>
|
||||
<string name="permissions.permission_missing">Az Ultrasonic működéséhez írás/olvasás hozzáférés szükséges a zenei fájl gyorsítótárhoz. A gyorsítótár helye visszaállítva az alapbeállításra.</string>
|
||||
|
@ -397,6 +397,12 @@
|
||||
<string name="settings.image_loader_concurrency_12">12</string>
|
||||
<string name="albumArt">Albumhoes</string>
|
||||
<string name="common_multiple_years">Meerdere jaren</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Resume when a Bluetooth device is connected</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Pause when a Bluetooth device is disconnected</string>
|
||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||
|
||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||
<string name="permissions.message_box_title">Warning</string>
|
||||
<string name="permissions.permission_missing">Ultrasonic needs read/write permission to the music cache directory. Cache directory was reset to its default value.</string>
|
||||
|
@ -397,6 +397,12 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników
|
||||
<string name="settings.image_loader_concurrency_12">12</string>
|
||||
<string name="albumArt">Okładka</string>
|
||||
<string name="common_multiple_years">Z różnych lat</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Resume when a Bluetooth device is connected</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Pause when a Bluetooth device is disconnected</string>
|
||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||
|
||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||
<string name="permissions.message_box_title">Warning</string>
|
||||
<string name="permissions.permission_missing">Ultrasonic needs read/write permission to the music cache directory. Cache directory was reset to its default value.</string>
|
||||
|
@ -397,6 +397,12 @@
|
||||
<string name="settings.image_loader_concurrency_12">12</string>
|
||||
<string name="albumArt">albumArt</string>
|
||||
<string name="common_multiple_years">Múltiplos Anos</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Resume when a Bluetooth device is connected</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Pause when a Bluetooth device is disconnected</string>
|
||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||
|
||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||
<string name="permissions.message_box_title">Warning</string>
|
||||
<string name="permissions.permission_missing">Ultrasonic needs read/write permission to the music cache directory. Cache directory was reset to its default value.</string>
|
||||
|
@ -397,6 +397,12 @@
|
||||
<string name="settings.image_loader_concurrency_12">12</string>
|
||||
<string name="albumArt">albumArt</string>
|
||||
<string name="common_multiple_years">Múltiplos Anos</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Resume when a Bluetooth device is connected</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Pause when a Bluetooth device is disconnected</string>
|
||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||
|
||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||
<string name="permissions.message_box_title">Warning</string>
|
||||
<string name="permissions.permission_missing">Ultrasonic needs read/write permission to the music cache directory. Cache directory was reset to its default value.</string>
|
||||
|
@ -291,5 +291,10 @@
|
||||
<item>11</item>
|
||||
<item>12</item>
|
||||
</string-array>
|
||||
<string-array name="bluetoothDeviceSettingNames" translatable="false">
|
||||
<item>@string/settings.playback.bluetooth_all</item>
|
||||
<item>@string/settings.playback.bluetooth_a2dp</item>
|
||||
<item>@string/settings.playback.bluetooth_disabled</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
@ -254,7 +254,7 @@
|
||||
<string name="settings.preload_5">5 songs</string>
|
||||
<string name="settings.preload_unlimited">Unlimited</string>
|
||||
<string name="settings.playback.resume_play_on_headphones_plug.title">Resume on headphones insertion</string>
|
||||
<string name="settings.playback.resume_play_on_headphones_plug.summary">App will resume paused playback on headphones insertion into device.</string>
|
||||
<string name="settings.playback.resume_play_on_headphones_plug.summary">App will resume paused playback on wired headphones insertion into device.</string>
|
||||
<string name="settings.screen_lit_summary">Keeping the screen on while downloading improves download speed.</string>
|
||||
<string name="settings.screen_lit_title">Keep Screen On</string>
|
||||
<string name="settings.scrobble_summary">Remember to set up your Last.fm user and password on the Subsonic server</string>
|
||||
@ -400,6 +400,11 @@
|
||||
<string name="albumArt">albumArt</string>
|
||||
<string name="common_multiple_years">Multiple Years</string>
|
||||
<string name="settings.server_address_unset" translatable="false">http://example.com</string>
|
||||
<string name="settings.playback.resume_on_bluetooth_device">Resume when a Bluetooth device is connected</string>
|
||||
<string name="settings.playback.pause_on_bluetooth_device">Pause when a Bluetooth device is disconnected</string>
|
||||
<string name="settings.playback.bluetooth_all">All Bluetooth devices</string>
|
||||
<string name="settings.playback.bluetooth_a2dp">Only audio (A2DP) devices</string>
|
||||
<string name="settings.playback.bluetooth_disabled">Disabled</string>
|
||||
|
||||
<string name="permissions.access_error">Ultrasonic can\'t access the music file cache. Cache location was reset to the default path.</string>
|
||||
<string name="permissions.message_box_title">Warning</string>
|
||||
|
@ -106,6 +106,12 @@
|
||||
a:title="@string/settings.playback.resume_play_on_headphones_plug.title"
|
||||
a:summary="@string/settings.playback.resume_play_on_headphones_plug.summary"
|
||||
/>
|
||||
<Preference
|
||||
a:key="resumeOnBluetoothDevice"
|
||||
a:title="@string/settings.playback.resume_on_bluetooth_device"/>
|
||||
<Preference
|
||||
a:key="pauseOnBluetoothDevice"
|
||||
a:title="@string/settings.playback.pause_on_bluetooth_device"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
a:title="@string/settings.notifications_title"
|
||||
|
Loading…
x
Reference in New Issue
Block a user