Option to ignore permanent audio focus loss
This commit is contained in:
parent
3265f119b2
commit
b42e923675
@ -40,4 +40,16 @@ THE SOFTWARE.
|
||||
android:paddingRight="20dip"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<CheckBox android:id="@+id/check_box"
|
||||
android:visibility="gone"
|
||||
android:paddingTop="10dip"
|
||||
android:paddingBottom="10dip"
|
||||
android:layout_marginLeft="12dip"
|
||||
android:paddingRight="20dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -8,5 +8,7 @@
|
||||
<attr name="sbpSummaryText" format="string"/>
|
||||
<attr name="sbpSummaryFormat" format="string"/>
|
||||
<attr name="sbpSummaryZeroText" format="string" />
|
||||
<attr name="sbpCheckBoxText" format="string" />
|
||||
<attr name="sbpCheckBoxKey" format="string" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
@ -154,6 +154,7 @@ THE SOFTWARE.
|
||||
<string name="volume_title">Volume</string>
|
||||
<string name="volume_during_ducking_title">Volume during notification</string>
|
||||
<string name="volume_during_ducking_summary">Playback volume: </string>
|
||||
<string name="ignore_audiofocus_loss_summary">Keep playing on permanent audio focus loss</string>
|
||||
<string name="media_button_title">Headset/Bluetooth controls</string>
|
||||
<string name="media_button_summary">This is also required for ICS lockscreen controls.</string>
|
||||
<string name="media_button_beep_title">Headset control beep</string>
|
||||
|
@ -39,7 +39,10 @@ THE SOFTWARE.
|
||||
android:defaultValue="50"
|
||||
vanilla:sbpSummaryText="@string/volume_during_ducking_summary"
|
||||
vanilla:sbpSummaryFormat="%s %.0f%%"
|
||||
vanilla:sbpMaxValue="100"/>
|
||||
vanilla:sbpMaxValue="100"
|
||||
vanilla:sbpCheckBoxKey="ignore_audiofocus_loss"
|
||||
vanilla:sbpCheckBoxText="@string/ignore_audiofocus_loss_summary"
|
||||
/>
|
||||
<CheckBoxPreference
|
||||
android:key="media_button"
|
||||
android:title="@string/media_button_title"
|
||||
|
@ -407,6 +407,10 @@ public final class PlaybackService extends Service
|
||||
* Percentage to set the volume as while a notification is playing (aka ducking)
|
||||
*/
|
||||
private int mVolumeDuringDucking;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private boolean mIgnoreAudioFocusLoss;
|
||||
/**
|
||||
* TRUE if the readahead feature is enabled
|
||||
*/
|
||||
@ -472,6 +476,7 @@ public final class PlaybackService extends Service
|
||||
mReplayGainUntaggedDeBump = settings.getInt(PrefKeys.REPLAYGAIN_UNTAGGED_DEBUMP, PrefDefaults.REPLAYGAIN_UNTAGGED_DEBUMP);
|
||||
|
||||
mVolumeDuringDucking = settings.getInt(PrefKeys.VOLUME_DURING_DUCKING, PrefDefaults.VOLUME_DURING_DUCKING);
|
||||
mIgnoreAudioFocusLoss = settings.getBoolean(PrefKeys.IGNORE_AUDIOFOCUS_LOSS, PrefDefaults.IGNORE_AUDIOFOCUS_LOSS);
|
||||
refreshDuckingValues();
|
||||
|
||||
mReadaheadEnabled = settings.getBoolean(PrefKeys.ENABLE_READAHEAD, PrefDefaults.ENABLE_READAHEAD);
|
||||
@ -869,6 +874,8 @@ public final class PlaybackService extends Service
|
||||
} else if (PrefKeys.VOLUME_DURING_DUCKING.equals(key)) {
|
||||
mVolumeDuringDucking = settings.getInt(PrefKeys.VOLUME_DURING_DUCKING, PrefDefaults.VOLUME_DURING_DUCKING);
|
||||
refreshDuckingValues();
|
||||
} else if (PrefKeys.IGNORE_AUDIOFOCUS_LOSS.equals(key)) {
|
||||
mIgnoreAudioFocusLoss = settings.getBoolean(PrefKeys.IGNORE_AUDIOFOCUS_LOSS, PrefDefaults.IGNORE_AUDIOFOCUS_LOSS);
|
||||
} else if (PrefKeys.ENABLE_READAHEAD.equals(key)) {
|
||||
mReadaheadEnabled = settings.getBoolean(PrefKeys.ENABLE_READAHEAD, PrefDefaults.ENABLE_READAHEAD);
|
||||
} else if (PrefKeys.AUTOPLAYLIST_PLAYCOUNTS.equals(key)) {
|
||||
@ -1167,7 +1174,8 @@ public final class PlaybackService extends Service
|
||||
public int pause()
|
||||
{
|
||||
synchronized (mStateLock) {
|
||||
int state = updateState(mState & ~FLAG_PLAYING);
|
||||
mTransientAudioLoss = false; // do not resume playback as this pause was user initiated
|
||||
int state = updateState(mState & ~FLAG_PLAYING & ~FLAG_DUCKING);
|
||||
userActionTriggered();
|
||||
return state;
|
||||
}
|
||||
@ -1408,9 +1416,7 @@ public final class PlaybackService extends Service
|
||||
|
||||
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)) {
|
||||
if (mHeadsetPause) {
|
||||
unsetFlag(FLAG_PLAYING);
|
||||
// Treat any pending transient audio loss as permanent
|
||||
mTransientAudioLoss = false;
|
||||
pause();
|
||||
}
|
||||
} else if (Intent.ACTION_SCREEN_ON.equals(action)) {
|
||||
userActionTriggered();
|
||||
@ -2128,6 +2134,16 @@ public final class PlaybackService extends Service
|
||||
public void onAudioFocusChange(int type)
|
||||
{
|
||||
Log.d("VanillaMusic", "audio focus change: " + type);
|
||||
|
||||
// Rewrite permanent focus loss into can_duck
|
||||
if (mIgnoreAudioFocusLoss) {
|
||||
switch (type) {
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
||||
case AudioManager.AUDIOFOCUS_LOSS:
|
||||
type = AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
||||
|
@ -68,4 +68,5 @@ public class PrefDefaults {
|
||||
public static final String FILESYSTEM_BROWSE_START = "";
|
||||
public static final int VOLUME_DURING_DUCKING = 50;
|
||||
public static final int AUTOPLAYLIST_PLAYCOUNTS = 0;
|
||||
public static final boolean IGNORE_AUDIOFOCUS_LOSS = false;
|
||||
}
|
||||
|
@ -69,4 +69,5 @@ public class PrefKeys {
|
||||
public static final String FILESYSTEM_BROWSE_START = "filesystem_browse_start";
|
||||
public static final String VOLUME_DURING_DUCKING = "volume_during_ducking";
|
||||
public static final String AUTOPLAYLIST_PLAYCOUNTS = "playcounts_autoplaylist";
|
||||
public static final String IGNORE_AUDIOFOCUS_LOSS = "ignore_audiofocus_loss";
|
||||
}
|
||||
|
@ -24,10 +24,12 @@
|
||||
package ch.blinkenlights.android.vanilla;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.TypedArray;
|
||||
import android.preference.DialogPreference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -67,6 +69,14 @@ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSee
|
||||
* Text to display if the value equals zero
|
||||
*/
|
||||
private String mZeroText;
|
||||
/**
|
||||
* CheckBox preferences key, may be null
|
||||
*/
|
||||
private String mCheckBoxKey;
|
||||
/**
|
||||
* Label of checkbox
|
||||
*/
|
||||
private String mCheckBoxText;
|
||||
/**
|
||||
* Add given value to summary value
|
||||
*/
|
||||
@ -79,6 +89,10 @@ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSee
|
||||
* TextView to display current summary
|
||||
*/
|
||||
private TextView mValueText;
|
||||
/**
|
||||
* CheckBox to display, may be null
|
||||
*/
|
||||
private CheckBox mCheckBox;
|
||||
|
||||
public SeekBarPreference(Context context, AttributeSet attrs)
|
||||
{
|
||||
@ -104,7 +118,9 @@ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSee
|
||||
mSummaryFormat = (mSummaryFormat == null ? "%s %.1f" : mSummaryFormat);
|
||||
mSummaryText = a.getString(R.styleable.SeekBarPreference_sbpSummaryText);
|
||||
mSummaryText = (mSummaryText == null ? "" : mSummaryText);
|
||||
mZeroText = a.getString(R.styleable.SeekBarPreference_sbpSummaryZeroText); // unlike other strings, this may be null
|
||||
mZeroText = a.getString(R.styleable.SeekBarPreference_sbpSummaryZeroText); // unlike other strings, this may be null
|
||||
mCheckBoxKey = a.getString(R.styleable.SeekBarPreference_sbpCheckBoxKey); // non-null if checkbox enabled
|
||||
mCheckBoxText = a.getString(R.styleable.SeekBarPreference_sbpCheckBoxText);
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@ -163,6 +179,13 @@ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSee
|
||||
seekBar.setProgress(mValue);
|
||||
seekBar.setOnSeekBarChangeListener(this);
|
||||
|
||||
if (mCheckBoxKey != null) {
|
||||
mCheckBox = (CheckBox)view.findViewById(R.id.check_box);
|
||||
mCheckBox.setText(mCheckBoxText);
|
||||
mCheckBox.setChecked(getCheckBoxPreference());
|
||||
mCheckBox.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -170,6 +193,8 @@ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSee
|
||||
protected void onDialogClosed(boolean positiveResult) {
|
||||
if (positiveResult) {
|
||||
mInitialValue = mValue;
|
||||
if (mCheckBox != null)
|
||||
saveCheckBoxPreference(mCheckBox.isChecked());
|
||||
} else {
|
||||
// User aborted: Set remembered start value
|
||||
setValue(mInitialValue);
|
||||
@ -202,4 +227,16 @@ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSee
|
||||
mValueText.setText(getSummary(value));
|
||||
persistInt(value);
|
||||
}
|
||||
|
||||
private void saveCheckBoxPreference(boolean enabled) {
|
||||
SharedPreferences.Editor editor = PlaybackService.getSettings(mContext).edit();
|
||||
editor.putBoolean(mCheckBoxKey, enabled);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
private boolean getCheckBoxPreference() {
|
||||
SharedPreferences settings = PlaybackService.getSettings(mContext);
|
||||
return settings.getBoolean(mCheckBoxKey, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user