Changed PauseCallService from BroadcastReceiver to PhoneStateListener
This commit is contained in:
parent
2e7ac6af80
commit
e67516559d
|
@ -71,13 +71,6 @@
|
||||||
<service android:name="org.xbmc.kore.service.IntentActionsService"
|
<service android:name="org.xbmc.kore.service.IntentActionsService"
|
||||||
android:exported="false"/>
|
android:exported="false"/>
|
||||||
|
|
||||||
<!-- Receivers -->
|
|
||||||
<receiver android:name="org.xbmc.kore.service.PauseCallService">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.PHONE_STATE"/>
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
|
|
||||||
<uses-library android:required="false" android:name="com.sec.android.app.multiwindow"/>
|
<uses-library android:required="false" android:name="com.sec.android.app.multiwindow"/>
|
||||||
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
||||||
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632.0dip" />
|
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632.0dip" />
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class Settings {
|
||||||
|
|
||||||
// Pause during calls
|
// Pause during calls
|
||||||
public static final String KEY_PREF_PAUSE_DURING_CALLS = "pref_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
|
// Other keys used in preferences.xml
|
||||||
public static final String KEY_PREF_ABOUT = "pref_about";
|
public static final String KEY_PREF_ABOUT = "pref_about";
|
||||||
|
|
|
@ -15,14 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package org.xbmc.kore.service;
|
package org.xbmc.kore.service;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.telephony.PhoneStateListener;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
import org.xbmc.kore.R;
|
import org.xbmc.kore.R;
|
||||||
import org.xbmc.kore.Settings;
|
|
||||||
import org.xbmc.kore.host.HostConnectionObserver;
|
import org.xbmc.kore.host.HostConnectionObserver;
|
||||||
import org.xbmc.kore.host.HostManager;
|
import org.xbmc.kore.host.HostManager;
|
||||||
import org.xbmc.kore.jsonrpc.method.Player;
|
import org.xbmc.kore.jsonrpc.method.Player;
|
||||||
|
@ -31,77 +28,42 @@ import org.xbmc.kore.jsonrpc.type.PlayerType;
|
||||||
import org.xbmc.kore.utils.LogUtils;
|
import org.xbmc.kore.utils.LogUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service maintains a notification in the notification area while
|
* This listener handles changes to the phone state, such as receiving a
|
||||||
* something is playing, and keeps running while it is playing.
|
* call or hanging up, and synchronizes Kodi's currently playing state
|
||||||
* This service stops itself as soon as the playing stops or there's no
|
* in order to prevent missing the movie (or what's playing) while the
|
||||||
* connection. Thus, this should only be started if something is already
|
* viewer is talking on the phone.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* A {@link HostConnectionObserver} singleton is used to keep track of Kodi's
|
* The listener query Kodi's state on phone state changed event.
|
||||||
* state. This singleton should be the same as used in the app's activities
|
* 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 {
|
implements HostConnectionObserver.PlayerEventsObserver {
|
||||||
public static final String TAG = LogUtils.makeLogTag(PauseCallService.class);
|
public static final String TAG = LogUtils.makeLogTag(PauseCallService.class);
|
||||||
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
|
private Context context;
|
||||||
private static HostConnectionObserver mHostConnectionObserver = null;
|
private int currentActivePlayerId = -1;
|
||||||
private static int currentActivePlayerId = -1;
|
private boolean isPlaying = false;
|
||||||
private static boolean isPlaying = false;
|
private boolean shouldResume = false;
|
||||||
private static boolean shouldResume = false;
|
|
||||||
|
|
||||||
@Override
|
public PauseCallService(Context context) {
|
||||||
public void onReceive(Context context, Intent intent) {
|
this.context = context;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// 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
|
// already done in a separate thread. Just fire the request and forget
|
||||||
HostManager hostManager = HostManager.getInstance(context);
|
HostManager hostManager = HostManager.getInstance(context);
|
||||||
if (mHostConnectionObserver != null) {
|
hostManager.getHostConnectionObserver().replyWithLastResult(this);
|
||||||
mHostConnectionObserver.unregisterPlayerObserver(this);
|
|
||||||
}
|
|
||||||
mHostConnectionObserver = hostManager.getHostConnectionObserver();
|
|
||||||
mHostConnectionObserver.registerPlayerObserver(this, true);
|
|
||||||
|
|
||||||
if(state == TelephonyManager.CALL_STATE_OFFHOOK && isPlaying) {
|
if (state == TelephonyManager.CALL_STATE_OFFHOOK && isPlaying) {
|
||||||
Player.PlayPause action = new Player.PlayPause(currentActivePlayerId);
|
Player.PlayPause action = new Player.PlayPause(currentActivePlayerId);
|
||||||
action.execute(hostManager.getConnection(), null, null);
|
action.execute(hostManager.getConnection(), null, null);
|
||||||
shouldResume = true;
|
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);
|
Player.PlayPause action = new Player.PlayPause(currentActivePlayerId);
|
||||||
action.execute(hostManager.getConnection(), null, null);
|
action.execute(hostManager.getConnection(), null, null);
|
||||||
shouldResume = false;
|
shouldResume = false;
|
||||||
}
|
} else if (state == TelephonyManager.CALL_STATE_RINGING) {
|
||||||
else if(state == TelephonyManager.CALL_STATE_RINGING) {
|
|
||||||
Player.Notification action = new Player.Notification(
|
Player.Notification action = new Player.Notification(
|
||||||
context.getResources().getString(R.string.pause_call_incoming_title),
|
context.getResources().getString(R.string.pause_call_incoming_title),
|
||||||
context.getResources().getString(R.string.pause_call_incoming_message));
|
context.getResources().getString(R.string.pause_call_incoming_message));
|
||||||
|
@ -121,17 +83,18 @@ public class PauseCallService extends BroadcastReceiver
|
||||||
public void playerOnPause(PlayerType.GetActivePlayersReturnType getActivePlayerResult,
|
public void playerOnPause(PlayerType.GetActivePlayersReturnType getActivePlayerResult,
|
||||||
PlayerType.PropertyValue getPropertiesResult,
|
PlayerType.PropertyValue getPropertiesResult,
|
||||||
ListType.ItemsAll getItemResult) {
|
ListType.ItemsAll getItemResult) {
|
||||||
|
if(currentActivePlayerId != getActivePlayerResult.playerid) {
|
||||||
|
shouldResume = false;
|
||||||
|
}
|
||||||
currentActivePlayerId = getActivePlayerResult.playerid;
|
currentActivePlayerId = getActivePlayerResult.playerid;
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playerOnStop() {
|
public void playerOnStop() {
|
||||||
if (mHostConnectionObserver != null) {
|
|
||||||
mHostConnectionObserver.unregisterPlayerObserver(this);
|
|
||||||
}
|
|
||||||
currentActivePlayerId = -1;
|
currentActivePlayerId = -1;
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
|
shouldResume = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -140,13 +103,13 @@ public class PauseCallService extends BroadcastReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playerNoResultsYet() {}
|
public void playerNoResultsYet() {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void systemOnQuit() {
|
|
||||||
playerOnStop();
|
playerOnStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void systemOnQuit() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inputOnInputRequested(String title, String type, String value) {}
|
public void inputOnInputRequested(String title, String type, String value) {}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.xbmc.kore.ui;
|
package org.xbmc.kore.ui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
|
@ -26,6 +27,8 @@ import android.support.v4.view.ViewPager;
|
||||||
import android.support.v4.widget.DrawerLayout;
|
import android.support.v4.widget.DrawerLayout;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.telephony.PhoneStateListener;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
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.PlayerType;
|
||||||
import org.xbmc.kore.jsonrpc.type.PlaylistType;
|
import org.xbmc.kore.jsonrpc.type.PlaylistType;
|
||||||
import org.xbmc.kore.service.NotificationService;
|
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.AddHostActivity;
|
||||||
import org.xbmc.kore.ui.hosts.AddHostFragmentFinish;
|
import org.xbmc.kore.ui.hosts.AddHostFragmentFinish;
|
||||||
import org.xbmc.kore.ui.views.CirclePageIndicator;
|
import org.xbmc.kore.ui.views.CirclePageIndicator;
|
||||||
|
@ -88,6 +92,8 @@ public class RemoteActivity extends BaseActivity
|
||||||
|
|
||||||
private NavigationDrawerFragment navigationDrawerFragment;
|
private NavigationDrawerFragment navigationDrawerFragment;
|
||||||
|
|
||||||
|
private PauseCallService pauseCallService = null;
|
||||||
|
|
||||||
@InjectView(R.id.background_image) ImageView backgroundImage;
|
@InjectView(R.id.background_image) ImageView backgroundImage;
|
||||||
@InjectView(R.id.pager_indicator) CirclePageIndicator pageIndicator;
|
@InjectView(R.id.pager_indicator) CirclePageIndicator pageIndicator;
|
||||||
@InjectView(R.id.pager) ViewPager viewPager;
|
@InjectView(R.id.pager) ViewPager viewPager;
|
||||||
|
@ -614,12 +620,28 @@ public class RemoteActivity extends BaseActivity
|
||||||
// Check whether we should show a notification
|
// Check whether we should show a notification
|
||||||
boolean showNotification = PreferenceManager
|
boolean showNotification = PreferenceManager
|
||||||
.getDefaultSharedPreferences(this)
|
.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) {
|
if (showNotification) {
|
||||||
// Let's start the notification service
|
// Let's start the notification service
|
||||||
LogUtils.LOGD(TAG, "Starting notification service");
|
LogUtils.LOGD(TAG, "Starting notification service");
|
||||||
startService(new Intent(this, NotificationService.class));
|
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,
|
public void playerOnPause(PlayerType.GetActivePlayersReturnType getActivePlayerResult,
|
||||||
|
@ -633,6 +655,12 @@ public class RemoteActivity extends BaseActivity
|
||||||
setImageViewBackground(null);
|
setImageViewBackground(null);
|
||||||
}
|
}
|
||||||
lastImageUrl = null;
|
lastImageUrl = null;
|
||||||
|
|
||||||
|
if(pauseCallService != null) {
|
||||||
|
((TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE)).listen(
|
||||||
|
pauseCallService, PhoneStateListener.LISTEN_NONE);
|
||||||
|
pauseCallService = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playerNoResultsYet() {
|
public void playerNoResultsYet() {
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="pref_pause_during_calls"
|
android:key="pref_pause_during_calls"
|
||||||
android:title="@string/pause_during_calls"
|
android:title="@string/pause_during_calls"
|
||||||
android:defaultValue="true"/>
|
android:defaultValue="false"/>
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="pref_use_hardware_volume_keys"
|
android:key="pref_use_hardware_volume_keys"
|
||||||
|
|
Loading…
Reference in New Issue