Using my Galaxy Nexus Android version
authorgu.martinm@gmail.com <gu.martinm@gmail.com>
Sun, 30 Mar 2014 17:29:45 +0000 (19:29 +0200)
committergu.martinm@gmail.com <gu.martinm@gmail.com>
Sun, 30 Mar 2014 17:29:45 +0000 (19:29 +0200)
12 files changed:
AndroidManifest.xml
project.properties
res/layout/fragment_main.xml
res/values/strings.xml
src/de/example/exampletdd/WeatherInformationActivity.java
src/de/example/exampletdd/activityinterface/OnClickButtons.java [new file with mode: 0644]
src/de/example/exampletdd/fragment/WeatherDataFragment.java
src/de/example/exampletdd/httpclient/WeatherHTTPClient.java
src/de/example/exampletdd/parser/JPOSWeatherParser.java
src/de/example/exampletdd/service/WeatherService.java
tests/AndroidManifest.xml
tests/project.properties

index 155fbb4..ba00203 100644 (file)
@@ -2,11 +2,12 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="de.example.exampletdd"
     android:versionCode="1"
-    android:versionName="1.0" >
+    android:versionName="1.0" android:installLocation="auto">
 
     <uses-sdk
-        android:minSdkVersion="19"
-        android:targetSdkVersion="19" />
+        android:minSdkVersion="18"
+        android:targetSdkVersion="18" android:maxSdkVersion="18"/>
+    <uses-permission android:name="android.permission.INTERNET"/>
 
     <application
         android:allowBackup="true"
index 4ab1256..ce39f2d 100644 (file)
@@ -11,4 +11,4 @@
 #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 
 # Project target.
-target=android-19
+target=android-18
index a801e94..29dd98f 100644 (file)
 
     <ImageView
         android:id="@+id/imageIcon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
         android:layout_below="@+id/editTextCity"
         android:layout_centerHorizontal="true"
-        android:layout_marginTop="30dp"
         android:contentDescription="@string/icon_weather_description"
+        android:scaleType="fitCenter"
         android:src="@drawable/ic_launcher" />
 
 </RelativeLayout>
\ No newline at end of file
index 1e684ca..56a3a09 100644 (file)
@@ -6,9 +6,9 @@
     <string name="button_weather">Get weather</string>
     <string name="uri_api_coord">http://api.openweathermap.org/data/{0}/weather?lat={1}&amp;lon={2}</string>
     <string name="uri_api_city">http://api.openweathermap.org/data/{0}/weather?q={1}</string>
-    <string name="uri_api_icon">http://openweathermap.org/img/w/{0}</string>
+    <string name="uri_api_icon">http://openweathermap.org/img/w/{0}.png</string>
     <string name="api_version">2.5</string>
-    <string name="text_default_city">City,country</string>
+    <string name="text_default_city">London,uk</string>
     <string name="text_field_city">City name</string>
     <string name="text_field_latitude">Latitude</string>
     <string name="text_field_longitude">Longitude</string>
index cb4e1b3..c721b7d 100644 (file)
@@ -1,49 +1,32 @@
 package de.example.exampletdd;
 
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
 import android.app.Activity;
 import android.app.DialogFragment;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.widget.EditText;
-import android.widget.ImageView;
+import android.view.View;
 import de.example.exampletdd.activityinterface.ErrorMessage;
-import de.example.exampletdd.activityinterface.UpdateWeatherData;
+import de.example.exampletdd.activityinterface.OnClickButtons;
 import de.example.exampletdd.fragment.ErrorDialogFragment;
 import de.example.exampletdd.fragment.WeatherDataFragment;
-import de.example.exampletdd.model.WeatherData;
 
-public class WeatherInformationActivity extends Activity implements ErrorMessage, UpdateWeatherData {
-    EditText weatherDescription;
-    EditText temperature;
-    EditText maxTemperature;
-    EditText minTemperature;
-    EditText sunRise;
-    EditText sunSet;
-    ImageView imageIcon;
+public class WeatherInformationActivity extends Activity implements ErrorMessage {
+    private OnClickButtons onclickButtons;
 
     @Override
     protected void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         this.setContentView(R.layout.activity_main);
 
+        final WeatherDataFragment weatherDataFragment = new WeatherDataFragment();
+
         if (savedInstanceState == null) {
             this.getFragmentManager().beginTransaction()
-            .add(R.id.container, new WeatherDataFragment()).commit();
+            .add(R.id.container, weatherDataFragment).commit();
         }
 
-        this.weatherDescription = (EditText) this.findViewById(R.id.editTextWeatherDescription);
-        this.temperature = (EditText) this.findViewById(R.id.editTextTemperature);
-        this.maxTemperature = (EditText) this.findViewById(R.id.editTextMaxTemperature);
-        this.minTemperature = (EditText) this.findViewById(R.id.editTextMinTemperature);
-        this.sunRise = (EditText) this.findViewById(R.id.editTextSunRise);
-        this.sunSet = (EditText) this.findViewById(R.id.editTextSunSet);
-        this.imageIcon = (ImageView) this.findViewById(R.id.imageIcon);
+        this.onclickButtons = weatherDataFragment;
     }
 
     @Override
@@ -73,40 +56,7 @@ public class WeatherInformationActivity extends Activity implements ErrorMessage
         newFragment.show(this.getFragmentManager(), "errorDialog");
     }
 
-
-    @Override
-    public void updateWeatherData(final WeatherData weatherData) {
-
-        if (weatherData.getWeather() != null) {
-            this.weatherDescription.setText(weatherData.getWeather().getDescription());
-            double conversion = weatherData.getMain().getTemp();
-            conversion = conversion - 273.15;
-            this.temperature.setText(String.valueOf(conversion));
-            conversion = weatherData.getMain().getMaxTemp();
-            conversion = conversion - 273.15;
-            this.maxTemperature.setText(String.valueOf(conversion));
-            conversion = weatherData.getMain().getMinTemp();
-            conversion = conversion - 273.15;
-            this.minTemperature.setText(String.valueOf(conversion));
-        }
-
-        if (weatherData.getSystem() != null) {
-            long unixTime = weatherData.getSystem().getSunRiseTime();
-            Date dateUnix = new Date(unixTime);
-            String dateFormatUnix = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z").format(dateUnix);
-            this.sunRise.setText(dateFormatUnix);
-
-            unixTime = weatherData.getSystem().getSunSetTime();
-            dateUnix = new Date(unixTime);
-            dateFormatUnix = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z").format(dateUnix);
-            this.sunSet.setText(dateFormatUnix);
-        }
-
-        if (weatherData.getIconData() != null) {
-            final Bitmap icon = BitmapFactory.decodeByteArray(
-                    weatherData.getIconData(), 0,
-                    weatherData.getIconData().length);
-            this.imageIcon.setImageBitmap(icon);
-        }
+    public void onClickGetWeather(final View v) {
+        this.onclickButtons.onClickGetWeather(v);
     }
 }
diff --git a/src/de/example/exampletdd/activityinterface/OnClickButtons.java b/src/de/example/exampletdd/activityinterface/OnClickButtons.java
new file mode 100644 (file)
index 0000000..0400afe
--- /dev/null
@@ -0,0 +1,9 @@
+package de.example.exampletdd.activityinterface;
+
+import android.view.View;
+
+public interface OnClickButtons {
+
+    public void onClickGetWeather(final View v);
+
+}
index a8fcbae..1efe3fb 100644 (file)
@@ -4,12 +4,17 @@ import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
 import org.apache.http.client.ClientProtocolException;
 import org.json.JSONException;
 
 import android.app.Activity;
 import android.app.Fragment;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.net.http.AndroidHttpClient;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -18,30 +23,47 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.EditText;
+import android.widget.ImageView;
 import de.example.exampletdd.R;
 import de.example.exampletdd.activityinterface.ErrorMessage;
-import de.example.exampletdd.activityinterface.UpdateWeatherData;
+import de.example.exampletdd.activityinterface.OnClickButtons;
 import de.example.exampletdd.httpclient.WeatherHTTPClient;
 import de.example.exampletdd.model.WeatherData;
 import de.example.exampletdd.parser.IJPOSWeatherParser;
 import de.example.exampletdd.parser.JPOSWeatherParser;
 import de.example.exampletdd.service.WeatherService;
 
-public class WeatherDataFragment extends Fragment {
-    private final Activity currentActivity;
+public class WeatherDataFragment extends Fragment implements OnClickButtons {
+    private Activity currentActivity;
+    EditText weatherDescription;
+    EditText temperature;
+    EditText maxTemperature;
+    EditText minTemperature;
+    EditText sunRise;
+    EditText sunSet;
+    ImageView imageIcon;
 
-    public WeatherDataFragment() {
-        this.currentActivity = this.getActivity();
-    }
 
     @Override
     public View onCreateView(final LayoutInflater inflater,
             final ViewGroup container, final Bundle savedInstanceState) {
         final View rootView = inflater.inflate(R.layout.fragment_main,
                 container, false);
+
+        this.currentActivity = this.getActivity();
+
+        this.weatherDescription = (EditText) rootView.findViewById(R.id.editTextWeatherDescription);
+        this.temperature = (EditText) rootView.findViewById(R.id.editTextTemperature);
+        this.maxTemperature = (EditText) rootView.findViewById(R.id.editTextMaxTemperature);
+        this.minTemperature = (EditText) rootView.findViewById(R.id.editTextMinTemperature);
+        this.sunRise = (EditText) rootView.findViewById(R.id.editTextSunRise);
+        this.sunSet = (EditText) rootView.findViewById(R.id.editTextSunSet);
+        this.imageIcon = (ImageView) rootView.findViewById(R.id.imageIcon);
+
         return rootView;
     }
 
+    @Override
     public void onClickGetWeather(final View v) {
 
         final IJPOSWeatherParser JPOSWeatherParser = new JPOSWeatherParser();
@@ -60,6 +82,44 @@ public class WeatherDataFragment extends Fragment {
         weatherTask.execute(cityCountry.getText().toString());
     }
 
+    public void updateWeatherData(final WeatherData weatherData) {
+        final DecimalFormat tempFormatter = new DecimalFormat("#####.#####");
+        final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss Z");
+
+        if (weatherData.getWeather() != null) {
+            this.weatherDescription.setText(weatherData.getWeather()
+                    .getDescription());
+            double conversion = weatherData.getMain().getTemp();
+            conversion = conversion - 273.15;
+            this.temperature.setText(tempFormatter.format(conversion));
+            conversion = weatherData.getMain().getMaxTemp();
+            conversion = conversion - 273.15;
+            this.maxTemperature.setText(tempFormatter.format(conversion));
+            conversion = weatherData.getMain().getMinTemp();
+            conversion = conversion - 273.15;
+            this.minTemperature.setText(tempFormatter.format(conversion));
+        }
+
+        if (weatherData.getSystem() != null) {
+            long unixTime = weatherData.getSystem().getSunRiseTime();
+            Date unixDate = new Date(unixTime * 1000L);
+            String dateFormatUnix = dateFormat.format(unixDate);
+            this.sunRise.setText(dateFormatUnix);
+
+            unixTime = weatherData.getSystem().getSunSetTime();
+            unixDate = new Date(unixTime * 1000L);
+            dateFormatUnix = dateFormat.format(unixDate);
+            this.sunSet.setText(dateFormatUnix);
+        }
+
+        if (weatherData.getIconData() != null) {
+            final Bitmap icon = BitmapFactory.decodeByteArray(
+                    weatherData.getIconData(), 0,
+                    weatherData.getIconData().length);
+            this.imageIcon.setImageBitmap(icon);
+        }
+    }
+
     public class WeatherTask extends AsyncTask<Object, Void, WeatherData> {
         private static final String TAG = "JSONWeatherTask";
         private final WeatherHTTPClient weatherHTTPClient;
@@ -73,91 +133,31 @@ public class WeatherDataFragment extends Fragment {
 
         @Override
         protected WeatherData doInBackground(final Object... params) {
-            final String cityCountry = (String) params[0];
-
-            final String urlAPICity = WeatherDataFragment.this.getResources()
-                    .getString(R.string.uri_api_city);
-            final String APIVersion = WeatherDataFragment.this.getResources()
-                    .getString(R.string.api_version);
-
-            String url = this.weatherService.createURIAPICityCountry(
-                    cityCountry, urlAPICity, APIVersion);
+            WeatherData weatherData = null;
 
-            String jsonData = null;
             try {
-                jsonData = this.weatherHTTPClient
-                        .retrieveJSONDataFromAPI(new URL(url));
+                weatherData = this.doInBackgroundThrowable(params);
             } catch (final ClientProtocolException e) {
                 Log.e(TAG, "WeatherHTTPClient exception: ", e);
-                ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                .createErrorDialog(R.string.error_dialog_generic_error);
             } catch (final MalformedURLException e) {
                 Log.e(TAG, "Syntax URL exception: ", e);
-                ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                .createErrorDialog(R.string.error_dialog_generic_error);
             } catch (final URISyntaxException e) {
                 Log.e(TAG, "WeatherHTTPClient exception: ", e);
-                ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                .createErrorDialog(R.string.error_dialog_generic_error);
             } catch (final IOException e) {
                 Log.e(TAG, "WeatherHTTPClient exception: ", e);
-                ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                .createErrorDialog(R.string.error_dialog_generic_error);
+            } catch (final JSONException e) {
+                Log.e(TAG, "WeatherService exception: ", e);
             } finally {
                 this.weatherHTTPClient.close();
             }
 
-            WeatherData weatherData = null;
-            if (jsonData != null) {
-                try {
-                    weatherData = this.weatherService.retrieveWeather(jsonData);
-                } catch (final JSONException e) {
-                    Log.e(TAG, "WeatherService exception: ", e);
-                    ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                    .createErrorDialog(R.string.error_dialog_generic_error);
-                }
-
-            }
-
-            if (weatherData != null) {
-                final String icon = weatherData.getWeather().getIcon();
-                final String urlAPIicon = WeatherDataFragment.this
-                        .getResources().getString(R.string.uri_api_icon);
-
-                url = this.weatherService.createURIAPIicon(icon, urlAPIicon);
-                try {
-                    final byte[] iconData = this.weatherHTTPClient
-                            .retrieveDataFromAPI(new URL(url)).toByteArray();
-                    weatherData.setIconData(iconData);
-                } catch (final ClientProtocolException e) {
-                    Log.e(TAG, "WeatherHTTPClient exception: ", e);
-                    ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                    .createErrorDialog(R.string.error_dialog_generic_error);
-                } catch (final MalformedURLException e) {
-                    Log.e(TAG, "Syntax URL exception: ", e);
-                    ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                    .createErrorDialog(R.string.error_dialog_generic_error);
-                } catch (final URISyntaxException e) {
-                    Log.e(TAG, "WeatherHTTPClient exception: ", e);
-                    ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                    .createErrorDialog(R.string.error_dialog_generic_error);
-                } catch (final IOException e) {
-                    Log.e(TAG, "WeatherHTTPClient exception: ", e);
-                    ((ErrorMessage) WeatherDataFragment.this.currentActivity)
-                    .createErrorDialog(R.string.error_dialog_generic_error);
-                } finally {
-                    this.weatherHTTPClient.close();
-                }
-            }
-
             return weatherData;
         }
 
         @Override
         protected void onPostExecute(final WeatherData weatherData) {
             if (weatherData != null) {
-                ((UpdateWeatherData) WeatherDataFragment.this.currentActivity)
-                .updateWeatherData(weatherData);
+                WeatherDataFragment.this.updateWeatherData(weatherData);
             } else {
                 ((ErrorMessage) WeatherDataFragment.this.currentActivity)
                 .createErrorDialog(R.string.error_dialog_generic_error);
@@ -174,5 +174,35 @@ public class WeatherDataFragment extends Fragment {
 
             this.weatherHTTPClient.close();
         }
+
+        private WeatherData doInBackgroundThrowable(final Object... params)
+                throws ClientProtocolException, MalformedURLException,
+                URISyntaxException, IOException, JSONException {
+            final String cityCountry = (String) params[0];
+            final String urlAPICity = WeatherDataFragment.this.getResources()
+                    .getString(R.string.uri_api_city);
+            final String APIVersion = WeatherDataFragment.this.getResources()
+                    .getString(R.string.api_version);
+            String url = this.weatherService.createURIAPICityCountry(
+                    cityCountry, urlAPICity, APIVersion);
+
+
+            final String jsonData = this.weatherHTTPClient.retrieveJSONDataFromAPI(new URL(url));
+
+
+            final WeatherData weatherData = this.weatherService.retrieveWeather(jsonData);
+
+
+            final String icon = weatherData.getWeather().getIcon();
+            final String urlAPIicon = WeatherDataFragment.this
+                    .getResources().getString(R.string.uri_api_icon);
+            url = this.weatherService.createURIAPIicon(icon, urlAPIicon);
+            final byte[] iconData = this.weatherHTTPClient
+                    .retrieveDataFromAPI(new URL(url)).toByteArray();
+            weatherData.setIconData(iconData);
+
+
+            return weatherData;
+        }
     }
 }
index aab1745..de36985 100644 (file)
@@ -35,12 +35,13 @@ public class WeatherHTTPClient {
                 if (response != null) {
                     final HttpEntity entity = response.getEntity();
                     if (entity != null) {
-                        final String contentEncoding = entity
-                                .getContentEncoding()
-                                .getValue();
+                        // Not receiving encoding :(
+                        // final String contentEncoding = entity
+                        // .getContentEncoding()
+                        // .getValue();
                         final ByteArrayOutputStream buffer = WeatherHTTPClient.this
                                 .sortResponse(response);
-                        return new String(buffer.toByteArray(), contentEncoding);
+                        return new String(buffer.toByteArray(), "UTF-8");
                     }
 
                     throw new IOException("There is no entity");
index 98de7be..ab23011 100644 (file)
@@ -1,5 +1,6 @@
 package de.example.exampletdd.parser;
 
+import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
@@ -25,7 +26,10 @@ public class JPOSWeatherParser implements IJPOSWeatherParser {
         final WeatherData.System system = new WeatherData.System(country,
                 sunRiseTime, sunSetTime, message);
 
-        jsonObject = jsonWeatherData.getJSONObject("weather");
+        // TODO: array of WeatherData.Weather :(
+        final JSONArray jsonArray = jsonWeatherData.getJSONArray("weather");
+        jsonObject = jsonArray.getJSONObject(0);
+
         final int id = jsonObject.getInt("id");
         final String mainWeather = jsonObject.getString("main");
         final String description = jsonObject.getString("description");
@@ -35,8 +39,8 @@ public class JPOSWeatherParser implements IJPOSWeatherParser {
 
         jsonObject = jsonWeatherData.getJSONObject("main");
         final double temp = jsonObject.getDouble("temp");
-        final double minTemp = jsonObject.getDouble("minTemp");
-        final double maxTemp = jsonObject.getDouble("maxTemp");
+        final double minTemp = jsonObject.getDouble("temp_min");
+        final double maxTemp = jsonObject.getDouble("temp_max");
         final double humidity = jsonObject.getDouble("humidity");
         final double pressure = jsonObject.getDouble("pressure");
         final WeatherData.Main main = new WeatherData.Main(temp, minTemp,
@@ -45,9 +49,18 @@ public class JPOSWeatherParser implements IJPOSWeatherParser {
         jsonObject = jsonWeatherData.getJSONObject("wind");
         final double speed = jsonObject.getDouble("speed");
         final double deg = jsonObject.getDouble("deg");
-        final double gust = jsonObject.getDouble("gust");
-        final double var_beg = jsonObject.getDouble("var_beg");
-        final double var_end = jsonObject.getDouble("var_end");
+        double gust = 0;
+        try {
+            gust = jsonObject.getDouble("gust");
+        } catch (final JSONException e) {}
+        double var_beg = 0;
+        try {
+            var_beg = jsonObject.getDouble("var_beg");
+        } catch (final JSONException e) {}
+        double var_end = 0;
+        try {
+            var_end = jsonObject.getDouble("var_end");
+        } catch (final JSONException e) {}
         final WeatherData.Wind wind = new WeatherData.Wind(speed, deg, gust,
                 var_beg, var_end);
 
@@ -55,7 +68,10 @@ public class JPOSWeatherParser implements IJPOSWeatherParser {
         final double cloudiness = jsonObject.getDouble("all");
         final WeatherData.Clouds clouds = new WeatherData.Clouds(cloudiness);
 
-        final double time = jsonObject.getDouble("time");
+        double time = 0;
+        try {
+            time = jsonObject.getDouble("time");
+        } catch (final JSONException e) {}
         final WeatherData.DataReceivingTime dataReceivingTime =
                 new WeatherData.DataReceivingTime(time);
 
index 3416d6e..ed393ca 100644 (file)
@@ -46,8 +46,10 @@ public class WeatherService {
     public String createURIAPIicon(final String icon, final String urlAPI) {
 
         final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.ENGLISH);
+        final Object[] values = new Object[1];
+        values[0] = icon;
 
-        return formatURIAPI.format(icon);
+        return formatURIAPI.format(values);
     }
 
 }
index a863aaa..80c69cf 100644 (file)
@@ -4,7 +4,7 @@
     android:versionCode="1"
     android:versionName="1.0" >
 
-    <uses-sdk android:minSdkVersion="19" />
+    <uses-sdk android:minSdkVersion="18" android:maxSdkVersion="18" android:targetSdkVersion="18"/>
 
     <instrumentation
         android:name="android.test.InstrumentationTestRunner"
index 4ab1256..ce39f2d 100644 (file)
@@ -11,4 +11,4 @@
 #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 
 # Project target.
-target=android-19
+target=android-18