diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 23da927..29c2ef1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -71,13 +71,6 @@
-
-
-
-
-
-
-
diff --git a/app/src/main/java/org/xbmc/kore/Settings.java b/app/src/main/java/org/xbmc/kore/Settings.java
index c76bb23..d83bab0 100644
--- a/app/src/main/java/org/xbmc/kore/Settings.java
+++ b/app/src/main/java/org/xbmc/kore/Settings.java
@@ -55,7 +55,7 @@ public class Settings {
// Pause during calls
public static final String KEY_PREF_PAUSE_DURING_CALLS = "pref_pause_during_calls";
- public static final boolean DEFAULT_PREF_PAUSE_DURING_CALLS = true;
+ public static final boolean DEFAULT_PREF_PAUSE_DURING_CALLS = false;
// Other keys used in preferences.xml
public static final String KEY_PREF_ABOUT = "pref_about";
diff --git a/app/src/main/java/org/xbmc/kore/service/PauseCallService.java b/app/src/main/java/org/xbmc/kore/service/PauseCallService.java
index 0253546..8ecf548 100644
--- a/app/src/main/java/org/xbmc/kore/service/PauseCallService.java
+++ b/app/src/main/java/org/xbmc/kore/service/PauseCallService.java
@@ -15,14 +15,11 @@
*/
package org.xbmc.kore.service;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.preference.PreferenceManager;
+import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import org.xbmc.kore.R;
-import org.xbmc.kore.Settings;
import org.xbmc.kore.host.HostConnectionObserver;
import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.jsonrpc.method.Player;
@@ -31,77 +28,42 @@ import org.xbmc.kore.jsonrpc.type.PlayerType;
import org.xbmc.kore.utils.LogUtils;
/**
- * This service maintains a notification in the notification area while
- * something is playing, and keeps running while it is playing.
- * This service stops itself as soon as the playing stops or there's no
- * connection. Thus, this should only be started if something is already
- * playing, otherwise it will shutdown automatically.
- * It doesn't try to mirror Kodi's state at all times, because that would
- * imply running at all times which can be resource consuming.
+ * This listener handles changes to the phone state, such as receiving a
+ * call or hanging up, and synchronizes Kodi's currently playing state
+ * in order to prevent missing the movie (or what's playing) while the
+ * viewer is talking on the phone.
*
- * A {@link HostConnectionObserver} singleton is used to keep track of Kodi's
- * state. This singleton should be the same as used in the app's activities
+ * The listener query Kodi's state on phone state changed event.
+ * When a call ends we only resume if it was paused by the listener.
*/
-public class PauseCallService extends BroadcastReceiver
+public class PauseCallService extends PhoneStateListener
implements HostConnectionObserver.PlayerEventsObserver {
public static final String TAG = LogUtils.makeLogTag(PauseCallService.class);
- private static int lastState = TelephonyManager.CALL_STATE_IDLE;
- private static HostConnectionObserver mHostConnectionObserver = null;
- private static int currentActivePlayerId = -1;
- private static boolean isPlaying = false;
- private static boolean shouldResume = false;
+ private Context context;
+ private int currentActivePlayerId = -1;
+ private boolean isPlaying = false;
+ private boolean shouldResume = false;
- @Override
- public void onReceive(Context context, Intent intent) {
- // Check whether we should react to phone state changes
- boolean shouldPause = PreferenceManager
- .getDefaultSharedPreferences(context)
- .getBoolean(Settings.KEY_PREF_PAUSE_DURING_CALLS, Settings.DEFAULT_PREF_PAUSE_DURING_CALLS);
- if(!shouldPause) return;
-
- int state = 0;
- String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
- LogUtils.LOGD(TAG, "onReceive " + stateStr);
-
- // The phone state changed from in call to idle
- if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
- state = TelephonyManager.CALL_STATE_IDLE;
- }
- // The phone state changed from idle to in call
- else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
- state = TelephonyManager.CALL_STATE_OFFHOOK;
- }
- // The phone state changed from idle to ringing
- else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
- state = TelephonyManager.CALL_STATE_RINGING;
- }
-
- if(state == lastState) return;
- handleState(context, state);
- lastState = state;
+ public PauseCallService(Context context) {
+ this.context = context;
}
- protected void handleState(Context context, int state) {
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
// We won't create a new thread because the request to the host are
// already done in a separate thread. Just fire the request and forget
HostManager hostManager = HostManager.getInstance(context);
- if (mHostConnectionObserver != null) {
- mHostConnectionObserver.unregisterPlayerObserver(this);
- }
- mHostConnectionObserver = hostManager.getHostConnectionObserver();
- mHostConnectionObserver.registerPlayerObserver(this, true);
+ hostManager.getHostConnectionObserver().replyWithLastResult(this);
- if(state == TelephonyManager.CALL_STATE_OFFHOOK && isPlaying) {
+ if (state == TelephonyManager.CALL_STATE_OFFHOOK && isPlaying) {
Player.PlayPause action = new Player.PlayPause(currentActivePlayerId);
action.execute(hostManager.getConnection(), null, null);
shouldResume = true;
- }
- else if(state == TelephonyManager.CALL_STATE_IDLE && !isPlaying && shouldResume) {
+ } else if (state == TelephonyManager.CALL_STATE_IDLE && !isPlaying && shouldResume) {
Player.PlayPause action = new Player.PlayPause(currentActivePlayerId);
action.execute(hostManager.getConnection(), null, null);
shouldResume = false;
- }
- else if(state == TelephonyManager.CALL_STATE_RINGING) {
+ } else if (state == TelephonyManager.CALL_STATE_RINGING) {
Player.Notification action = new Player.Notification(
context.getResources().getString(R.string.pause_call_incoming_title),
context.getResources().getString(R.string.pause_call_incoming_message));
@@ -121,17 +83,18 @@ public class PauseCallService extends BroadcastReceiver
public void playerOnPause(PlayerType.GetActivePlayersReturnType getActivePlayerResult,
PlayerType.PropertyValue getPropertiesResult,
ListType.ItemsAll getItemResult) {
+ if(currentActivePlayerId != getActivePlayerResult.playerid) {
+ shouldResume = false;
+ }
currentActivePlayerId = getActivePlayerResult.playerid;
isPlaying = false;
}
@Override
public void playerOnStop() {
- if (mHostConnectionObserver != null) {
- mHostConnectionObserver.unregisterPlayerObserver(this);
- }
currentActivePlayerId = -1;
isPlaying = false;
+ shouldResume = false;
}
@Override
@@ -140,13 +103,13 @@ public class PauseCallService extends BroadcastReceiver
}
@Override
- public void playerNoResultsYet() {}
-
- @Override
- public void systemOnQuit() {
+ public void playerNoResultsYet() {
playerOnStop();
}
+ @Override
+ public void systemOnQuit() {}
+
@Override
public void inputOnInputRequested(String title, String type, String value) {}
diff --git a/app/src/main/java/org/xbmc/kore/ui/RemoteActivity.java b/app/src/main/java/org/xbmc/kore/ui/RemoteActivity.java
index acbf2d4..86dac3c 100644
--- a/app/src/main/java/org/xbmc/kore/ui/RemoteActivity.java
+++ b/app/src/main/java/org/xbmc/kore/ui/RemoteActivity.java
@@ -15,6 +15,7 @@
*/
package org.xbmc.kore.ui;
+import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Point;
@@ -26,6 +27,8 @@ import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.Menu;
@@ -53,6 +56,7 @@ import org.xbmc.kore.jsonrpc.type.ListType;
import org.xbmc.kore.jsonrpc.type.PlayerType;
import org.xbmc.kore.jsonrpc.type.PlaylistType;
import org.xbmc.kore.service.NotificationService;
+import org.xbmc.kore.service.PauseCallService;
import org.xbmc.kore.ui.hosts.AddHostActivity;
import org.xbmc.kore.ui.hosts.AddHostFragmentFinish;
import org.xbmc.kore.ui.views.CirclePageIndicator;
@@ -88,6 +92,8 @@ public class RemoteActivity extends BaseActivity
private NavigationDrawerFragment navigationDrawerFragment;
+ private PauseCallService pauseCallService = null;
+
@InjectView(R.id.background_image) ImageView backgroundImage;
@InjectView(R.id.pager_indicator) CirclePageIndicator pageIndicator;
@InjectView(R.id.pager) ViewPager viewPager;
@@ -614,12 +620,28 @@ public class RemoteActivity extends BaseActivity
// Check whether we should show a notification
boolean showNotification = PreferenceManager
.getDefaultSharedPreferences(this)
- .getBoolean(Settings.KEY_PREF_SHOW_NOTIFICATION, Settings.DEFAULT_PREF_SHOW_NOTIFICATION);
+ .getBoolean(Settings.KEY_PREF_SHOW_NOTIFICATION,
+ Settings.DEFAULT_PREF_SHOW_NOTIFICATION);
if (showNotification) {
// Let's start the notification service
LogUtils.LOGD(TAG, "Starting notification service");
startService(new Intent(this, NotificationService.class));
}
+
+ // Check whether we should react to phone state changes
+ boolean shouldPause = PreferenceManager
+ .getDefaultSharedPreferences(this)
+ .getBoolean(Settings.KEY_PREF_USE_HARDWARE_VOLUME_KEYS,
+ Settings.DEFAULT_PREF_USE_HARDWARE_VOLUME_KEYS);
+ if (shouldPause) {
+ // Let's start the notification service
+ LogUtils.LOGD(TAG, "Starting phone state listener");
+ if(pauseCallService == null) {
+ pauseCallService = new PauseCallService(this);
+ ((TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE)).listen(
+ pauseCallService, PhoneStateListener.LISTEN_CALL_STATE);
+ }
+ }
}
public void playerOnPause(PlayerType.GetActivePlayersReturnType getActivePlayerResult,
@@ -633,6 +655,12 @@ public class RemoteActivity extends BaseActivity
setImageViewBackground(null);
}
lastImageUrl = null;
+
+ if(pauseCallService != null) {
+ ((TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE)).listen(
+ pauseCallService, PhoneStateListener.LISTEN_NONE);
+ pauseCallService = null;
+ }
}
public void playerNoResultsYet() {
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index eac38d4..80b9b0c 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -37,7 +37,7 @@
+ android:defaultValue="false"/>