Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

Commit

Permalink
3.11 Add fully functional units setting
Browse files Browse the repository at this point in the history
  • Loading branch information
sdspikes authored and Lyla committed Mar 4, 2015
1 parent 29db009 commit cdd3f2c
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,15 @@ private String getReadableDateString(long time){
/**
* Prepare the weather high/lows for presentation.
*/
private String formatHighLows(double high, double low) {
private String formatHighLows(double high, double low, String unitType) {

if (unitType.equals(getString(R.string.pref_units_imperial))) {
high = (high * 1.8) + 32;
low = (low * 1.8) + 32;
} else if (!unitType.equals(getString(R.string.pref_units_metric))) {
Log.d(LOG_TAG, "Unit type not found: " + unitType);
}

// For presentation, assume the user doesn't care about tenths of a degree.
long roundedHigh = Math.round(high);
long roundedLow = Math.round(low);
Expand Down Expand Up @@ -193,6 +201,18 @@ private String[] getWeatherDataFromJson(String forecastJsonStr, int numDays)
dayTime = new Time();

String[] resultStrs = new String[numDays];

// Data is fetched in Celsius by default.
// If user prefers to see in Fahrenheit, convert the values here.
// We do this rather than fetching in Fahrenheit so that the user can
// change this option without us having to re-fetch the data once
// we start storing the values in a database.
SharedPreferences sharedPrefs =
PreferenceManager.getDefaultSharedPreferences(getActivity());
String unitType = sharedPrefs.getString(
getString(R.string.pref_units_key),
getString(R.string.pref_units_metric));

for(int i = 0; i < weatherArray.length(); i++) {
// For now, using the format "Day, description, hi/low"
String day;
Expand Down Expand Up @@ -220,7 +240,7 @@ private String[] getWeatherDataFromJson(String forecastJsonStr, int numDays)
double high = temperatureObject.getDouble(OWM_MAX);
double low = temperatureObject.getDouble(OWM_MIN);

highAndLow = formatHighLows(high, low);
highAndLow = formatHighLows(high, low, unitType);
resultStrs[i] = day + " - " + description + " - " + highAndLow;
}
return resultStrs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public void onCreate(Bundle savedInstanceState) {
// For all preferences, attach an OnPreferenceChangeListener so the UI summary can be
// updated when the preference changes.
bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_units_key)));
}

/**
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<string-array name="pref_units_options">
<item>@string/pref_units_label_metric</item>
<item>@string/pref_units_label_imperial</item>
</string-array>

<string-array name="pref_units_values">
<item>@string/pref_units_metric</item>
<item>@string/pref_units_imperial</item>
</string-array>
</resources>
18 changes: 18 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,22 @@
<!-- Default postal code for location preference [CHAR LIMIT=NONE] -->
<string name="pref_location_default" translatable="false">94043</string>

<!-- Label for the temperature units preference [CHAR LIMIT=30] -->
<string name="pref_units_label">Temperature Units</string>

<!-- Label for metric option in temperature unit preference [CHAR LIMIT=25] -->
<string name="pref_units_label_metric">Metric</string>

<!-- Label for imperial option in temperature unit preference [CHAR LIMIT=25] -->
<string name="pref_units_label_imperial">Imperial</string>

<!-- Key name for temperature unit preference in SharedPreferences [CHAR LIMIT=NONE] -->
<string name="pref_units_key" translatable="false">units</string>

<!-- Value in SharedPreferences for metric temperature unit option [CHAR LIMIT=NONE] -->
<string name="pref_units_metric" translatable="false">metric</string>

<!-- Value in SharedPreferences for imperial temperature unit option [CHAR LIMIT=NONE] -->
<string name="pref_units_imperial" translatable="false">imperial</string>

</resources>
7 changes: 7 additions & 0 deletions app/src/main/res/xml/pref_general.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@
android:inputType="text"
android:singleLine="true" />

<ListPreference
android:title="@string/pref_units_label"
android:key="@string/pref_units_key"
android:defaultValue="@string/pref_units_metric"
android:entryValues="@array/pref_units_values"
android:entries="@array/pref_units_options" />

</PreferenceScreen>

8 comments on commit cdd3f2c

@isupovs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I was inattentive and missed an explanation but why should we use manual converting of temperature instead of getting already converted vlues from Openweathermap service?

@closer76
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@isupovs : you can go back and watch the video of "Temperature Units Setting" in Lesson 3 again. Katherine mentioned that the App will eventually has a database to store these data, so it's better keep internal data consistent.

@peterqz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@isupovs Agree with you. It sounds more easy with Openweather. (reinvented the wheel).

Maybe a little issue with URL.
"http://api.openweathermap.org/data/2.5/forecast/daily?" This is for "Location instead of zip"

@mshukla19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peterqz As @closer76 mentioned, this was done to maintain consistency when storing values in the database. Imagine you store 7 rows in metric units and the next 7 in imperial units. Then every time you retrieve the values from database, you will have to check for the unit type and this can lead to inconsistencies. So its better to use just one api call for metric and convert to imperial on the fly

@oldergod
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As well, why do API calls when you can already compute its result?

@damonmcc
Copy link

@damonmcc damonmcc commented on cdd3f2c May 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@salogel42 @ceruleanotter Why not use a TwoStatePreference like a SwitchPreference for the temperature unit choice? That was my first instinct but I couldn't resolve an error due to setInitialValue (called automatically in the background) receiving a string when the activity starts.

@emperatorLeo
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry , I'm still a beginner in android, someone could please explain me why we have to edit the "build.gradle" file , I saw that when I clicked in the diff for this node link, its the firs file edited but in the video doesn't say anything about that file and why we have to manually edited and add this:
buildTypes.each {
it.buildConfigField 'String', 'OPEN_WEATHER_MAP_API_KEY', MyOpenWeatherMapApiKey
}

@joshRamirez
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@emperatorLeo The apikey will be exposed, meaning anyone can see it and steal your apikey. To prevent this you can store your apikey in gradle.properties for example and reference it in your buildConfigField.

Also using buildConfig means you can switch between dev and prod versions if you have multiple apikeys and keep them hidden.

Please sign in to comment.