Automatically switch to remote after media start

This commit is contained in:
Synced Synapse 2015-01-17 10:45:34 +00:00
parent 8c634320f4
commit 0e043ab0ac
15 changed files with 176 additions and 24 deletions

View File

@ -22,7 +22,7 @@ import android.text.format.DateUtils;
import com.syncedsynapse.kore2.utils.LogUtils;
/**
* Singleton that holds the settings of the app.
* Singleton that holds the settings of the app, that are not stored in the default shared preferences
*
* Interfaces with {@link android.content.SharedPreferences} to load/store these preferences.
*/
@ -52,7 +52,22 @@ public class Settings {
// Default values
private static final int DEFAULT_MAX_CAST_PICTURES = 12;
// Singleton instance
/**
* Default Shared Preferences keys.
* These settings are automatically managed by the Preferences mechanism.
* Make sure these are the same as in preferences.xml
*/
public static final String KEY_PREF_THEME = "pref_theme";
public static final String KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START =
"pref_switch_to_remote_after_media_start";
public static final String KEY_PREF_ABOUT = "pref_about";
public static final String KEY_PREF_COFFEE = "pref_coffee";
public static final String DEFAULT_PREF_THEME = "0";
public static final boolean DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START = true;
// Singleton instance
private static Settings instance = null;
private Context context;

View File

@ -23,6 +23,7 @@ import android.content.res.TypedArray;
import android.database.Cursor;
import android.net.Uri;
import android.os.*;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
@ -46,6 +47,7 @@ import android.widget.Toast;
import com.melnykov.fab.FloatingActionButton;
import com.melnykov.fab.ObservableScrollView;
import com.syncedsynapse.kore2.R;
import com.syncedsynapse.kore2.Settings;
import com.syncedsynapse.kore2.host.HostInfo;
import com.syncedsynapse.kore2.host.HostManager;
import com.syncedsynapse.kore2.jsonrpc.ApiCallback;
@ -97,6 +99,7 @@ public class AlbumDetailsFragment extends Fragment
private String albumTitle;
private List<FileDownloadHelper.SongInfo> songInfoList = null;
@InjectView(R.id.exit_transition_view) View exitTransitionView;
// Buttons
@InjectView(R.id.fab) ImageButton fabButton;
@InjectView(R.id.add_to_playlist) ImageButton addToPlaylistButton;
@ -189,6 +192,8 @@ public class AlbumDetailsFragment extends Fragment
@Override
public void onResume() {
// Force the exit view to invisible
exitTransitionView.setVisibility(View.INVISIBLE);
super.onResume();
}
@ -258,7 +263,16 @@ public class AlbumDetailsFragment extends Fragment
action.execute(hostManager.getConnection(), new ApiCallback<String>() {
@Override
public void onSucess(String result) {
// Do nothing, play should be starting
// Check whether we should switch to the remote
boolean switchToRemote = PreferenceManager
.getDefaultSharedPreferences(getActivity())
.getBoolean(Settings.KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START,
Settings.DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START);
if (switchToRemote) {
int cx = (fabButton.getLeft() + fabButton.getRight()) / 2;
int cy = (fabButton.getTop() + fabButton.getBottom()) / 2;
UIUtils.switchToRemoteWithAnimation(getActivity(), cx, cy, exitTransitionView);
}
}
@Override

View File

@ -20,6 +20,7 @@ import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarActivity;
import com.syncedsynapse.kore2.Settings;
import com.syncedsynapse.kore2.utils.UIUtils;
/**
@ -31,8 +32,7 @@ public class BaseActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
setTheme(UIUtils.getThemeResourceId(
prefs.getString(SettingsFragment.KEY_PREF_THEME,
SettingsFragment.DEFAULT_PREF_THEME)));
prefs.getString(Settings.KEY_PREF_THEME, Settings.DEFAULT_PREF_THEME)));
super.onCreate(savedInstanceState);
}

View File

@ -24,6 +24,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
@ -107,9 +108,9 @@ public class MovieDetailsFragment extends Fragment
@InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout;
@InjectView(R.id.exit_transition_view) View exitTransitionView;
// Buttons
@InjectView(R.id.fab) ImageButton fabButton;
@InjectView(R.id.add_to_playlist) ImageButton addToPlaylistButton;
@InjectView(R.id.go_to_imdb) ImageButton imdbButton;
@InjectView(R.id.download) ImageButton downloadButton;
@ -210,6 +211,8 @@ public class MovieDetailsFragment extends Fragment
@Override
public void onResume() {
bus.register(this);
// Force the exit view to invisible
exitTransitionView.setVisibility(View.INVISIBLE);
super.onResume();
}
@ -338,7 +341,16 @@ public class MovieDetailsFragment extends Fragment
action.execute(hostManager.getConnection(), new ApiCallback<String>() {
@Override
public void onSucess(String result) {
// Do nothing, play should be starting
// Check whether we should switch to the remote
boolean switchToRemote = PreferenceManager
.getDefaultSharedPreferences(getActivity())
.getBoolean(Settings.KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START,
Settings.DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START);
if (switchToRemote) {
int cx = (fabButton.getLeft() + fabButton.getRight()) / 2;
int cy = (fabButton.getTop() + fabButton.getBottom()) / 2;
UIUtils.switchToRemoteWithAnimation(getActivity(), cx, cy, exitTransitionView);
}
}
@Override

View File

@ -24,6 +24,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
@ -45,6 +46,7 @@ import android.widget.Toast;
import com.melnykov.fab.FloatingActionButton;
import com.melnykov.fab.ObservableScrollView;
import com.syncedsynapse.kore2.R;
import com.syncedsynapse.kore2.Settings;
import com.syncedsynapse.kore2.host.HostInfo;
import com.syncedsynapse.kore2.host.HostManager;
import com.syncedsynapse.kore2.jsonrpc.ApiCallback;
@ -100,6 +102,7 @@ public class MusicVideoDetailsFragment extends Fragment
@InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout;
@InjectView(R.id.exit_transition_view) View exitTransitionView;
// Buttons
@InjectView(R.id.fab) ImageButton fabButton;
@InjectView(R.id.add_to_playlist) ImageButton addToPlaylistButton;
@ -190,6 +193,8 @@ public class MusicVideoDetailsFragment extends Fragment
@Override
public void onResume() {
bus.register(this);
// Force the exit view to invisible
exitTransitionView.setVisibility(View.INVISIBLE);
super.onResume();
}
@ -295,7 +300,16 @@ public class MusicVideoDetailsFragment extends Fragment
action.execute(hostManager.getConnection(), new ApiCallback<String>() {
@Override
public void onSucess(String result) {
// Do nothing
// Check whether we should switch to the remote
boolean switchToRemote = PreferenceManager
.getDefaultSharedPreferences(getActivity())
.getBoolean(Settings.KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START,
Settings.DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START);
if (switchToRemote) {
int cx = (fabButton.getLeft() + fabButton.getRight()) / 2;
int cy = (fabButton.getTop() + fabButton.getBottom()) / 2;
UIUtils.switchToRemoteWithAnimation(getActivity(), cx, cy, exitTransitionView);
}
}
@Override

View File

@ -25,6 +25,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.syncedsynapse.kore2.R;
import com.syncedsynapse.kore2.Settings;
import com.syncedsynapse.kore2.utils.LogUtils;
import com.syncedsynapse.kore2.utils.UIUtils;
@ -40,8 +41,8 @@ public class SettingsActivity extends ActionBarActivity{
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
setTheme(UIUtils.getThemeResourceId(
prefs.getString(SettingsFragment.KEY_PREF_THEME,
SettingsFragment.DEFAULT_PREF_THEME)));
prefs.getString(Settings.KEY_PREF_THEME,
Settings.DEFAULT_PREF_THEME)));
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);

View File

@ -46,14 +46,6 @@ public class SettingsFragment extends PreferenceFragment
public static final String COFFEE_SKU = "coffee";
public static final int COFFEE_RC = 1001;
/**
* Preferences keys. Make sure these are the same as in preferences.xml
*/
public static final String KEY_PREF_THEME = "pref_theme";
public static final String KEY_PREF_ABOUT = "pref_about";
public static final String KEY_PREF_COFFEE = "pref_coffee";
public static final String DEFAULT_PREF_THEME = "0";
// Billing helper
private IabHelper mBillingHelper;
@ -97,7 +89,7 @@ public class SettingsFragment extends PreferenceFragment
// Update summaries
setupPreferences(mSettings.hasBoughtCoffee);
if (key.equals(KEY_PREF_THEME)) {
if (key.equals(Settings.KEY_PREF_THEME)) {
//String newTheme = sharedPreferences.getString(key, DEFAULT_PREF_THEME);
// restart to apply new theme (actually build an entirely new task stack)
@ -118,7 +110,7 @@ public class SettingsFragment extends PreferenceFragment
LogUtils.LOGD(TAG, "Setting up preferences. Has bought coffee? " + hasBoughtCoffee);
// Coffee upgrade
final Preference coffeePref = findPreference(KEY_PREF_COFFEE);
final Preference coffeePref = findPreference(Settings.KEY_PREF_COFFEE);
if (coffeePref != null) {
if (hasBoughtCoffee) {
if (settings.showThanksForCofeeMessage) {
@ -150,7 +142,7 @@ public class SettingsFragment extends PreferenceFragment
}
// Theme preferences
ListPreference themePref = (ListPreference)findPreference(KEY_PREF_THEME);
ListPreference themePref = (ListPreference)findPreference(Settings.KEY_PREF_THEME);
if (hasBoughtCoffee) {
themePref.setEnabled(true);
themePref.setSummary(themePref.getEntry());
@ -166,7 +158,7 @@ public class SettingsFragment extends PreferenceFragment
getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException exc) {
}
Preference aboutPreference = findPreference(KEY_PREF_ABOUT);
Preference aboutPreference = findPreference(Settings.KEY_PREF_ABOUT);
aboutPreference.setSummary(nameAndVersion);
aboutPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
@ -202,7 +194,7 @@ public class SettingsFragment extends PreferenceFragment
mSettings.save();
// Lock upgrade preference
Preference coffeePreference = findPreference(KEY_PREF_COFFEE);
Preference coffeePreference = findPreference(Settings.KEY_PREF_COFFEE);
coffeePreference.setEnabled(false);
coffeePreference.setSummary(getResources().getString(R.string.error_setting_up_billing, result.getMessage()));

View File

@ -24,6 +24,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
@ -44,6 +45,7 @@ import android.widget.Toast;
import com.melnykov.fab.FloatingActionButton;
import com.melnykov.fab.ObservableScrollView;
import com.syncedsynapse.kore2.R;
import com.syncedsynapse.kore2.Settings;
import com.syncedsynapse.kore2.host.HostInfo;
import com.syncedsynapse.kore2.host.HostManager;
import com.syncedsynapse.kore2.jsonrpc.ApiCallback;
@ -100,6 +102,7 @@ public class TVShowEpisodeDetailsFragment extends Fragment
@InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout;
@InjectView(R.id.exit_transition_view) View exitTransitionView;
// Buttons
@InjectView(R.id.fab) ImageButton fabButton;
@InjectView(R.id.add_to_playlist) ImageButton addToPlaylistButton;
@ -201,6 +204,8 @@ public class TVShowEpisodeDetailsFragment extends Fragment
@Override
public void onResume() {
bus.register(this);
// Force the exit view to invisible
exitTransitionView.setVisibility(View.INVISIBLE);
super.onResume();
}
@ -329,7 +334,16 @@ public class TVShowEpisodeDetailsFragment extends Fragment
action.execute(hostManager.getConnection(), new ApiCallback<String>() {
@Override
public void onSucess(String result) {
// Do nothing, playback should start
// Check whether we should switch to the remote
boolean switchToRemote = PreferenceManager
.getDefaultSharedPreferences(getActivity())
.getBoolean(Settings.KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START,
Settings.DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START);
if (switchToRemote) {
int cx = (fabButton.getLeft() + fabButton.getRight()) / 2;
int cy = (fabButton.getTop() + fabButton.getBottom()) / 2;
UIUtils.switchToRemoteWithAnimation(getActivity(), cx, cy, exitTransitionView);
}
}
@Override

View File

@ -15,13 +15,18 @@
*/
package com.syncedsynapse.kore2.utils;
import android.animation.Animator;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.WindowManager;
import android.widget.GridLayout;
import android.widget.ImageView;
@ -34,6 +39,7 @@ import com.syncedsynapse.kore2.host.HostInfo;
import com.syncedsynapse.kore2.host.HostManager;
import com.syncedsynapse.kore2.jsonrpc.type.GlobalType;
import com.syncedsynapse.kore2.jsonrpc.type.VideoType;
import com.syncedsynapse.kore2.ui.RemoteActivity;
import java.util.ArrayList;
import java.util.List;
@ -356,4 +362,49 @@ public class UIUtils {
return R.style.NightTheme;
}
}
/**
* Launches the remote activity, performing a circular reveal animation if
* Lollipop or later
*
* @param context Context
* @param centerX Center X of the animation
* @param centerY Center Y of the animation
* @param exitTransitionView View to reveal. Should occupy the whole screen and
* be invisible before calling this
*/
@TargetApi(21)
public static void switchToRemoteWithAnimation(final Context context,
int centerX, int centerY,
final View exitTransitionView) {
final Intent launchIntent = new Intent(context, RemoteActivity.class);
if (Utils.isLollipopOrLater()) {
// Show the animation
int endRadius = Math.max(exitTransitionView.getHeight(), exitTransitionView.getWidth());
Animator exitAnim = ViewAnimationUtils.createCircularReveal(exitTransitionView,
centerX, centerY, 0, endRadius);
exitAnim.setDuration(200);
exitAnim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {}
@Override
public void onAnimationEnd(Animator animation) {
// Launch remote activity
context.startActivity(launchIntent);
}
@Override public void onAnimationCancel(Animator animation) {}
@Override
public void onAnimationRepeat(Animator animation) {}
});
exitTransitionView.setVisibility(View.VISIBLE);
exitAnim.start();
} else {
// No animation show, just launch the remote
context.startActivity(launchIntent);
}
}
}

View File

@ -221,4 +221,11 @@
app:fab_colorNormal="?attr/fabColorNormal"
app:fab_colorPressed="?attr/fabColorPressed"/>
<!-- View that will be shown with the circularReveal when user presses the FAB -->
<View
android:id="@+id/exit_transition_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/fabColorNormal"
android:visibility="invisible"/>
</RelativeLayout>

View File

@ -255,4 +255,12 @@
android:src="@drawable/ic_play_arrow_white_24dp"
app:fab_colorNormal="?attr/fabColorNormal"
app:fab_colorPressed="?attr/fabColorPressed"/>
<!-- View that will be shown with the circularReveal when user presses the FAB -->
<View
android:id="@+id/exit_transition_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/fabColorNormal"
android:visibility="invisible"/>
</RelativeLayout>

View File

@ -285,4 +285,12 @@
android:src="@drawable/ic_play_arrow_white_24dp"
app:fab_colorNormal="?attr/fabColorNormal"
app:fab_colorPressed="?attr/fabColorPressed"/>
<!-- View that will be shown with the circularReveal when user presses the FAB -->
<View
android:id="@+id/exit_transition_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/fabColorNormal"
android:visibility="invisible"/>
</RelativeLayout>

View File

@ -178,4 +178,12 @@
android:src="@drawable/ic_play_arrow_white_24dp"
app:fab_colorNormal="?attr/fabColorNormal"
app:fab_colorPressed="?attr/fabColorPressed"/>
<!-- View that will be shown with the circularReveal when user presses the FAB -->
<View
android:id="@+id/exit_transition_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/fabColorNormal"
android:visibility="invisible"/>
</RelativeLayout>

View File

@ -257,6 +257,9 @@
<string name="theme_solarized">Solarized</string>
<string name="theme_solarized_dark">Solarized Dark</string>
<string name="switch_to_remote">Switch to remote after media start</string>
<string name="about">About</string>
<string name="about_desc"><![CDATA[
\u00A9 2015 Synced Synapse.<br><br>

View File

@ -29,6 +29,11 @@
android:entryValues="@array/themes_values_array"
android:defaultValue="0"/>
<CheckBoxPreference
android:key="pref_switch_to_remote_after_media_start"
android:title="@string/switch_to_remote"
android:defaultValue="true"/>
<Preference
android:key="pref_about"
android:title="@string/about"/>