mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-30 23:51:32 +03:00
Fixed audio focus handling
This commit is contained in:
parent
aae40c076e
commit
3d61dde83f
@ -0,0 +1,90 @@
|
|||||||
|
package org.moire.ultrasonic.service;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.moire.ultrasonic.domain.PlayerState;
|
||||||
|
import org.moire.ultrasonic.util.Constants;
|
||||||
|
import org.moire.ultrasonic.util.Util;
|
||||||
|
|
||||||
|
import kotlin.Lazy;
|
||||||
|
|
||||||
|
import static org.koin.java.standalone.KoinJavaComponent.inject;
|
||||||
|
|
||||||
|
public class AudioFocusHandler
|
||||||
|
{
|
||||||
|
private static final String TAG = AudioFocusHandler.class.getSimpleName();
|
||||||
|
|
||||||
|
private static boolean hasFocus;
|
||||||
|
private static boolean pauseFocus;
|
||||||
|
private static boolean lowerFocus;
|
||||||
|
|
||||||
|
// TODO: This is a circular reference, try to remove it
|
||||||
|
private Lazy<MediaPlayerController> mediaPlayerControllerLazy = inject(MediaPlayerController.class);
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public AudioFocusHandler(Context context)
|
||||||
|
{
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestAudioFocus()
|
||||||
|
{
|
||||||
|
if (!hasFocus)
|
||||||
|
{
|
||||||
|
final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
|
hasFocus = true;
|
||||||
|
audioManager.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onAudioFocusChange(int focusChange)
|
||||||
|
{
|
||||||
|
MediaPlayerController mediaPlayerController = mediaPlayerControllerLazy.getValue();
|
||||||
|
if ((focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) && !mediaPlayerController.isJukeboxEnabled())
|
||||||
|
{
|
||||||
|
Log.v(TAG, "Lost Audio Focus");
|
||||||
|
if (mediaPlayerController.getPlayerState() == PlayerState.STARTED)
|
||||||
|
{
|
||||||
|
SharedPreferences preferences = Util.getPreferences(context);
|
||||||
|
int lossPref = Integer.parseInt(preferences.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1"));
|
||||||
|
if (lossPref == 2 || (lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK))
|
||||||
|
{
|
||||||
|
lowerFocus = true;
|
||||||
|
mediaPlayerController.setVolume(0.1f);
|
||||||
|
}
|
||||||
|
else if (lossPref == 0 || (lossPref == 1))
|
||||||
|
{
|
||||||
|
pauseFocus = true;
|
||||||
|
mediaPlayerController.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (focusChange == AudioManager.AUDIOFOCUS_GAIN)
|
||||||
|
{
|
||||||
|
Log.v(TAG, "Regained Audio Focus");
|
||||||
|
if (pauseFocus)
|
||||||
|
{
|
||||||
|
pauseFocus = false;
|
||||||
|
mediaPlayerController.start();
|
||||||
|
}
|
||||||
|
else if (lowerFocus)
|
||||||
|
{
|
||||||
|
lowerFocus = false;
|
||||||
|
mediaPlayerController.setVolume(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (focusChange == AudioManager.AUDIOFOCUS_LOSS && !mediaPlayerController.isJukeboxEnabled())
|
||||||
|
{
|
||||||
|
hasFocus = false;
|
||||||
|
mediaPlayerController.pause();
|
||||||
|
audioManager.abandonAudioFocus(this);
|
||||||
|
Log.v(TAG, "Abandoned Audio Focus");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
|
||||||
|
Log.v(TAG, "Got Audio Focus");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -84,6 +84,7 @@ public class LocalMediaPlayer
|
|||||||
private PositionCache positionCache;
|
private PositionCache positionCache;
|
||||||
private int secondaryProgress = -1;
|
private int secondaryProgress = -1;
|
||||||
|
|
||||||
|
private final AudioFocusHandler audioFocusHandler;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -112,8 +113,9 @@ public class LocalMediaPlayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalMediaPlayer(Context context)
|
public LocalMediaPlayer(AudioFocusHandler audioFocusHandler, Context context)
|
||||||
{
|
{
|
||||||
|
this.audioFocusHandler = audioFocusHandler;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,9 +242,9 @@ public class LocalMediaPlayer
|
|||||||
Util.unregisterMediaButtonEventReceiver(context, true);
|
Util.unregisterMediaButtonEventReceiver(context, true);
|
||||||
wakeLock.release();
|
wakeLock.release();
|
||||||
}
|
}
|
||||||
catch (Throwable ignored)
|
catch (Throwable exception)
|
||||||
{
|
{
|
||||||
Log.w(TAG, "LocalMediaPlayer onDestroy exception: ", ignored);
|
Log.w(TAG, "LocalMediaPlayer onDestroy exception: ", exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i(TAG, "LocalMediaPlayer destroyed");
|
Log.i(TAG, "LocalMediaPlayer destroyed");
|
||||||
@ -286,7 +288,7 @@ public class LocalMediaPlayer
|
|||||||
|
|
||||||
if (playerState == PlayerState.STARTED)
|
if (playerState == PlayerState.STARTED)
|
||||||
{
|
{
|
||||||
Util.requestAudioFocus(context);
|
audioFocusHandler.requestAudioFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED)
|
if (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED)
|
||||||
|
@ -92,10 +92,6 @@ public class Util extends DownloadActivity
|
|||||||
public static final String CM_AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged";
|
public static final String CM_AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged";
|
||||||
public static final String CM_AVRCP_METADATA_CHANGED = "com.android.music.metachanged";
|
public static final String CM_AVRCP_METADATA_CHANGED = "com.android.music.metachanged";
|
||||||
|
|
||||||
private static boolean hasFocus;
|
|
||||||
private static boolean pauseFocus;
|
|
||||||
private static boolean lowerFocus;
|
|
||||||
|
|
||||||
private static boolean mediaButtonsRegisteredForUI;
|
private static boolean mediaButtonsRegisteredForUI;
|
||||||
private static boolean mediaButtonsRegisteredForService;
|
private static boolean mediaButtonsRegisteredForService;
|
||||||
|
|
||||||
@ -1181,60 +1177,6 @@ public class Util extends DownloadActivity
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void requestAudioFocus(final Context context)
|
|
||||||
{
|
|
||||||
if (!hasFocus)
|
|
||||||
{
|
|
||||||
final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
|
||||||
hasFocus = true;
|
|
||||||
audioManager.requestAudioFocus(new OnAudioFocusChangeListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onAudioFocusChange(int focusChange)
|
|
||||||
{
|
|
||||||
MediaPlayerController mediaPlayerController = (MediaPlayerController) context;
|
|
||||||
if ((focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) && !mediaPlayerController.isJukeboxEnabled())
|
|
||||||
{
|
|
||||||
if (mediaPlayerController.getPlayerState() == PlayerState.STARTED)
|
|
||||||
{
|
|
||||||
SharedPreferences preferences = getPreferences(context);
|
|
||||||
int lossPref = Integer.parseInt(preferences.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1"));
|
|
||||||
if (lossPref == 2 || (lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK))
|
|
||||||
{
|
|
||||||
lowerFocus = true;
|
|
||||||
mediaPlayerController.setVolume(0.1f);
|
|
||||||
}
|
|
||||||
else if (lossPref == 0 || (lossPref == 1))
|
|
||||||
{
|
|
||||||
pauseFocus = true;
|
|
||||||
mediaPlayerController.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (focusChange == AudioManager.AUDIOFOCUS_GAIN)
|
|
||||||
{
|
|
||||||
if (pauseFocus)
|
|
||||||
{
|
|
||||||
pauseFocus = false;
|
|
||||||
mediaPlayerController.start();
|
|
||||||
}
|
|
||||||
else if (lowerFocus)
|
|
||||||
{
|
|
||||||
lowerFocus = false;
|
|
||||||
mediaPlayerController.setVolume(1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (focusChange == AudioManager.AUDIOFOCUS_LOSS && !mediaPlayerController.isJukeboxEnabled())
|
|
||||||
{
|
|
||||||
hasFocus = false;
|
|
||||||
mediaPlayerController.pause();
|
|
||||||
audioManager.abandonAudioFocus(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getMinDisplayMetric(Context context)
|
public static int getMinDisplayMetric(Context context)
|
||||||
{
|
{
|
||||||
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
|
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
|
||||||
|
@ -10,6 +10,7 @@ import org.moire.ultrasonic.service.LocalMediaPlayer
|
|||||||
import org.moire.ultrasonic.service.MediaPlayerController
|
import org.moire.ultrasonic.service.MediaPlayerController
|
||||||
import org.moire.ultrasonic.service.MediaPlayerControllerImpl
|
import org.moire.ultrasonic.service.MediaPlayerControllerImpl
|
||||||
import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport
|
import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport
|
||||||
|
import org.moire.ultrasonic.service.AudioFocusHandler
|
||||||
import org.moire.ultrasonic.util.ShufflePlayBuffer
|
import org.moire.ultrasonic.util.ShufflePlayBuffer
|
||||||
|
|
||||||
val mediaPlayerModule = module {
|
val mediaPlayerModule = module {
|
||||||
@ -23,7 +24,8 @@ val mediaPlayerModule = module {
|
|||||||
single { ExternalStorageMonitor(androidContext()) }
|
single { ExternalStorageMonitor(androidContext()) }
|
||||||
single { ShufflePlayBuffer(androidContext()) }
|
single { ShufflePlayBuffer(androidContext()) }
|
||||||
single { Downloader(androidContext(), get(), get(), get()) }
|
single { Downloader(androidContext(), get(), get(), get()) }
|
||||||
single { LocalMediaPlayer(androidContext()) }
|
single { LocalMediaPlayer(get(), androidContext()) }
|
||||||
|
single { AudioFocusHandler(get()) }
|
||||||
|
|
||||||
// TODO Ideally this can be cleaned up when all circular references are removed.
|
// TODO Ideally this can be cleaned up when all circular references are removed.
|
||||||
single { MediaPlayerControllerImpl(androidContext(), get(), get(), get(), get(), get()) }
|
single { MediaPlayerControllerImpl(androidContext(), get(), get(), get(), get(), get()) }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user