package fr.tvbarthel.apps.simplethermometer;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.GradientDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.rebound.SimpleSpringListener;
import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringConfig;
import com.facebook.rebound.SpringSystem;
import fr.tvbarthel.apps.simplethermometer.dialogfragments.AboutDialogFragment;
import fr.tvbarthel.apps.simplethermometer.dialogfragments.ListPickerDialogFragment;
import fr.tvbarthel.apps.simplethermometer.dialogfragments.MoreAppsDialogFragment;
import fr.tvbarthel.apps.simplethermometer.dialogfragments.OpacityDialogFragment;
import fr.tvbarthel.apps.simplethermometer.dialogfragments.SharedPreferenceColorPickerDialogFragment;
import fr.tvbarthel.apps.simplethermometer.dialogfragments.TemperatureUnitPickerDialogFragment;
import fr.tvbarthel.apps.simplethermometer.services.TemperatureUpdaterService;
import fr.tvbarthel.apps.simplethermometer.utils.ColorUtils;
import fr.tvbarthel.apps.simplethermometer.utils.PreferenceUtils;
import fr.tvbarthel.apps.simplethermometer.widget.STWidgetProvider;
public class MainActivity extends ActionBarActivity implements SharedPreferences.OnSharedPreferenceChangeListener,
ListPickerDialogFragment.Listener {
private static final int CHOICE_ID_COLORS = 100;
private static final int CHOICE_ID_OPACITIES = 200;
/*
UI Elements
*/
//Display the temperature with the unit symbol
private TextView mTextViewTemperature;
//Text Background
private GradientDrawable mEllipseBackground;
//Left Line
private View mLeftLine;
//Right Line
private View mRightLine;
//Progress Bar
private ProgressBar mProgressBar;
//The root to use as background
private View mRootView;
// A single Toast used to display textToast
private Toast mTextToast;
// A simple broadcast receiver to catch error from the updater service
private BroadcastReceiver mBroadcastReceiver;
/*
Activity Overrides
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.activity_main_toolbar);
setSupportActionBar(toolbar);
//Retrieve the UI elements references
mTextViewTemperature = (TextView) findViewById(R.id.activity_main_temperature);
mLeftLine = findViewById(R.id.activity_main_horizontal_line_left);
mRightLine = findViewById(R.id.activity_main_horizontal_line_right);
mEllipseBackground = (GradientDrawable) mTextViewTemperature.getBackground();
mProgressBar = (ProgressBar) findViewById(R.id.activity_main_progress_bar);
mRootView = findViewById(R.id.activity_main_root);
mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && TemperatureUpdaterService.ACTION_UPDATE_ERROR.equals(intent.getAction())) {
makeTextToast(intent.getStringExtra(TemperatureUpdaterService.EXTRA_UPDATE_ERROR));
displayLastKnownTemperature();
}
}
};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
initRebound();
}
}
@Override
protected void onResume() {
super.onResume();
//Listen to the shared preference changes
PreferenceUtils.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
//Set the background color
setBackgroundColor();
//Set the text color
setTextColor();
//Set the foreground color
setForegroundColor();
//Display the temperature
displayLastKnownTemperature();
//refresh the temperature if it's outdated
refreshTemperatureIfOutdated();
// Register a broadcast receiver for the error from the TemperatureUpdaterService
final IntentFilter filter = new IntentFilter(TemperatureUpdaterService.ACTION_UPDATE_ERROR);
registerReceiver(mBroadcastReceiver, filter);
}
@Override
protected void onPause() {
super.onPause();
//Stop listening to shared preference changes
PreferenceUtils.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
//hide Toast if displayed
hideToastIfDisplayed();
// Unregister the broadcast receiver
unregisterReceiver(mBroadcastReceiver);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_action_set_color:
//Ask for the color you want to change through an AlertDialogFragment
ListPickerDialogFragment.newInstance(CHOICE_ID_COLORS, getResources().getStringArray(R.array.change_color_options)
).show(getSupportFragmentManager(), null);
return true;
case R.id.menu_item_action_temperature_unit:
//Ask for the temperature unit you want to use
pickTemperatureUnit();
return true;
case R.id.menu_item_action_manual_refresh:
//Manually update the temperature if it's outdated
refreshTemperatureIfOutdated(true);
return true;
case R.id.menu_item_action_about:
//Show the about AlertDialogFragment
displayAbout();
return true;
case R.id.menu_item_action_report_a_problem:
return handleReportAProblem();
case R.id.menu_item_action_more_apps:
return handleMoreApps();
case R.id.menu_item_action_set_opacity:
return handleSetOpacity();
default:
return super.onOptionsItemSelected(item);
}
}
/*
SharedPreferences.OnSharedPreferenceChangeListener Override
*/
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String sharedPreferenceKey) {
boolean broadcastChangeToWidgets = false;
//the shared preference with the key "sharedPreferenceKey" has changed
if (sharedPreferenceKey.equals(PreferenceUtils.PREF_KEY_BACKGROUND_COLOR) ||
PreferenceUtils.PREF_KEY_BACKGROUND_OPACITY.equals(sharedPreferenceKey)) {
//Set the new background color stored in the SharedPreferences "sharedPreferences"
setBackgroundColor();
broadcastChangeToWidgets = true;
} else if (sharedPreferenceKey.equals(PreferenceUtils.PREF_KEY_TEXT_COLOR) ||
PreferenceUtils.PREF_KEY_TEXT_OPACITY.equals(sharedPreferenceKey)) {
//Set the new text color stored in the SharedPreferences "sharedPreferences"
setTextColor();
broadcastChangeToWidgets = true;
} else if (sharedPreferenceKey.equals(PreferenceUtils.PREF_KEY_FOREGROUND_COLOR) ||
PreferenceUtils.PREF_KEY_FOREGROUND_OPACITY.equals(sharedPreferenceKey)) {
//Set the new foreground color stored in the SharedPreferences "sharedPreferences"
setForegroundColor();
broadcastChangeToWidgets = true;
} else if (sharedPreferenceKey.equals(PreferenceUtils.PREF_KEY_TEMPERATURE_UNIT_STRING)) {
//Display the temperature with the new unit stored in the SharedPreferences "sharedPreferences"
displayLastKnownTemperature();
broadcastChangeToWidgets = true;
} else if (sharedPreferenceKey.equals(PreferenceUtils.PREF_KEY_LAST_UPDATE_TIME)) {
// A new update have been completed
// Display the temperature with the new value stored in the SharedPreferences "sharedPreferences"
displayLastKnownTemperature();
}
if (broadcastChangeToWidgets) {
//A change has to be propagate to the app widgets
Intent intent = new Intent(this, STWidgetProvider.class);
intent.setAction(STWidgetProvider.APPWIDGET_DATA_CHANGED);
sendBroadcast(intent);
}
}
/*
ChangeColorDialogFragment.Listener Override
*/
@Override
public void onChoiceSelected(int choiceId, int which) {
if (choiceId == CHOICE_ID_COLORS) {
onColorChangeRequested(which);
} else if (choiceId == CHOICE_ID_OPACITIES) {
onOpacityChangeRequested(which);
}
}
private void onOpacityChangeRequested(int which) {
PreferenceUtils.PreferenceId preferenceId = PreferenceUtils.PreferenceId.BACKGROUND;
if (which == 1) {
preferenceId = PreferenceUtils.PreferenceId.TEXT;
} else if (which == 2) {
preferenceId = PreferenceUtils.PreferenceId.FOREGROUND;
}
OpacityDialogFragment.newInstance(preferenceId).show(getSupportFragmentManager(), null);
}
private void onColorChangeRequested(int which) {
PreferenceUtils.PreferenceId preferenceId = PreferenceUtils.PreferenceId.BACKGROUND;
if (which == 1) {
preferenceId = PreferenceUtils.PreferenceId.TEXT;
} else if (which == 2) {
preferenceId = PreferenceUtils.PreferenceId.FOREGROUND;
}
pickSharedPreferenceColor(preferenceId);
}
private boolean handleSetOpacity() {
// Ask which opacity to set
ListPickerDialogFragment.newInstance(CHOICE_ID_OPACITIES, getResources().getStringArray(R.array.change_opacity_options)
).show(getSupportFragmentManager(), null);
return true;
}
/**
* Handle the "more apps" action.
*
* @return true is the action is handled, false otherwise.
*/
private boolean handleMoreApps() {
(new MoreAppsDialogFragment()).show(getSupportFragmentManager(), null);
return true;
}
/**
* Handle the "report a problem" action.
* <p/>
* Start a new activity to send a problem report.
*
* @return true if the action is handled, false otherwise.
*/
private boolean handleReportAProblem() {
final String email = getString(R.string.report_a_problem_email);
final String subject = getString(R.string.report_a_problem_default_subject);
final String uriString = getString(R.string.report_a_problem_uri,
Uri.encode(email), Uri.encode(subject));
final Uri mailToUri = Uri.parse(uriString);
final Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(mailToUri);
startActivity(intent);
return true;
}
/**
* Display the temperature with a unit symbol.
* The temperature and the unit are retrieved from {@code mDefaultSharedPreferences}
* so the temperature should be up to date.
*/
private void displayLastKnownTemperature() {
final String temperature = PreferenceUtils.getTemperatureAsString(this);
mTextViewTemperature.setText(temperature);
mProgressBar.setVisibility(View.INVISIBLE);
}
/**
* Retrieve the foreground color stored in a {@link android.content.SharedPreferences},
* and apply it to the foreground elements.
*/
private void setForegroundColor() {
//Retrieve the foreground color
int foregroundColor = PreferenceUtils.getPreferedColor(this, PreferenceUtils.PreferenceId.FOREGROUND);
// Retrieve the alpha
int foregroundAlpha = PreferenceUtils.getPreferedAlpha(this, PreferenceUtils.PreferenceId.FOREGROUND);
// Add the alpha to the color
foregroundColor = ColorUtils.addAlphaToColor(foregroundColor, foregroundAlpha);
//Apply color to the foreground elements
mLeftLine.setBackgroundColor(foregroundColor);
mRightLine.setBackgroundColor(foregroundColor);
mEllipseBackground.setColor(foregroundColor);
}
/**
* Retrieve the text color stored in a {@link android.content.SharedPreferences},
* and set it to the textViews.
*/
private void setTextColor() {
//Retrieve the text color
final int textColor = PreferenceUtils.getPreferedColor(this, PreferenceUtils.PreferenceId.TEXT);
final int textAlpha = PreferenceUtils.getPreferedAlpha(this, PreferenceUtils.PreferenceId.TEXT);
//Set the text color to the temperature textView
mTextViewTemperature.setTextColor(ColorUtils.addAlphaToColor(textColor, textAlpha));
}
/**
* Retrieve the background color stored in a {@link android.content.SharedPreferences},
* and use it to set the background color of {@code mRelativeLayoutBackground}.
*/
private void setBackgroundColor() {
final int backgroundColor = PreferenceUtils.getPreferedColor(this,
PreferenceUtils.PreferenceId.BACKGROUND);
final int backgroundAlpha = PreferenceUtils.getPreferedAlpha(this,
PreferenceUtils.PreferenceId.BACKGROUND);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mRootView.setBackgroundDrawable(new ColorDrawable(
ColorUtils.addAlphaToColor(backgroundColor, backgroundAlpha)));
} else {
mRootView.setBackground(new ColorDrawable(
ColorUtils.addAlphaToColor(backgroundColor, backgroundAlpha)));
}
}
/**
* Show a {@link fr.tvbarthel.apps.simplethermometer.dialogfragments.TemperatureUnitPickerDialogFragment}
* to ask the user to chose a temperature unit.
*/
private void pickTemperatureUnit() {
TemperatureUnitPickerDialogFragment.newInstance(getResources().getStringArray(R.array.pref_temperature_name),
getResources().getStringArray(R.array.pref_temperature_unit_symbols)).show(getSupportFragmentManager(), null);
}
/**
* Show a {@link fr.tvbarthel.apps.simplethermometer.dialogfragments.SharedPreferenceColorPickerDialogFragment}
* to ask the user to chose a color to store for the sharedPreference with the key {@code preferenceKey}
*
* @param preferenceId the {@link fr.tvbarthel.apps.simplethermometer.utils.PreferenceUtils.PreferenceId} for which the color will be picked.
*/
private void pickSharedPreferenceColor(PreferenceUtils.PreferenceId preferenceId) {
SharedPreferenceColorPickerDialogFragment.newInstance(preferenceId, ColorUtils.getColorPicks(this))
.show(getSupportFragmentManager(), null);
}
/**
* Show a textToast.
*
* @param message the {@link String} to show.
*/
private void makeTextToast(String message) {
//hide mTextToast if showing
hideToastIfDisplayed();
//make a toast that just contains a text view
mTextToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
mTextToast.show();
}
private void makeTextToast(int stringId) {
makeTextToast(getString(stringId));
}
/**
* Hide {@code mTextToast} if displayed
*/
private void hideToastIfDisplayed() {
if (mTextToast != null) {
mTextToast.cancel();
mTextToast = null;
}
}
/**
* Refresh the temperature if it's outdated
*
* @param manualRefresh true if it's a manual refresh request
*/
private void refreshTemperatureIfOutdated(boolean manualRefresh) {
if (PreferenceUtils.isTemperatureOutdated(this, manualRefresh)) {
if (manualRefresh) {
mTextViewTemperature.setText("");
mProgressBar.setVisibility(View.VISIBLE);
}
TemperatureUpdaterService.startForUpdate(this);
} else if (manualRefresh) {
makeTextToast(R.string.error_message_temperature_up_to_date);
}
}
private void refreshTemperatureIfOutdated() {
refreshTemperatureIfOutdated(false);
}
/**
* Show the about information in a {@link fr.tvbarthel.apps.simplethermometer.dialogfragments.AboutDialogFragment}
*/
private void displayAbout() {
new AboutDialogFragment().show(getSupportFragmentManager(), null);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void initRebound() {
final SpringSystem springSystem = SpringSystem.create();
final Spring spring = springSystem.createSpring();
spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(40, 3));
spring.addListener(new SimpleSpringListener() {
@Override
public void onSpringUpdate(Spring spring) {
float value = (float) spring.getCurrentValue();
float scale = 1f - (value * 0.5f);
mTextViewTemperature.setScaleX(scale);
mTextViewTemperature.setScaleY(scale);
}
});
mTextViewTemperature.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
spring.setEndValue(1);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
spring.setEndValue(0);
break;
}
return true;
}
});
}
}