diff --git a/app/build.gradle b/app/build.gradle
index 28b1396..c83808d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -21,6 +21,7 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.github.bumptech.glide:glide:3.5.2'
compile 'com.android.support:appcompat-v7:21.0.2'
compile 'com.android.support:support-annotations:22.0.0'
}
diff --git a/app/src/main/java/com/example/android/sunshine/app/DetailFragment.java b/app/src/main/java/com/example/android/sunshine/app/DetailFragment.java
index 04ff14d..0c88c6f 100644
--- a/app/src/main/java/com/example/android/sunshine/app/DetailFragment.java
+++ b/app/src/main/java/com/example/android/sunshine/app/DetailFragment.java
@@ -34,6 +34,7 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
+import com.bumptech.glide.Glide;
import com.example.android.sunshine.app.data.WeatherContract;
import com.example.android.sunshine.app.data.WeatherContract.WeatherEntry;
@@ -184,7 +185,11 @@ public class DetailFragment extends Fragment implements LoaderManager.LoaderCall
int weatherId = data.getInt(COL_WEATHER_CONDITION_ID);
// Use weather art image
- mIconView.setImageResource(Utility.getArtResourceForWeatherCondition(weatherId));
+ Glide.with(this)
+ .load(Utility.getArtUrlForWeatherCondition(getActivity(), weatherId))
+ .error(Utility.getArtResourceForWeatherCondition(weatherId))
+ .crossFade()
+ .into(mIconView);
// Read date from cursor and update views for day of week and date
long date = data.getLong(COL_WEATHER_DATE);
diff --git a/app/src/main/java/com/example/android/sunshine/app/ForecastAdapter.java b/app/src/main/java/com/example/android/sunshine/app/ForecastAdapter.java
index 6c200ad..0b404e2 100644
--- a/app/src/main/java/com/example/android/sunshine/app/ForecastAdapter.java
+++ b/app/src/main/java/com/example/android/sunshine/app/ForecastAdapter.java
@@ -24,6 +24,8 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
+import com.bumptech.glide.Glide;
+
/**
* {@link ForecastAdapter} exposes a list of weather forecasts
* from a {@link Cursor} to a {@link android.widget.ListView}.
@@ -91,20 +93,27 @@ public class ForecastAdapter extends CursorAdapter {
int viewType = getItemViewType(cursor.getPosition());
int weatherId = cursor.getInt(ForecastFragment.COL_WEATHER_CONDITION_ID);
+ int fallbackIconId;
switch (viewType) {
case VIEW_TYPE_TODAY: {
// Get weather icon
- viewHolder.iconView.setImageResource(Utility.getArtResourceForWeatherCondition(
- weatherId));
+ fallbackIconId = Utility.getArtResourceForWeatherCondition(
+ weatherId);
break;
}
- case VIEW_TYPE_FUTURE_DAY: {
+ default: {
// Get weather icon
- viewHolder.iconView.setImageResource(Utility.getIconResourceForWeatherCondition(
- weatherId));
+ fallbackIconId = Utility.getIconResourceForWeatherCondition(
+ weatherId);
break;
}
}
+
+ Glide.with(mContext)
+ .load(Utility.getArtUrlForWeatherCondition(mContext, weatherId))
+ .error(fallbackIconId)
+ .crossFade()
+ .into(viewHolder.iconView);
// Read date from cursor
long dateInMillis = cursor.getLong(ForecastFragment.COL_WEATHER_DATE);
diff --git a/app/src/main/java/com/example/android/sunshine/app/Utility.java b/app/src/main/java/com/example/android/sunshine/app/Utility.java
index 2e76fb7..73f424a 100644
--- a/app/src/main/java/com/example/android/sunshine/app/Utility.java
+++ b/app/src/main/java/com/example/android/sunshine/app/Utility.java
@@ -216,6 +216,43 @@ public class Utility {
return -1;
}
+ /**
+ * Helper method to provide the art urls according to the weather condition id returned
+ * by the OpenWeatherMap call.
+ *
+ * @param context Context to use for retrieving the URL format
+ * @param weatherId from OpenWeatherMap API response
+ * @return url for the corresponding weather artwork. null if no relation is found.
+ */
+ public static String getArtUrlForWeatherCondition(Context context, int weatherId) {
+ // Based on weather code data found at:
+ // http://bugs.openweathermap.org/projects/api/wiki/Weather_Condition_Codes
+ if (weatherId >= 200 && weatherId <= 232) {
+ return context.getString(R.string.format_art_url, "storm");
+ } else if (weatherId >= 300 && weatherId <= 321) {
+ return context.getString(R.string.format_art_url, "light_rain");
+ } else if (weatherId >= 500 && weatherId <= 504) {
+ return context.getString(R.string.format_art_url, "rain");
+ } else if (weatherId == 511) {
+ return context.getString(R.string.format_art_url, "snow");
+ } else if (weatherId >= 520 && weatherId <= 531) {
+ return context.getString(R.string.format_art_url, "rain");
+ } else if (weatherId >= 600 && weatherId <= 622) {
+ return context.getString(R.string.format_art_url, "snow");
+ } else if (weatherId >= 701 && weatherId <= 761) {
+ return context.getString(R.string.format_art_url, "fog");
+ } else if (weatherId == 761 || weatherId == 781) {
+ return context.getString(R.string.format_art_url, "storm");
+ } else if (weatherId == 800) {
+ return context.getString(R.string.format_art_url, "clear");
+ } else if (weatherId == 801) {
+ return context.getString(R.string.format_art_url, "light_clouds");
+ } else if (weatherId >= 802 && weatherId <= 804) {
+ return context.getString(R.string.format_art_url, "clouds");
+ }
+ return null;
+ }
+
/**
* Helper method to provide the art resource id according to the weather condition id returned
* by the OpenWeatherMap call.
diff --git a/app/src/main/java/com/example/android/sunshine/app/sync/SunshineSyncAdapter.java b/app/src/main/java/com/example/android/sunshine/app/sync/SunshineSyncAdapter.java
index 0ce1a77..21e39e0 100644
--- a/app/src/main/java/com/example/android/sunshine/app/sync/SunshineSyncAdapter.java
+++ b/app/src/main/java/com/example/android/sunshine/app/sync/SunshineSyncAdapter.java
@@ -2,6 +2,7 @@ package com.example.android.sunshine.app.sync;
import android.accounts.Account;
import android.accounts.AccountManager;
+import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.AbstractThreadedSyncAdapter;
@@ -28,6 +29,7 @@ import android.support.v4.app.TaskStackBuilder;
import android.text.format.Time;
import android.util.Log;
+import com.bumptech.glide.Glide;
import com.example.android.sunshine.app.MainActivity;
import com.example.android.sunshine.app.R;
import com.example.android.sunshine.app.Utility;
@@ -46,6 +48,7 @@ import java.lang.annotation.RetentionPolicy;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Vector;
+import java.util.concurrent.ExecutionException;
public class SunshineSyncAdapter extends AbstractThreadedSyncAdapter {
public final String LOG_TAG = SunshineSyncAdapter.class.getSimpleName();
@@ -377,8 +380,33 @@ public class SunshineSyncAdapter extends AbstractThreadedSyncAdapter {
int iconId = Utility.getIconResourceForWeatherCondition(weatherId);
Resources resources = context.getResources();
- Bitmap largeIcon = BitmapFactory.decodeResource(resources,
- Utility.getArtResourceForWeatherCondition(weatherId));
+ int artResourceId = Utility.getArtResourceForWeatherCondition(weatherId);
+ String artUrl = Utility.getArtUrlForWeatherCondition(context, weatherId);
+
+ // On Honeycomb and higher devices, we can retrieve the size of the large icon
+ // Prior to that, we use a fixed size
+ @SuppressLint("InlinedApi")
+ int largeIconWidth = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
+ ? resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_width)
+ : resources.getDimensionPixelSize(R.dimen.notification_large_icon_default);
+ @SuppressLint("InlinedApi")
+ int largeIconHeight = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
+ ? resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height)
+ : resources.getDimensionPixelSize(R.dimen.notification_large_icon_default);
+
+ // Retrieve the large icon
+ Bitmap largeIcon;
+ try {
+ largeIcon = Glide.with(context)
+ .load(artUrl)
+ .asBitmap()
+ .error(artResourceId)
+ .fitCenter()
+ .into(largeIconWidth, largeIconHeight).get();
+ } catch (InterruptedException | ExecutionException e) {
+ Log.e(LOG_TAG, "Error retrieving large icon from " + artUrl, e);
+ largeIcon = BitmapFactory.decodeResource(resources, artResourceId);
+ }
String title = context.getString(R.string.app_name);
// Define the text of the forecast.
diff --git a/app/src/main/res/layout/fragment_detail.xml b/app/src/main/res/layout/fragment_detail.xml
index 29c2793..be69a26 100644
--- a/app/src/main/res/layout/fragment_detail.xml
+++ b/app/src/main/res/layout/fragment_detail.xml
@@ -83,7 +83,8 @@
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true" />
+ android:layout_width="wrap_content"
+ android:adjustViewBounds="true" />
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"/>
diff --git a/app/src/main/res/layout/list_item_forecast_today.xml b/app/src/main/res/layout/list_item_forecast_today.xml
index 76daab3..55e0353 100644
--- a/app/src/main/res/layout/list_item_forecast_today.xml
+++ b/app/src/main/res/layout/list_item_forecast_today.xml
@@ -71,7 +71,8 @@
android:id="@+id/list_item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"/>
+ android:layout_gravity="center_horizontal"
+ android:adjustViewBounds="true"/>
16dp
16dp
+
+ 48dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f83ebc9..f0b386a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -81,6 +81,9 @@
imperial
+
+ https://raw.githubusercontent.com/udacity/Sunshine-Version-2/sunshine_master/app/src/main/res/drawable-xxhdpi/art_%s.png
+
Today