2 * Copyright 2017 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.moiseum.wolnelektury.view.player.service;
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.media.AudioManager;
24 import android.support.annotation.NonNull;
25 import android.support.v4.media.MediaMetadataCompat;
28 * Abstract player implementation that handles playing music with proper handling of headphones
31 public abstract class PlayerAdapter {
33 private static final float MEDIA_VOLUME_DEFAULT = 1.0f;
34 private static final float MEDIA_VOLUME_DUCK = 0.2f;
36 private static final IntentFilter AUDIO_NOISY_INTENT_FILTER =
37 new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
39 private boolean mAudioNoisyReceiverRegistered = false;
40 private final BroadcastReceiver mAudioNoisyReceiver =
41 new BroadcastReceiver() {
43 public void onReceive(Context context, Intent intent) {
44 if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
52 private final Context mApplicationContext;
53 private final AudioManager mAudioManager;
54 private final AudioFocusHelper mAudioFocusHelper;
56 private boolean mPlayOnAudioFocus = false;
58 public PlayerAdapter(@NonNull Context context) {
59 mApplicationContext = context.getApplicationContext();
60 mAudioManager = (AudioManager) mApplicationContext.getSystemService(Context.AUDIO_SERVICE);
61 mAudioFocusHelper = new AudioFocusHelper();
64 public abstract void playFromMedia(MediaMetadataCompat metadata);
66 public abstract MediaMetadataCompat getCurrentMedia();
68 public abstract boolean isPlaying();
70 public final void play() {
71 if (mAudioFocusHelper.requestAudioFocus()) {
72 registerAudioNoisyReceiver();
78 * Called when media is ready to be played and indicates the app has audio focus.
80 protected abstract void onPlay();
82 public final void pause() {
83 if (!mPlayOnAudioFocus) {
84 mAudioFocusHelper.abandonAudioFocus();
87 unregisterAudioNoisyReceiver();
92 * Called when media must be paused.
94 protected abstract void onPause();
96 public final void stop() {
97 mAudioFocusHelper.abandonAudioFocus();
98 unregisterAudioNoisyReceiver();
103 * Called when the media must be stopped. The player should clean up resources at this
106 protected abstract void onStop();
108 public abstract void seekTo(long position);
110 public abstract void fastForward();
112 public abstract void rewind();
114 public abstract void setVolume(float volume);
116 private void registerAudioNoisyReceiver() {
117 if (!mAudioNoisyReceiverRegistered) {
118 mApplicationContext.registerReceiver(mAudioNoisyReceiver, AUDIO_NOISY_INTENT_FILTER);
119 mAudioNoisyReceiverRegistered = true;
123 private void unregisterAudioNoisyReceiver() {
124 if (mAudioNoisyReceiverRegistered) {
125 mApplicationContext.unregisterReceiver(mAudioNoisyReceiver);
126 mAudioNoisyReceiverRegistered = false;
131 * Helper class for managing audio focus related tasks.
133 private final class AudioFocusHelper
134 implements AudioManager.OnAudioFocusChangeListener {
136 private boolean requestAudioFocus() {
137 final int result = mAudioManager.requestAudioFocus(this,
138 AudioManager.STREAM_MUSIC,
139 AudioManager.AUDIOFOCUS_GAIN);
140 return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
143 private void abandonAudioFocus() {
144 mAudioManager.abandonAudioFocus(this);
148 public void onAudioFocusChange(int focusChange) {
149 switch (focusChange) {
150 case AudioManager.AUDIOFOCUS_GAIN:
151 if (mPlayOnAudioFocus && !isPlaying()) {
153 } else if (isPlaying()) {
154 setVolume(MEDIA_VOLUME_DEFAULT);
156 mPlayOnAudioFocus = false;
158 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
159 setVolume(MEDIA_VOLUME_DUCK);
161 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
163 mPlayOnAudioFocus = true;
167 case AudioManager.AUDIOFOCUS_LOSS:
168 mAudioManager.abandonAudioFocus(this);
169 mPlayOnAudioFocus = false;