WeatherInformation: using Android Studio
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 19 Oct 2014 23:09:50 +0000 (01:09 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 19 Oct 2014 23:09:50 +0000 (01:09 +0200)
346 files changed:
AndroidManifest.xml [deleted file]
app/build.gradle [new file with mode: 0644]
app/libs/jackson-core-2.3.3.jar [new file with mode: 0644]
app/lint.xml [new file with mode: 0644]
app/src/androidTest/java/de/example/exampletdd/test/JPOSWeatherParserTest.java [new file with mode: 0644]
app/src/androidTest/java/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java [new file with mode: 0644]
app/src/androidTest/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
app/src/androidTest/res/drawable-ldpi/ic_launcher.png [new file with mode: 0644]
app/src/androidTest/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
app/src/androidTest/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
app/src/androidTest/res/values/strings.xml [new file with mode: 0644]
app/src/main/AndroidManifest.xml [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/MapActivity.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/NotificationIntentService.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/SpecificActivity.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/WeatherInformationBootReceiver.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/WeatherInformationPreferencesActivity.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/WeatherTabsActivity.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/WidgetIntentService.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/dummy/DummyContent.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/ErrorDialogFragment.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/ProgressDialogFragment.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/current/CurrentFragment.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/map/MapButtonsFragment.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/map/MapProgressFragment.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/overview/OverviewAdapter.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/overview/OverviewEntry.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/overview/OverviewFragment.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/fragment/specific/SpecificFragment.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/httpclient/Consts.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/httpclient/ContentType.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/httpclient/CustomHTTPClient.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/DatabaseQueries.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/WeatherLocation.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/WeatherLocationContract.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/WeatherLocationDbHelper.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/WeatherLocationDbQueries.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Clouds.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Coord.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Current.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Main.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Rain.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Snow.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Sys.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Weather.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/currentweather/Wind.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/forecastweather/City.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/forecastweather/Coord.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/forecastweather/Forecast.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/forecastweather/List.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/forecastweather/Temp.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/model/forecastweather/Weather.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/parser/IJPOSParser.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/parser/JPOSWeatherParser.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/service/IconsList.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/service/PermanentStorage.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/service/ServiceParser.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/widget/WidgetConfigure.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/widget/WidgetPreferences.java [new file with mode: 0644]
app/src/main/java/de/example/exampletdd/widget/WidgetProvider.java [new file with mode: 0644]
app/src/main/res/anim/weather_map_enter_progress.xml [new file with mode: 0644]
app/src/main/res/anim/weather_map_exit_progress.xml [new file with mode: 0644]
app/src/main/res/drawable-hdpi/ic_action_import_export.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/ic_action_map.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/ic_action_place.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/ic_action_refresh.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/ic_action_search.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/ic_action_settings.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/ic_menu_settings_holo_light.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/thermometer.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_clear.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_clear_night.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_few_clouds.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_few_clouds_night.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_fog.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_overcast.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_severe_alert.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_showers.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_showers_scattered.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_snow.png [new file with mode: 0644]
app/src/main/res/drawable-hdpi/weather_storm.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/ic_action_import_export.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/ic_action_map.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/ic_action_place.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/ic_action_refresh.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/ic_action_search.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/ic_action_settings.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/thermometer.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_clear.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_clear_night.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_few_clouds.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_few_clouds_night.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_fog.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_overcast.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_severe_alert.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_showers.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_showers_scattered.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_snow.png [new file with mode: 0644]
app/src/main/res/drawable-mdpi/weather_storm.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/ic_action_import_export.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/ic_action_map.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/ic_action_place.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/ic_action_refresh.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/ic_action_search.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/ic_action_settings.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/thermometer.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_clear.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_clear_night.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_few_clouds.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_few_clouds_night.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_fog.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_overcast.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_severe_alert.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_showers.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_showers_scattered.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_snow.png [new file with mode: 0644]
app/src/main/res/drawable-xhdpi/weather_storm.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/ic_action_import_export.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/ic_action_map.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/ic_action_place.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/ic_action_refresh.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/ic_action_search.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/ic_action_settings.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/ic_launcher.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/thermometer.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_clear.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_clear_night.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_few_clouds.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_few_clouds_night.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_fog.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_overcast.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_severe_alert.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_showers.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_showers_scattered.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_snow.png [new file with mode: 0644]
app/src/main/res/drawable-xxhdpi/weather_storm.png [new file with mode: 0644]
app/src/main/res/layout-large/weather_main.xml [new file with mode: 0644]
app/src/main/res/layout/appwidget.xml [new file with mode: 0644]
app/src/main/res/layout/appwidget_configure.xml [new file with mode: 0644]
app/src/main/res/layout/appwidget_error.xml [new file with mode: 0644]
app/src/main/res/layout/fragment_pager.xml [new file with mode: 0644]
app/src/main/res/layout/notification.xml [new file with mode: 0644]
app/src/main/res/layout/weather_current_fragment.xml [new file with mode: 0644]
app/src/main/res/layout/weather_main_entry_list.xml [new file with mode: 0644]
app/src/main/res/layout/weather_map.xml [new file with mode: 0644]
app/src/main/res/layout/weather_map_buttons.xml [new file with mode: 0644]
app/src/main/res/layout/weather_map_progress.xml [new file with mode: 0644]
app/src/main/res/layout/weather_specific.xml [new file with mode: 0644]
app/src/main/res/layout/weather_specific_fragment.xml [new file with mode: 0644]
app/src/main/res/menu/main.xml [new file with mode: 0644]
app/src/main/res/menu/weather_main_menu.xml [new file with mode: 0644]
app/src/main/res/values-v11/styles.xml [new file with mode: 0644]
app/src/main/res/values-v14/dimens.xml [new file with mode: 0644]
app/src/main/res/values-v14/styles.xml [new file with mode: 0644]
app/src/main/res/values-w820dp/dimens.xml [new file with mode: 0644]
app/src/main/res/values/arrays.xml [new file with mode: 0644]
app/src/main/res/values/dimens.xml [new file with mode: 0644]
app/src/main/res/values/strings.xml [new file with mode: 0644]
app/src/main/res/values/styles.xml [new file with mode: 0644]
app/src/main/res/xml/appwidget_preferences.xml [new file with mode: 0644]
app/src/main/res/xml/appwidget_provider.xml [new file with mode: 0644]
app/src/main/res/xml/weather_preferences.xml [new file with mode: 0644]
build.gradle [new file with mode: 0644]
gen/.gitignore [deleted file]
gradle/wrapper/gradle-wrapper.jar [new file with mode: 0644]
gradle/wrapper/gradle-wrapper.properties [new file with mode: 0644]
gradlew [new file with mode: 0755]
gradlew.bat [new file with mode: 0644]
ic_launcher-web.png [deleted file]
import-summary.txt [new file with mode: 0644]
libs/android-support-v4.jar [deleted file]
libs/jackson-core-2.3.3.jar [deleted file]
lint.xml [deleted file]
proguard-project.txt [deleted file]
project.properties [deleted file]
res/anim/weather_map_enter_progress.xml [deleted file]
res/anim/weather_map_exit_progress.xml [deleted file]
res/drawable-hdpi/ic_action_import_export.png [deleted file]
res/drawable-hdpi/ic_action_map.png [deleted file]
res/drawable-hdpi/ic_action_place.png [deleted file]
res/drawable-hdpi/ic_action_refresh.png [deleted file]
res/drawable-hdpi/ic_action_search.png [deleted file]
res/drawable-hdpi/ic_action_settings.png [deleted file]
res/drawable-hdpi/ic_launcher.png [deleted file]
res/drawable-hdpi/ic_menu_settings_holo_light.png [deleted file]
res/drawable-hdpi/thermometer.png [deleted file]
res/drawable-hdpi/weather_clear.png [deleted file]
res/drawable-hdpi/weather_clear_night.png [deleted file]
res/drawable-hdpi/weather_few_clouds.png [deleted file]
res/drawable-hdpi/weather_few_clouds_night.png [deleted file]
res/drawable-hdpi/weather_fog.png [deleted file]
res/drawable-hdpi/weather_overcast.png [deleted file]
res/drawable-hdpi/weather_severe_alert.png [deleted file]
res/drawable-hdpi/weather_showers.png [deleted file]
res/drawable-hdpi/weather_showers_scattered.png [deleted file]
res/drawable-hdpi/weather_snow.png [deleted file]
res/drawable-hdpi/weather_storm.png [deleted file]
res/drawable-mdpi/ic_action_import_export.png [deleted file]
res/drawable-mdpi/ic_action_map.png [deleted file]
res/drawable-mdpi/ic_action_place.png [deleted file]
res/drawable-mdpi/ic_action_refresh.png [deleted file]
res/drawable-mdpi/ic_action_search.png [deleted file]
res/drawable-mdpi/ic_action_settings.png [deleted file]
res/drawable-mdpi/ic_launcher.png [deleted file]
res/drawable-mdpi/thermometer.png [deleted file]
res/drawable-mdpi/weather_clear.png [deleted file]
res/drawable-mdpi/weather_clear_night.png [deleted file]
res/drawable-mdpi/weather_few_clouds.png [deleted file]
res/drawable-mdpi/weather_few_clouds_night.png [deleted file]
res/drawable-mdpi/weather_fog.png [deleted file]
res/drawable-mdpi/weather_overcast.png [deleted file]
res/drawable-mdpi/weather_severe_alert.png [deleted file]
res/drawable-mdpi/weather_showers.png [deleted file]
res/drawable-mdpi/weather_showers_scattered.png [deleted file]
res/drawable-mdpi/weather_snow.png [deleted file]
res/drawable-mdpi/weather_storm.png [deleted file]
res/drawable-xhdpi/ic_action_import_export.png [deleted file]
res/drawable-xhdpi/ic_action_map.png [deleted file]
res/drawable-xhdpi/ic_action_place.png [deleted file]
res/drawable-xhdpi/ic_action_refresh.png [deleted file]
res/drawable-xhdpi/ic_action_search.png [deleted file]
res/drawable-xhdpi/ic_action_settings.png [deleted file]
res/drawable-xhdpi/ic_launcher.png [deleted file]
res/drawable-xhdpi/thermometer.png [deleted file]
res/drawable-xhdpi/weather_clear.png [deleted file]
res/drawable-xhdpi/weather_clear_night.png [deleted file]
res/drawable-xhdpi/weather_few_clouds.png [deleted file]
res/drawable-xhdpi/weather_few_clouds_night.png [deleted file]
res/drawable-xhdpi/weather_fog.png [deleted file]
res/drawable-xhdpi/weather_overcast.png [deleted file]
res/drawable-xhdpi/weather_severe_alert.png [deleted file]
res/drawable-xhdpi/weather_showers.png [deleted file]
res/drawable-xhdpi/weather_showers_scattered.png [deleted file]
res/drawable-xhdpi/weather_snow.png [deleted file]
res/drawable-xhdpi/weather_storm.png [deleted file]
res/drawable-xxhdpi/ic_action_import_export.png [deleted file]
res/drawable-xxhdpi/ic_action_map.png [deleted file]
res/drawable-xxhdpi/ic_action_place.png [deleted file]
res/drawable-xxhdpi/ic_action_refresh.png [deleted file]
res/drawable-xxhdpi/ic_action_search.png [deleted file]
res/drawable-xxhdpi/ic_action_settings.png [deleted file]
res/drawable-xxhdpi/ic_launcher.png [deleted file]
res/drawable-xxhdpi/thermometer.png [deleted file]
res/drawable-xxhdpi/weather_clear.png [deleted file]
res/drawable-xxhdpi/weather_clear_night.png [deleted file]
res/drawable-xxhdpi/weather_few_clouds.png [deleted file]
res/drawable-xxhdpi/weather_few_clouds_night.png [deleted file]
res/drawable-xxhdpi/weather_fog.png [deleted file]
res/drawable-xxhdpi/weather_overcast.png [deleted file]
res/drawable-xxhdpi/weather_severe_alert.png [deleted file]
res/drawable-xxhdpi/weather_showers.png [deleted file]
res/drawable-xxhdpi/weather_showers_scattered.png [deleted file]
res/drawable-xxhdpi/weather_snow.png [deleted file]
res/drawable-xxhdpi/weather_storm.png [deleted file]
res/layout-large/weather_main.xml [deleted file]
res/layout/appwidget.xml [deleted file]
res/layout/appwidget_configure.xml [deleted file]
res/layout/appwidget_error.xml [deleted file]
res/layout/fragment_pager.xml [deleted file]
res/layout/notification.xml [deleted file]
res/layout/weather_current_fragment.xml [deleted file]
res/layout/weather_main_entry_list.xml [deleted file]
res/layout/weather_map.xml [deleted file]
res/layout/weather_map_buttons.xml [deleted file]
res/layout/weather_map_progress.xml [deleted file]
res/layout/weather_specific.xml [deleted file]
res/layout/weather_specific_fragment.xml [deleted file]
res/menu/main.xml [deleted file]
res/menu/weather_main_menu.xml [deleted file]
res/values-v11/styles.xml [deleted file]
res/values-v14/dimens.xml [deleted file]
res/values-v14/styles.xml [deleted file]
res/values-w820dp/dimens.xml [deleted file]
res/values/arrays.xml [deleted file]
res/values/dimens.xml [deleted file]
res/values/strings.xml [deleted file]
res/values/styles.xml [deleted file]
res/xml/appwidget_preferences.xml [deleted file]
res/xml/appwidget_provider.xml [deleted file]
res/xml/weather_preferences.xml [deleted file]
settings.gradle [new file with mode: 0644]
src/de/example/exampletdd/MapActivity.java [deleted file]
src/de/example/exampletdd/NotificationIntentService.java [deleted file]
src/de/example/exampletdd/SpecificActivity.java [deleted file]
src/de/example/exampletdd/WeatherInformationBootReceiver.java [deleted file]
src/de/example/exampletdd/WeatherInformationPreferencesActivity.java [deleted file]
src/de/example/exampletdd/WeatherTabsActivity.java [deleted file]
src/de/example/exampletdd/WidgetIntentService.java [deleted file]
src/de/example/exampletdd/dummy/DummyContent.java [deleted file]
src/de/example/exampletdd/fragment/ErrorDialogFragment.java [deleted file]
src/de/example/exampletdd/fragment/ProgressDialogFragment.java [deleted file]
src/de/example/exampletdd/fragment/current/CurrentFragment.java [deleted file]
src/de/example/exampletdd/fragment/map/MapButtonsFragment.java [deleted file]
src/de/example/exampletdd/fragment/map/MapProgressFragment.java [deleted file]
src/de/example/exampletdd/fragment/overview/OverviewAdapter.java [deleted file]
src/de/example/exampletdd/fragment/overview/OverviewEntry.java [deleted file]
src/de/example/exampletdd/fragment/overview/OverviewFragment.java [deleted file]
src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java [deleted file]
src/de/example/exampletdd/fragment/specific/SpecificFragment.java [deleted file]
src/de/example/exampletdd/httpclient/Consts.java [deleted file]
src/de/example/exampletdd/httpclient/ContentType.java [deleted file]
src/de/example/exampletdd/httpclient/CustomHTTPClient.java [deleted file]
src/de/example/exampletdd/model/DatabaseQueries.java [deleted file]
src/de/example/exampletdd/model/WeatherLocation.java [deleted file]
src/de/example/exampletdd/model/WeatherLocationContract.java [deleted file]
src/de/example/exampletdd/model/WeatherLocationDbHelper.java [deleted file]
src/de/example/exampletdd/model/WeatherLocationDbQueries.java [deleted file]
src/de/example/exampletdd/model/currentweather/Clouds.java [deleted file]
src/de/example/exampletdd/model/currentweather/Coord.java [deleted file]
src/de/example/exampletdd/model/currentweather/Current.java [deleted file]
src/de/example/exampletdd/model/currentweather/Main.java [deleted file]
src/de/example/exampletdd/model/currentweather/Rain.java [deleted file]
src/de/example/exampletdd/model/currentweather/Snow.java [deleted file]
src/de/example/exampletdd/model/currentweather/Sys.java [deleted file]
src/de/example/exampletdd/model/currentweather/Weather.java [deleted file]
src/de/example/exampletdd/model/currentweather/Wind.java [deleted file]
src/de/example/exampletdd/model/forecastweather/City.java [deleted file]
src/de/example/exampletdd/model/forecastweather/Coord.java [deleted file]
src/de/example/exampletdd/model/forecastweather/Forecast.java [deleted file]
src/de/example/exampletdd/model/forecastweather/List.java [deleted file]
src/de/example/exampletdd/model/forecastweather/Temp.java [deleted file]
src/de/example/exampletdd/model/forecastweather/Weather.java [deleted file]
src/de/example/exampletdd/parser/IJPOSParser.java [deleted file]
src/de/example/exampletdd/parser/JPOSWeatherParser.java [deleted file]
src/de/example/exampletdd/service/IconsList.java [deleted file]
src/de/example/exampletdd/service/PermanentStorage.java [deleted file]
src/de/example/exampletdd/service/ServiceParser.java [deleted file]
src/de/example/exampletdd/widget/WidgetConfigure.java [deleted file]
src/de/example/exampletdd/widget/WidgetPreferences.java [deleted file]
src/de/example/exampletdd/widget/WidgetProvider.java [deleted file]
tests/AndroidManifest.xml [deleted file]
tests/gen/de/example/exampletdd/test/BuildConfig.java [deleted file]
tests/gen/de/example/exampletdd/test/R.java [deleted file]
tests/proguard-project.txt [deleted file]
tests/project.properties [deleted file]
tests/res/drawable-hdpi/ic_launcher.png [deleted file]
tests/res/drawable-ldpi/ic_launcher.png [deleted file]
tests/res/drawable-mdpi/ic_launcher.png [deleted file]
tests/res/drawable-xhdpi/ic_launcher.png [deleted file]
tests/res/values/strings.xml [deleted file]
tests/src/de/example/exampletdd/test/JPOSWeatherParserTest.java [deleted file]
tests/src/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java [deleted file]

diff --git a/AndroidManifest.xml b/AndroidManifest.xml
deleted file mode 100644 (file)
index 55771d1..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="de.example.exampletdd"
-    android:installLocation="auto"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-sdk
-        android:maxSdkVersion="18"
-        android:minSdkVersion="18"
-        android:targetSdkVersion="18" />
-
-    <uses-feature
-        android:glEsVersion="0x00020000"
-        android:required="true" />
-    
-    <!-- TODO: http://developer.android.com/guide/topics/manifest/supports-screens-element.html -->
-    <!-- TODO: supporting multiple layouts/languages http://developer.android.com/guide/practices/screens_support.html -->
-    <compatible-screens>
-       <screen android:screenSize="normal" android:screenDensity="xhdpi" />
-       </compatible-screens>
-    <supports-screens android:smallScreens="false" />
-
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <!--
-     The following two permissions are not required to use
-     Google Maps Android API v2, but are recommended.
-    -->
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
-    
-    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 
-    
-    <application
-        android:allowBackup="true"
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:logo="@drawable/ic_launcher"
-        android:theme="@style/AppTheme"
-        android:supportsRtl="false">
-
-        <activity android:name="de.example.exampletdd.WeatherTabsActivity"
-            android:hardwareAccelerated="false"
-            android:uiOptions="splitActionBarWhenNarrow"
-            android:launchMode="singleTop" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity android:name="de.example.exampletdd.WeatherInformationPreferencesActivity"
-            android:parentActivityName="de.example.exampletdd.WeatherTabsActivity" >
-            <intent-filter>
-                <action android:name="android.intent.action.WEATHERINFORMATIONSETTINGS" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-            <intent-filter>
-                               <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
-                               <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-        <activity android:name="de.example.exampletdd.MapActivity"
-            android:parentActivityName="de.example.exampletdd.WeatherTabsActivity" >
-            <intent-filter>
-                <action android:name="android.intent.action.WEATHERINFORMATIONMAP" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity android:name="de.example.exampletdd.SpecificActivity"
-            android:parentActivityName="de.example.exampletdd.WeatherTabsActivity"
-            android:exported="false" >
-            <intent-filter>
-                <action android:name="android.intent.action.WEATHERINFORMATIONSPECIFICDATA" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity android:name="de.example.exampletdd.widget.WidgetConfigure">
-            <intent-filter>
-                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
-            </intent-filter>
-        </activity>
-        
-        <receiver android:name="de.example.exampletdd.WeatherInformationBootReceiver"
-            android:enabled="true">
-            <intent-filter>
-                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
-            </intent-filter>
-        </receiver>
-        <receiver android:name="de.example.exampletdd.widget.WidgetProvider" >
-            <intent-filter>
-                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
-            </intent-filter>
-            <meta-data android:name="android.appwidget.provider"
-                       android:resource="@xml/appwidget_provider" />
-        </receiver>
-
-        <!-- Service to update Notification -->
-        <service android:name="de.example.exampletdd.NotificationIntentService"
-            android:exported="false"
-            android:enabled="true" />
-        
-        <!-- Service to update Widget -->
-               <service android:name="de.example.exampletdd.WidgetIntentService"
-                   android:exported="false"
-            android:enabled="true" />
-        
-
-        <meta-data
-            android:name="com.google.android.maps.v2.API_KEY"
-            android:value="" />
-        <meta-data
-            android:name="com.google.android.gms.version"
-            android:value="@integer/google_play_services_version" />
-
-    </application>
-
-</manifest>
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644 (file)
index 0000000..2f990f1
--- /dev/null
@@ -0,0 +1,28 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 18
+    buildToolsVersion "20.0.0"
+
+    defaultConfig {
+        applicationId "de.example.exampletdd"
+        minSdkVersion 18
+        targetSdkVersion 18
+
+        testApplicationId "de.example.exampletdd.test"
+        testInstrumentationRunner "android.test.InstrumentationTestRunner"
+    }
+
+    buildTypes {
+        release {
+            runProguard false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+        }
+    }
+}
+
+dependencies {
+    compile 'com.android.support:support-v4:+'
+    compile 'com.google.android.gms:play-services:+'
+    compile files('libs/jackson-core-2.3.3.jar')
+}
diff --git a/app/libs/jackson-core-2.3.3.jar b/app/libs/jackson-core-2.3.3.jar
new file mode 100644 (file)
index 0000000..8312650
Binary files /dev/null and b/app/libs/jackson-core-2.3.3.jar differ
diff --git a/app/lint.xml b/app/lint.xml
new file mode 100644 (file)
index 0000000..ee0eead
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint>
\ No newline at end of file
diff --git a/app/src/androidTest/java/de/example/exampletdd/test/JPOSWeatherParserTest.java b/app/src/androidTest/java/de/example/exampletdd/test/JPOSWeatherParserTest.java
new file mode 100644 (file)
index 0000000..42e89eb
--- /dev/null
@@ -0,0 +1,35 @@
+package de.example.exampletdd.test;
+
+import junit.framework.TestCase;
+
+import org.json.JSONException;
+
+import de.example.exampletdd.model.WeatherData;
+import de.example.exampletdd.parser.JPOSWeatherParser;
+
+public class JPOSWeatherParserTest extends TestCase {
+    private JPOSWeatherParser jposWeatherParser;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        this.jposWeatherParser = new JPOSWeatherParser();
+    }
+
+    public void testRetrieveWeatherFromJPOS() throws JSONException {
+        // Arrange
+        final String jsonData = "{\"coord\":{\"lon\":139,\"lat\":35}}";
+        final double longitude = 139;
+        final double latitude = 35;
+        final WeatherData.Coord coord = new WeatherData.Coord(longitude, latitude);
+        final WeatherData expectedWeather = new WeatherData.Builder().setCoord(coord).build();
+
+        // Act
+        final WeatherData finalWeather = this.jposWeatherParser.retrieveWeatherFromJPOS(jsonData);
+
+        // Assert
+        assertEquals(expectedWeather.toString(), finalWeather.toString());
+    }
+
+}
diff --git a/app/src/androidTest/java/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java b/app/src/androidTest/java/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java
new file mode 100644 (file)
index 0000000..90c0d07
--- /dev/null
@@ -0,0 +1,44 @@
+package de.example.exampletdd.test;
+
+import android.content.Intent;
+import android.test.ActivityUnitTestCase;
+import android.widget.Button;
+import de.example.exampletdd.WeatherInformationActivity;
+
+public class WeatherInformationActivityUnitTest extends
+        ActivityUnitTestCase<WeatherInformationActivity> {
+
+    private WeatherInformationActivity activity;
+
+    public WeatherInformationActivityUnitTest() {
+        super(WeatherInformationActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final Intent intent = new Intent(this.getInstrumentation().getTargetContext(),
+                WeatherInformationActivity.class);
+        this.startActivity(intent, null, null);
+        this.activity = this.getActivity();
+    }
+
+    public void testIntentTriggerViaOnClick() {
+        final int buttonweather = de.example.exampletdd.R.id.buttonweather;
+        final Button view = (Button) this.activity.findViewById(buttonweather);
+        assertNotNull("Button Weather not allowed to be null", view);
+
+        view.performClick();
+
+        // TouchUtils cannot be used, only allowed in
+        // InstrumentationTestCase or ActivityInstrumentationTestCase2
+
+        // Check the intent which was started
+        final Intent triggeredIntent = this.getStartedActivityIntent();
+        assertNotNull("Intent was null", triggeredIntent);
+        final String data = triggeredIntent.getDataString();
+
+        assertEquals("Incorrect data passed via the intent",
+                "http://gumartinm.name", data);
+    }
+}
diff --git a/app/src/androidTest/res/drawable-hdpi/ic_launcher.png b/app/src/androidTest/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..96a442e
Binary files /dev/null and b/app/src/androidTest/res/drawable-hdpi/ic_launcher.png differ
diff --git a/app/src/androidTest/res/drawable-ldpi/ic_launcher.png b/app/src/androidTest/res/drawable-ldpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..9923872
Binary files /dev/null and b/app/src/androidTest/res/drawable-ldpi/ic_launcher.png differ
diff --git a/app/src/androidTest/res/drawable-mdpi/ic_launcher.png b/app/src/androidTest/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..359047d
Binary files /dev/null and b/app/src/androidTest/res/drawable-mdpi/ic_launcher.png differ
diff --git a/app/src/androidTest/res/drawable-xhdpi/ic_launcher.png b/app/src/androidTest/res/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..71c6d76
Binary files /dev/null and b/app/src/androidTest/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/app/src/androidTest/res/values/strings.xml b/app/src/androidTest/res/values/strings.xml
new file mode 100644 (file)
index 0000000..00a3f66
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">Weather Information Test</string>
+
+</resources>
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..55771d1
--- /dev/null
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="de.example.exampletdd"
+    android:installLocation="auto"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:maxSdkVersion="18"
+        android:minSdkVersion="18"
+        android:targetSdkVersion="18" />
+
+    <uses-feature
+        android:glEsVersion="0x00020000"
+        android:required="true" />
+    
+    <!-- TODO: http://developer.android.com/guide/topics/manifest/supports-screens-element.html -->
+    <!-- TODO: supporting multiple layouts/languages http://developer.android.com/guide/practices/screens_support.html -->
+    <compatible-screens>
+       <screen android:screenSize="normal" android:screenDensity="xhdpi" />
+       </compatible-screens>
+    <supports-screens android:smallScreens="false" />
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!--
+     The following two permissions are not required to use
+     Google Maps Android API v2, but are recommended.
+    -->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
+    
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 
+    
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:logo="@drawable/ic_launcher"
+        android:theme="@style/AppTheme"
+        android:supportsRtl="false">
+
+        <activity android:name="de.example.exampletdd.WeatherTabsActivity"
+            android:hardwareAccelerated="false"
+            android:uiOptions="splitActionBarWhenNarrow"
+            android:launchMode="singleTop" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name="de.example.exampletdd.WeatherInformationPreferencesActivity"
+            android:parentActivityName="de.example.exampletdd.WeatherTabsActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.WEATHERINFORMATIONSETTINGS" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                               <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
+                               <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <activity android:name="de.example.exampletdd.MapActivity"
+            android:parentActivityName="de.example.exampletdd.WeatherTabsActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.WEATHERINFORMATIONMAP" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name="de.example.exampletdd.SpecificActivity"
+            android:parentActivityName="de.example.exampletdd.WeatherTabsActivity"
+            android:exported="false" >
+            <intent-filter>
+                <action android:name="android.intent.action.WEATHERINFORMATIONSPECIFICDATA" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name="de.example.exampletdd.widget.WidgetConfigure">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
+            </intent-filter>
+        </activity>
+        
+        <receiver android:name="de.example.exampletdd.WeatherInformationBootReceiver"
+            android:enabled="true">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
+            </intent-filter>
+        </receiver>
+        <receiver android:name="de.example.exampletdd.widget.WidgetProvider" >
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+            </intent-filter>
+            <meta-data android:name="android.appwidget.provider"
+                       android:resource="@xml/appwidget_provider" />
+        </receiver>
+
+        <!-- Service to update Notification -->
+        <service android:name="de.example.exampletdd.NotificationIntentService"
+            android:exported="false"
+            android:enabled="true" />
+        
+        <!-- Service to update Widget -->
+               <service android:name="de.example.exampletdd.WidgetIntentService"
+                   android:exported="false"
+            android:enabled="true" />
+        
+
+        <meta-data
+            android:name="com.google.android.maps.v2.API_KEY"
+            android:value="" />
+        <meta-data
+            android:name="com.google.android.gms.version"
+            android:value="@integer/google_play_services_version" />
+
+    </application>
+
+</manifest>
diff --git a/app/src/main/java/de/example/exampletdd/MapActivity.java b/app/src/main/java/de/example/exampletdd/MapActivity.java
new file mode 100644 (file)
index 0000000..01a3c41
--- /dev/null
@@ -0,0 +1,408 @@
+package de.example.exampletdd;
+
+import android.app.ActionBar;
+import android.content.Context;
+import android.location.Criteria;
+import android.location.Geocoder;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
+import com.google.android.gms.maps.MapFragment;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+import de.example.exampletdd.fragment.map.MapButtonsFragment;
+import de.example.exampletdd.fragment.map.MapProgressFragment;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
+
+public class MapActivity extends FragmentActivity implements
+                                                                       LocationListener,
+                                                                       MapProgressFragment.TaskCallbacks {
+    private static final String PROGRESS_FRAGMENT_TAG = "PROGRESS_FRAGMENT";
+    private static final String BUTTONS_FRAGMENT_TAG = "BUTTONS_FRAGMENT";
+    private WeatherLocation mRestoreUI;
+       
+    // Google Play Services Map
+    private GoogleMap mMap;
+    // TODO: read and store from different threads? Hopefully always from UI thread.
+    private Marker mMarker;
+    
+    private LocationManager mLocationManager;
+
+    @Override
+    protected void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        this.setContentView(R.layout.weather_map);
+        
+        // Acquire a reference to the system Location Manager
+        this.mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
+        
+        // Google Play Services Map
+        final MapFragment mapFragment = (MapFragment) this.getFragmentManager()
+                .findFragmentById(R.id.weather_map_fragment_map);
+        this.mMap = mapFragment.getMap();
+        this.mMap.setMyLocationEnabled(false);
+        this.mMap.getUiSettings().setMyLocationButtonEnabled(false);
+        this.mMap.getUiSettings().setZoomControlsEnabled(true);
+        this.mMap.getUiSettings().setCompassEnabled(true);
+        this.mMap.setOnMapLongClickListener(new MapActivityOnMapLongClickListener(this));
+    }
+    
+    @Override
+    protected void onRestoreInstanceState(final Bundle savedInstanceState) {
+       // Instead of restoring the state during onCreate() you may choose to
+       // implement onRestoreInstanceState(), which the system calls after the
+       // onStart() method. The system calls onRestoreInstanceState() only if
+       // there is a saved state to restore, so you do not need to check whether
+       // the Bundle is null:
+        super.onRestoreInstanceState(savedInstanceState);
+        
+        // Restore UI state
+        this.mRestoreUI = (WeatherLocation) savedInstanceState.getSerializable("WeatherLocation");
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final ActionBar actionBar = this.getActionBar();
+        // TODO: string resource
+        actionBar.setTitle("Mark your location");
+        
+        WeatherLocation weatherLocation;
+        if (this.mRestoreUI != null) {
+               // Restore UI state
+               weatherLocation = this.mRestoreUI;
+               // just once
+               this.mRestoreUI = null;
+        } else if (this.mMarker != null ) {
+               final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
+            final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
+            final String cityString = city.getText().toString();
+            final String countryString = country.getText().toString();
+            
+            final LatLng point = this.mMarker.getPosition();
+            double latitude = point.latitude;
+            double longitude = point.longitude;
+
+            weatherLocation = new WeatherLocation()
+                       .setCity(cityString)
+                       .setCountry(countryString)
+                       .setLatitude(latitude)
+                       .setLongitude(longitude);
+       } else {
+               final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
+               weatherLocation = query.queryDataBase();
+        }
+        
+        if (weatherLocation != null) {
+               this.updateUI(weatherLocation);
+        }
+    }
+    
+    /**
+     * I am not using fragment transactions in the right way. But I do not know other way for doing what I am doing.
+     * 
+     * {@link http://stackoverflow.com/questions/16265733/failure-delivering-result-onactivityforresult}
+     */
+    @Override
+    public void onPostResume() {
+       super.onPostResume();
+       
+       final FragmentManager fm = getSupportFragmentManager();
+       final Fragment progressFragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
+       if (progressFragment == null) {
+                this.addButtonsFragment();
+       } else {
+               this.removeProgressFragment();
+               final Bundle bundle = progressFragment.getArguments();
+               double latitude = bundle.getDouble("latitude");
+               double longitude = bundle.getDouble("longitude");
+               this.addProgressFragment(latitude, longitude);
+       }
+    }
+    
+    @Override
+    public void onSaveInstanceState(final Bundle savedInstanceState) {
+       // Save UI state
+       // Save Google Maps Marker
+       if (this.mMarker != null) {
+               final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
+            final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
+            final String cityString = city.getText().toString();
+            final String countryString = country.getText().toString();
+            
+            final LatLng point = this.mMarker.getPosition();
+            double latitude = point.latitude;
+            double longitude = point.longitude;
+
+            final WeatherLocation location = new WeatherLocation()
+                       .setCity(cityString)
+                       .setCountry(countryString)
+                       .setLatitude(latitude)
+                       .setLongitude(longitude);
+            savedInstanceState.putSerializable("WeatherLocation", location);
+        }
+               
+       super.onSaveInstanceState(savedInstanceState);
+    }
+    
+       @Override
+       public void onPause() {
+               super.onPause();
+               
+               this.mLocationManager.removeUpdates(this);
+       }
+       
+    public void onClickSaveLocation(final View v) {
+       if (this.mMarker != null) {
+               final LatLng position = this.mMarker.getPosition();
+               
+               final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
+            final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
+            final String cityString = city.getText().toString();
+            final String countryString = country.getText().toString();
+            
+               final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
+               final WeatherLocation weatherLocation = query.queryDataBase();
+            if (weatherLocation != null) {
+               weatherLocation
+               .setCity(cityString)
+               .setCountry(countryString)
+               .setLatitude(position.latitude)
+               .setLongitude(position.longitude)
+               .setLastCurrentUIUpdate(null)
+               .setLastForecastUIUpdate(null);
+               query.updateDataBase(weatherLocation);
+            } else {
+               final WeatherLocation location = new WeatherLocation()
+                       .setCity(cityString)
+                       .setCountry(countryString)
+                       .setIsSelected(true)
+                       .setLatitude(position.latitude)
+                       .setLongitude(position.longitude);
+               query.insertIntoDataBase(location);
+            }
+       }
+    }
+    
+    public void onClickGetLocation(final View v) {
+       // TODO: Somehow I should show a progress dialog.
+        // If Google Play Services is available
+        if (this.mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
+               // TODO: Hopefully there will be results even if location did not change...   
+            final Criteria criteria = new Criteria();
+            criteria.setAccuracy(Criteria.ACCURACY_FINE);
+            criteria.setAltitudeRequired(false);
+            criteria.setBearingAccuracy(Criteria.NO_REQUIREMENT);
+            criteria.setBearingRequired(false);
+            criteria.setCostAllowed(false);
+            criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
+            criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
+            criteria.setSpeedAccuracy(Criteria.NO_REQUIREMENT);
+            criteria.setSpeedRequired(false);
+            criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH);
+            
+            this.mLocationManager.requestSingleUpdate(criteria, this, null);
+        } else {
+               // TODO: string resource
+               Toast.makeText(this, "You do not have enabled location.", Toast.LENGTH_LONG).show();
+        }
+        // Trying to use the synchronous calls. Problems: mGoogleApiClient read/store from different threads.
+        // new GetLocationTask(this).execute();
+    }
+    
+    private void updateUI(final WeatherLocation weatherLocation) {
+
+        final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
+        final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
+        city.setText(weatherLocation.getCity());
+        country.setText(weatherLocation.getCountry());
+
+        final LatLng point = new LatLng(weatherLocation.getLatitude(), weatherLocation.getLongitude());
+        if (this.mMarker != null) {
+               // Just one marker on map
+               this.mMarker.remove();
+        }
+        this.mMarker = this.mMap.addMarker(new MarkerOptions().position(point).draggable(true));
+        this.mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(point, 5));
+        this.mMap.animateCamera(CameraUpdateFactory.zoomIn());
+        this.mMap.animateCamera(CameraUpdateFactory.zoomTo(8), 2000, null);
+    }
+    
+    private class MapActivityOnMapLongClickListener implements OnMapLongClickListener {
+       // Store the context passed to the AsyncTask when the system instantiates it.
+        private final Context localContext;
+        
+       private MapActivityOnMapLongClickListener(final Context context) {
+               this.localContext = context;
+       }
+       
+               @Override
+               public void onMapLongClick(final LatLng point) {
+                       final MapActivity activity = (MapActivity) this.localContext;
+                       activity.getAddressAndUpdateUI(point.latitude, point.longitude);
+               }
+       
+    }
+
+    /**
+     * Getting the address of the current location, using reverse geocoding only works if
+     * a geocoding service is available.
+     *
+     */
+    private void getAddressAndUpdateUI(final double latitude, final double longitude) {
+        // In Gingerbread and later, use Geocoder.isPresent() to see if a geocoder is available.
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && Geocoder.isPresent()) {
+               this.removeButtonsFragment();
+               this.removeProgressFragment();
+               this.addProgressFragment(latitude, longitude);
+        } else {
+               this.removeProgressFragment();
+               this.addButtonsFragment();
+               // No geocoder is present. Issue an error message.
+               // TODO: string resource
+            Toast.makeText(this, "Cannot get address. No geocoder available.", Toast.LENGTH_LONG).show();
+            
+            // Default values
+            final String city = this.getString(R.string.city_not_found);
+            final String country = this.getString(R.string.country_not_found); 
+            final WeatherLocation weatherLocation = new WeatherLocation()
+                       .setLatitude(latitude)
+                       .setLongitude(longitude)
+                       .setCity(city)
+                       .setCountry(country);
+            
+            updateUI(weatherLocation);
+        }
+    }
+
+       /*****************************************************************************************************
+        *
+        *                                                      MapProgressFragment.TaskCallbacks
+        *
+        *****************************************************************************************************/
+       @Override
+       public void onPostExecute(WeatherLocation weatherLocation) {
+
+        this.updateUI(weatherLocation);
+        this.removeProgressFragment();
+
+        this.addButtonsFragment();
+       }
+
+       /*****************************************************************************************************
+        *
+        *                                                      MapProgressFragment
+        * I am not using fragment transactions in the right way. But I do not know other way for doing what I am doing.
+     * Android sucks.
+     *
+     * "Avoid performing transactions inside asynchronous callback methods." :(
+     * see: http://stackoverflow.com/questions/16265733/failure-delivering-result-onactivityforresult
+     * see: http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html
+     * How do you do what I am doing in a different way without using fragments?
+        *****************************************************************************************************/
+       
+       private void addProgressFragment(final double latitude, final double longitude) {
+       final Fragment progressFragment = new MapProgressFragment();
+       progressFragment.setRetainInstance(true);
+       final Bundle args = new Bundle();
+       args.putDouble("latitude", latitude);
+       args.putDouble("longitude", longitude);
+       progressFragment.setArguments(args);
+       
+       final FragmentManager fm = this.getSupportFragmentManager();
+       final FragmentTransaction fragmentTransaction = fm.beginTransaction();
+       fragmentTransaction.setCustomAnimations(R.anim.weather_map_enter_progress, R.anim.weather_map_exit_progress);
+       fragmentTransaction.add(R.id.weather_map_buttons_container, progressFragment, PROGRESS_FRAGMENT_TAG).commit();
+       fm.executePendingTransactions();
+       }
+       
+       private void removeProgressFragment() {
+       final FragmentManager fm = this.getSupportFragmentManager();
+       final Fragment progressFragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
+       if (progressFragment != null) {
+               final FragmentTransaction fragmentTransaction = fm.beginTransaction();
+               fragmentTransaction.remove(progressFragment).commit();
+               fm.executePendingTransactions();
+       }
+       }
+       
+       private void addButtonsFragment() {
+               final FragmentManager fm = this.getSupportFragmentManager();
+       Fragment buttonsFragment = fm.findFragmentByTag(BUTTONS_FRAGMENT_TAG);
+       if (buttonsFragment == null) {
+               buttonsFragment = new MapButtonsFragment();
+               buttonsFragment.setRetainInstance(true);
+               final FragmentTransaction fragmentTransaction = fm.beginTransaction();
+               fragmentTransaction.setCustomAnimations(R.anim.weather_map_enter_progress, R.anim.weather_map_exit_progress);
+               fragmentTransaction.add(R.id.weather_map_buttons_container, buttonsFragment, BUTTONS_FRAGMENT_TAG).commit();
+               fm.executePendingTransactions();
+       }
+       
+       if (this.mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
+               final Button getLocationButton = (Button) this.findViewById(R.id.weather_map_button_getlocation);
+               getLocationButton.setEnabled(true);
+       }
+       }
+       
+       private void removeButtonsFragment() {
+       final FragmentManager fm = this.getSupportFragmentManager();
+       final Fragment buttonsFragment = fm.findFragmentByTag(BUTTONS_FRAGMENT_TAG);
+       if (buttonsFragment != null) {
+               final FragmentTransaction fragmentTransaction = fm.beginTransaction();
+               fragmentTransaction.remove(buttonsFragment).commit();
+               fm.executePendingTransactions();
+       }
+       }
+
+   /*****************************************************************************************************
+    *
+    *                                                  android.location.LocationListener
+    *
+    *****************************************************************************************************/
+       
+       @Override
+       public void onLocationChanged(final Location location) {
+               // It was called from onClickGetLocation (UI thread) This method will run in the same thread (the UI thread)
+               // so, I do no think there should be any problem.
+
+               // Display the current location in the UI
+               // TODO: May location not be null?
+               this.getAddressAndUpdateUI(location.getLatitude(), location.getLongitude());
+       }
+       
+       @Override
+       public void onStatusChanged(String provider, int status, Bundle extras) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void onProviderEnabled(String provider) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void onProviderDisabled(String provider) {
+               // TODO Auto-generated method stub
+               
+       }
+}
diff --git a/app/src/main/java/de/example/exampletdd/NotificationIntentService.java b/app/src/main/java/de/example/exampletdd/NotificationIntentService.java
new file mode 100644 (file)
index 0000000..596b43f
--- /dev/null
@@ -0,0 +1,234 @@
+package de.example.exampletdd;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+import org.apache.http.client.ClientProtocolException;
+
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.http.AndroidHttpClient;
+import android.preference.PreferenceManager;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.NotificationManagerCompat;
+import android.support.v4.app.TaskStackBuilder;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import com.fasterxml.jackson.core.JsonParseException;
+
+import de.example.exampletdd.httpclient.CustomHTTPClient;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
+import de.example.exampletdd.model.currentweather.Current;
+import de.example.exampletdd.parser.JPOSWeatherParser;
+import de.example.exampletdd.service.IconsList;
+import de.example.exampletdd.service.ServiceParser;
+
+public class NotificationIntentService extends IntentService {
+    private static final String TAG = "NotificationIntentService";
+
+
+    public NotificationIntentService() {
+        super("NIS-Thread");
+    }
+
+    @Override
+    protected void onHandleIntent(final Intent intent) {
+        final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        
+        if (weatherLocation != null) {
+            final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser());
+            final CustomHTTPClient HTTPClient = new CustomHTTPClient(
+                    AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent"));
+
+            Current current = null;
+            try {
+               current = this.doInBackgroundThrowable(weatherLocation, HTTPClient, weatherService);
+                
+            } catch (final JsonParseException e) {
+                Log.e(TAG, "doInBackground exception: ", e);
+            } catch (final ClientProtocolException e) {
+                Log.e(TAG, "doInBackground exception: ", e);
+            } catch (final MalformedURLException e) {
+                Log.e(TAG, "doInBackground exception: ", e);
+            } catch (final URISyntaxException e) {
+                Log.e(TAG, "doInBackground exception: ", e);
+            } catch (final IOException e) {
+                // logger infrastructure swallows UnknownHostException :/
+                Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
+            } finally {
+                HTTPClient.close();
+            }
+            
+            if (current != null) {
+               this.showNotification(current, weatherLocation);
+            }
+        }
+    }
+
+    private Current doInBackgroundThrowable(final WeatherLocation weatherLocation,
+            final CustomHTTPClient HTTPClient, final ServiceParser weatherService)
+                    throws ClientProtocolException, MalformedURLException, URISyntaxException,
+                    JsonParseException, IOException {
+
+        final String APIVersion = this.getResources().getString(R.string.api_version);
+
+        final String urlAPI = this.getResources().getString(R.string.uri_api_weather_today);
+        final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
+                weatherLocation.getLatitude(), weatherLocation.getLongitude());
+        final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
+        final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
+        final Current current = weatherService.retrieveCurrentFromJPOS(jsonData);
+        // TODO: what is this for? I guess I could skip it :/
+        final Calendar now = Calendar.getInstance();
+        current.setDate(now.getTime());
+        
+        return current;
+    }
+    
+    private interface UnitsConversor {
+       
+       public double doConversion(final double value);
+    }
+    
+    private void showNotification(final Current current, final WeatherLocation weatherLocation) {
+        final SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(this.getApplicationContext());
+
+               // TODO: repeating the same code in Overview, Specific and Current!!!
+               // 1. Update units of measurement.
+        // 1.1 Temperature
+        String tempSymbol;
+        UnitsConversor tempUnitsConversor;
+        String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key);
+        String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
+        if (unitsPreferenceValue.equals(values[0])) {
+               tempSymbol = values[0];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value - 273.15;
+                               }
+                       
+               };
+        } else if (unitsPreferenceValue.equals(values[1])) {
+               tempSymbol = values[1];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return (value * 1.8) - 459.67;
+                               }
+                       
+               };
+        } else {
+               tempSymbol = values[2];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value;
+                               }
+                       
+               };
+        }
+
+
+        // 2. Formatters
+        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
+        tempFormatter.applyPattern("#####.#####");
+
+
+        // 3. Prepare data for RemoteViews.
+        String tempMax = "";
+        if (current.getMain().getTemp_max() != null) {
+            double conversion = (Double) current.getMain().getTemp_max();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempMax = tempFormatter.format(conversion) + tempSymbol;
+        }
+        String tempMin = "";
+        if (current.getMain().getTemp_min() != null) {
+            double conversion = (Double) current.getMain().getTemp_min();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempMin = tempFormatter.format(conversion) + tempSymbol;
+        }
+        Bitmap picture;
+        if ((current.getWeather().size() > 0)
+                && (current.getWeather().get(0).getIcon() != null)
+                && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) {
+            final String icon = current.getWeather().get(0).getIcon();
+            picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
+                    .getResourceDrawable());
+        } else {
+            picture = BitmapFactory.decodeResource(this.getResources(),
+                    R.drawable.weather_severe_alert);
+        }
+        final String city = weatherLocation.getCity();
+        final String country = weatherLocation.getCountry();
+        
+        // 4. Insert data in RemoteViews.
+        final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.notification);
+        remoteView.setImageViewBitmap(R.id.weather_notification_image, picture);
+        remoteView.setTextViewText(R.id.weather_notification_temperature_max, tempMax);
+        remoteView.setTextViewText(R.id.weather_notification_temperature_min, tempMin);
+        remoteView.setTextViewText(R.id.weather_notification_city, city);
+        remoteView.setTextViewText(R.id.weather_notification_country, country);
+
+        // 5. Activity launcher.
+        final Intent resultIntent =  new Intent(this.getApplicationContext(), WeatherTabsActivity.class);
+        // The PendingIntent to launch our activity if the user selects this notification
+//        final PendingIntent contentIntent = PendingIntent.getActivity(
+//                     this.getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+        // The stack builder object will contain an artificial back stack for the started Activity.
+        // This ensures that navigating backward from the Activity leads out of
+        // your application to the Home screen.
+        final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext());
+        // Adds the back stack for the Intent (but not the Intent itself)
+        stackBuilder.addParentStack(WeatherTabsActivity.class);
+        // Adds the Intent that starts the Activity to the top of the stack
+        stackBuilder.addNextIntent(resultIntent);
+        final PendingIntent resultPendingIntent =
+                       stackBuilder.getPendingIntent(
+                    0,
+                    PendingIntent.FLAG_UPDATE_CURRENT
+                );
+        
+       final NotificationManagerCompat notificationManager =
+                       NotificationManagerCompat.from(this.getApplicationContext());
+       
+
+       // 6. Create notification.
+        final NotificationCompat.Builder notificationBuilder =
+                       new NotificationCompat.Builder(this.getApplicationContext())
+                       .setContent(remoteView)
+                .setSmallIcon(R.drawable.ic_launcher)
+                .setAutoCancel(true)
+                .setLocalOnly(true)
+                .setWhen(System.currentTimeMillis())
+                .setContentIntent(resultPendingIntent)
+                .setPriority(NotificationCompat.PRIORITY_DEFAULT);
+        
+        final Notification notification = notificationBuilder.build();
+        notification.flags |= Notification.FLAG_AUTO_CANCEL;
+
+        // Send the notification.
+        // Sets an ID for the notification, so it can be updated (just in case)
+        int notifyID = 1;
+        notificationManager.notify(notifyID, notification);
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/SpecificActivity.java b/app/src/main/java/de/example/exampletdd/SpecificActivity.java
new file mode 100644 (file)
index 0000000..3cb5da4
--- /dev/null
@@ -0,0 +1,37 @@
+package de.example.exampletdd;
+
+import android.app.ActionBar;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
+
+public class SpecificActivity extends FragmentActivity {
+
+    @Override
+    protected void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        this.setContentView(R.layout.weather_specific);
+
+        final ActionBar actionBar = this.getActionBar();
+
+        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        // 1. Update title.
+        final DatabaseQueries query = new DatabaseQueries(this);
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        if (weatherLocation != null) {
+               final ActionBar actionBar = this.getActionBar();
+            // TODO: I18N and comma :/
+            actionBar.setTitle(weatherLocation.getCity() + "," + weatherLocation.getCountry());        
+        }
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/WeatherInformationBootReceiver.java b/app/src/main/java/de/example/exampletdd/WeatherInformationBootReceiver.java
new file mode 100644 (file)
index 0000000..05b751d
--- /dev/null
@@ -0,0 +1,57 @@
+package de.example.exampletdd;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.SystemClock;
+import android.preference.PreferenceManager;
+
+public class WeatherInformationBootReceiver extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(final Context context, final Intent intent) {
+
+        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
+               
+               // Update Time Rate
+            final SharedPreferences sharedPreferences = PreferenceManager
+                    .getDefaultSharedPreferences(context);
+            final String keyPreference = context
+                    .getString(R.string.weather_preferences_update_time_rate_key);
+            final String updateTimeRate = sharedPreferences.getString(keyPreference, "");            
+            long chosenInterval = 0;
+            if (updateTimeRate.equals("900")) {
+               chosenInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
+            } else if (updateTimeRate.equals("1800")) {
+               chosenInterval = AlarmManager.INTERVAL_HALF_HOUR;
+            } else if (updateTimeRate.equals("3600")) {
+               chosenInterval = AlarmManager.INTERVAL_HOUR;
+            } else if (updateTimeRate.equals("43200")) {
+               chosenInterval = AlarmManager.INTERVAL_HALF_DAY;
+            } else if (updateTimeRate.equals("86400")) {
+               chosenInterval = AlarmManager.INTERVAL_DAY;
+            }
+
+            if (chosenInterval != 0) {
+                final AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+                // TODO: better use some string instead of .class? In case I change the service class
+                // this could be a problem (I guess)
+                final Intent serviceIntent = new Intent(context, NotificationIntentService.class);
+                final PendingIntent alarmIntent = PendingIntent.getService(
+                               context,
+                               0,
+                               serviceIntent,
+                               PendingIntent.FLAG_UPDATE_CURRENT);
+                alarmMgr.setInexactRepeating(
+                               AlarmManager.ELAPSED_REALTIME,
+                               SystemClock.elapsedRealtime() + chosenInterval,
+                               chosenInterval,
+                               alarmIntent);
+            }
+        }
+    }
+
+}
diff --git a/app/src/main/java/de/example/exampletdd/WeatherInformationPreferencesActivity.java b/app/src/main/java/de/example/exampletdd/WeatherInformationPreferencesActivity.java
new file mode 100644 (file)
index 0000000..1e9b0d4
--- /dev/null
@@ -0,0 +1,27 @@
+package de.example.exampletdd;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import de.example.exampletdd.fragment.preferences.WeatherInformationPreferencesFragment;
+
+public class WeatherInformationPreferencesActivity extends Activity {
+
+    @Override
+    protected void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        this.getFragmentManager()
+        .beginTransaction()
+        .replace(android.R.id.content,
+                new WeatherInformationPreferencesFragment()).commit();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final ActionBar actionBar = this.getActionBar();
+        actionBar.setTitle(this.getString(R.string.weather_preferences_action_settings));
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/WeatherTabsActivity.java b/app/src/main/java/de/example/exampletdd/WeatherTabsActivity.java
new file mode 100644 (file)
index 0000000..168ab2e
--- /dev/null
@@ -0,0 +1,182 @@
+package de.example.exampletdd;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.FragmentTransaction;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.Menu;
+import android.view.MenuItem;
+import de.example.exampletdd.fragment.current.CurrentFragment;
+import de.example.exampletdd.fragment.overview.OverviewFragment;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
+
+public class WeatherTabsActivity extends FragmentActivity {
+    private static final int NUM_ITEMS = 2;
+    private ViewPager mPager;
+    
+    @Override
+    protected void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        this.setContentView(R.layout.fragment_pager);
+
+        this.mPager = (ViewPager)this.findViewById(R.id.pager);
+        this.mPager.setAdapter(new TabsAdapter(this.getSupportFragmentManager()));
+
+
+        this.mPager.setOnPageChangeListener(
+                new ViewPager.SimpleOnPageChangeListener() {
+                    @Override
+                    public void onPageSelected(final int position) {
+                        WeatherTabsActivity.this.getActionBar().setSelectedNavigationItem(position);
+                    }
+                });
+
+
+        final ActionBar actionBar = this.getActionBar();
+
+        PreferenceManager.setDefaultValues(this, R.xml.weather_preferences, false);
+
+        // Specify that tabs should be displayed in the action bar.
+        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+        // Create a tab listener that is called when the user changes tabs.
+        final ActionBar.TabListener tabListener = new ActionBar.TabListener() {
+
+            @Override
+            public void onTabSelected(final Tab tab, final FragmentTransaction ft) {
+                WeatherTabsActivity.this.mPager.setCurrentItem(tab.getPosition());
+
+            }
+
+            @Override
+            public void onTabUnselected(final Tab tab, final FragmentTransaction ft) {
+
+            }
+
+            @Override
+            public void onTabReselected(final Tab tab, final FragmentTransaction ft) {
+
+            }
+
+        };
+
+        actionBar.addTab(actionBar.newTab().setText("CURRENTLY").setTabListener(tabListener));
+        actionBar.addTab(actionBar.newTab().setText("FORECAST").setTabListener(tabListener));
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(final Menu menu) {
+
+        this.getMenuInflater().inflate(R.menu.weather_main_menu, menu);
+
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem item) {
+        // Handle action bar item clicks here. The action bar will
+        // automatically handle clicks on the Home/Up button, so long
+        // as you specify a parent activity in AndroidManifest.xml.
+        super.onOptionsItemSelected(item);
+
+        Intent intent;
+        final int itemId = item.getItemId();
+        if (itemId == R.id.weather_menu_settings) {
+            intent = new Intent("de.example.exampletdd.WEATHERINFO")
+            .setComponent(new ComponentName("de.example.exampletdd",
+                    "de.example.exampletdd.WeatherInformationPreferencesActivity"));
+            this.startActivity(intent);
+            return true;
+        } else if (itemId == R.id.weather_menu_map) {
+            intent = new Intent("de.example.exampletdd.WEATHERINFO").
+                       setComponent(new ComponentName("de.example.exampletdd",
+                                       "de.example.exampletdd.MapActivity"));
+            this.startActivity(intent);
+            return true;
+        } else {
+        }
+
+        // TODO: calling again super method?
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(final Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+    }
+
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final ActionBar actionBar = this.getActionBar();
+        
+        // 1. Update title.
+        final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        if (weatherLocation != null) {
+            // TODO: I18N and comma :/
+            actionBar.setTitle(weatherLocation.getCity() + "," + weatherLocation.getCountry());        
+        } else {
+               // TODO: static resource
+               actionBar.setTitle("no chosen location");
+        }
+
+        // 2. Update forecast tab text.
+        final SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(this);
+        final String keyPreference = this.getString(R.string.weather_preferences_day_forecast_key);
+        final String value = sharedPreferences.getString(keyPreference, "");
+        String humanValue = "";
+        if (value.equals("5")) {
+            humanValue = "5 DAY FORECAST";
+        } else if (value.equals("10")) {
+            humanValue = "10 DAY FORECAST";
+        } else if (value.equals("14")) {
+            humanValue = "14 DAY FORECAST";
+        }
+        actionBar.getTabAt(1).setText(humanValue);
+    }
+
+    @Override
+    public void onSaveInstanceState(final Bundle savedInstanceState) {
+        super.onSaveInstanceState(savedInstanceState);
+    }
+
+    private class TabsAdapter extends FragmentPagerAdapter {
+        public TabsAdapter(final FragmentManager fm) {
+            super(fm);
+        }
+
+        @Override
+        public int getCount() {
+            return NUM_ITEMS;
+        }
+
+        @Override
+        public Fragment getItem(final int position) {
+            if (position == 0) {
+               // TODO: new instance every time I click on tab?
+                return new CurrentFragment();
+            } else {
+               // TODO: new instance every time I click on tab?
+                final Fragment fragment = new OverviewFragment();
+                return fragment;
+            }
+
+        }
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/WidgetIntentService.java b/app/src/main/java/de/example/exampletdd/WidgetIntentService.java
new file mode 100644 (file)
index 0000000..ed38545
--- /dev/null
@@ -0,0 +1,304 @@
+package de.example.exampletdd;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+import org.apache.http.client.ClientProtocolException;
+
+import android.app.IntentService;
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.net.http.AndroidHttpClient;
+import android.preference.PreferenceManager;
+import android.support.v4.app.TaskStackBuilder;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import com.fasterxml.jackson.core.JsonParseException;
+
+import de.example.exampletdd.httpclient.CustomHTTPClient;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
+import de.example.exampletdd.model.currentweather.Current;
+import de.example.exampletdd.parser.JPOSWeatherParser;
+import de.example.exampletdd.service.IconsList;
+import de.example.exampletdd.service.PermanentStorage;
+import de.example.exampletdd.service.ServiceParser;
+import de.example.exampletdd.widget.WidgetConfigure;
+
+public class WidgetIntentService extends IntentService {
+       private static final String TAG = "WidgetIntentService";
+
+
+       public WidgetIntentService() {
+               super("WIS-Thread");
+       }
+
+       @Override
+       protected void onHandleIntent(final Intent intent) {
+               Log.i(TAG, "onHandleIntent");
+               final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+               final boolean isUpdateByApp = intent.getBooleanExtra("updateByApp", false);
+
+               if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+                       // Nothing to do. Something went wrong. Show error.
+                       return;
+               }
+
+
+               final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
+               final WeatherLocation weatherLocation = query.queryDataBase();
+               
+               if (weatherLocation == null) {
+                       // Nothing to do. Show error.
+                       final RemoteViews view = this.makeErrorView(appWidgetId);
+                       this.updateWidget(view, appWidgetId);
+                       return;
+               }
+               
+               if (isUpdateByApp) {            
+                       this.updateByApp(weatherLocation, appWidgetId);
+               } else {
+                       this.updateByTimeout(weatherLocation, appWidgetId);
+               }
+
+       }
+
+       private void updateByApp(final WeatherLocation weatherLocation, final int appWidgetId) {
+               final PermanentStorage store = new PermanentStorage(this.getApplicationContext());
+        final Current current = store.getCurrent();
+               
+               this.updateWidget(current, weatherLocation, appWidgetId);
+       }
+       
+       private void updateByTimeout(final WeatherLocation weatherLocation, final int appWidgetId) {
+
+               final Current current = this.getRemoteCurrent(weatherLocation);
+
+               this.updateWidget(current, weatherLocation, appWidgetId);
+       }
+       
+       private void updateWidget(final Current current, final WeatherLocation weatherLocation, final int appWidgetId) {
+
+               if (current != null) {
+                       final RemoteViews view = this.makeView(current, weatherLocation, appWidgetId);
+                       this.updateWidget(view, appWidgetId);
+               } else {
+                       // Show error.
+                       final RemoteViews view = this.makeErrorView(appWidgetId);
+                       this.updateWidget(view, appWidgetId);
+               }
+       }
+
+
+       
+       private Current getRemoteCurrent(final WeatherLocation weatherLocation) {
+
+               final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser());
+               final CustomHTTPClient HTTPClient = new CustomHTTPClient(
+                               AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent"));
+
+               try {
+                       return this.getRemoteCurrentThrowable(weatherLocation, HTTPClient, weatherService);
+
+               } catch (final JsonParseException e) {
+                       Log.e(TAG, "doInBackground exception: ", e);
+               } catch (final ClientProtocolException e) {
+                       Log.e(TAG, "doInBackground exception: ", e);
+               } catch (final MalformedURLException e) {
+                       Log.e(TAG, "doInBackground exception: ", e);
+               } catch (final URISyntaxException e) {
+                       Log.e(TAG, "doInBackground exception: ", e);
+               } catch (final IOException e) {
+                       // logger infrastructure swallows UnknownHostException :/
+                       Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
+               } finally {
+                       HTTPClient.close();
+               }
+
+               return null;
+       }
+
+       private Current getRemoteCurrentThrowable(final WeatherLocation weatherLocation,
+                       final CustomHTTPClient HTTPClient, final ServiceParser weatherService)
+                                       throws ClientProtocolException, MalformedURLException, URISyntaxException,
+                                       JsonParseException, IOException {
+
+               final String APIVersion = this.getResources().getString(R.string.api_version);
+
+               final String urlAPI = this.getResources().getString(R.string.uri_api_weather_today);
+               final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
+                               weatherLocation.getLatitude(), weatherLocation.getLongitude());
+               final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
+               final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
+               final Current current = weatherService.retrieveCurrentFromJPOS(jsonData);
+               // TODO: what is this for? I guess I could skip it :/
+               final Calendar now = Calendar.getInstance();
+               current.setDate(now.getTime());
+
+               return current;
+       }
+
+    private interface UnitsConversor {
+       
+       public double doConversion(final double value);
+    }
+    
+       private RemoteViews makeView(final Current current, final WeatherLocation weatherLocation, final int appWidgetId) {
+               final SharedPreferences sharedPreferences = PreferenceManager
+                               .getDefaultSharedPreferences(this.getApplicationContext());
+
+               // TODO: repeating the same code in Overview, Specific and Current!!!
+               // 1. Update units of measurement.
+        // 1.1 Temperature
+        String tempSymbol;
+        UnitsConversor tempUnitsConversor;
+        String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key);
+        String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
+        if (unitsPreferenceValue.equals(values[0])) {
+               tempSymbol = values[0];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value - 273.15;
+                               }
+                       
+               };
+        } else if (unitsPreferenceValue.equals(values[1])) {
+               tempSymbol = values[1];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return (value * 1.8) - 459.67;
+                               }
+                       
+               };
+        } else {
+               tempSymbol = values[2];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value;
+                               }
+                       
+               };
+        }
+
+
+               // 2. Formatters
+               final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
+               tempFormatter.applyPattern("#####.#####");
+
+
+               // 3. Prepare data for RemoteViews.
+               String tempMax = "";
+               if (current.getMain().getTemp_max() != null) {
+                       double conversion = (Double) current.getMain().getTemp_max();
+                       conversion = tempUnitsConversor.doConversion(conversion);
+                       tempMax = tempFormatter.format(conversion) + tempSymbol;
+               }
+               String tempMin = "";
+               if (current.getMain().getTemp_min() != null) {
+                       double conversion = (Double) current.getMain().getTemp_min();
+                       conversion = tempUnitsConversor.doConversion(conversion);
+                       tempMin = tempFormatter.format(conversion) + tempSymbol;
+               }
+               Bitmap picture;
+               if ((current.getWeather().size() > 0)
+                               && (current.getWeather().get(0).getIcon() != null)
+                               && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) {
+                       final String icon = current.getWeather().get(0).getIcon();
+                       picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
+                                       .getResourceDrawable());
+               } else {
+                       picture = BitmapFactory.decodeResource(this.getResources(),
+                                       R.drawable.weather_severe_alert);
+               }
+               final String city = weatherLocation.getCity();
+               final String country = weatherLocation.getCountry();
+
+               // 4. Insert data in RemoteViews.
+               final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.appwidget);
+               remoteView.setImageViewBitmap(R.id.weather_appwidget_image, picture);
+               remoteView.setTextViewText(R.id.weather_appwidget_temperature_max, tempMax);
+               remoteView.setTextViewText(R.id.weather_appwidget_temperature_min, tempMin);
+               remoteView.setTextViewText(R.id.weather_appwidget_city, city);
+               remoteView.setTextViewText(R.id.weather_appwidget_country, country);
+
+               // 5. Activity launcher.
+               final Intent resultIntent =  new Intent(this.getApplicationContext(), WidgetConfigure.class);
+               resultIntent.putExtra("actionFromUser", true);
+               resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+               // From: http://stackoverflow.com/questions/4011178/multiple-instances-of-widget-only-updating-last-widget
+               final Uri data = Uri.withAppendedPath(Uri.parse("PAIN" + "://widget/id/") ,String.valueOf(appWidgetId));
+               resultIntent.setData(data);
+
+               final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext());
+               // Adds the back stack for the Intent (but not the Intent itself)
+               stackBuilder.addParentStack(WidgetConfigure.class);
+               // Adds the Intent that starts the Activity to the top of the stack
+               stackBuilder.addNextIntent(resultIntent);
+               final PendingIntent resultPendingIntent =
+                               stackBuilder.getPendingIntent(
+                                               0,
+                                               PendingIntent.FLAG_UPDATE_CURRENT
+                                               );
+               remoteView.setOnClickPendingIntent(R.id.weather_appwidget, resultPendingIntent);
+               
+               return remoteView;
+       }
+       
+       private RemoteViews makeErrorView(final int appWidgetId) {
+               final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.appwidget_error);
+
+               // 5. Activity launcher.
+               final Intent resultIntent =  new Intent(this.getApplicationContext(), WidgetConfigure.class);
+               resultIntent.putExtra("actionFromUser", true);
+               resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+               // From: http://stackoverflow.com/questions/4011178/multiple-instances-of-widget-only-updating-last-widget
+               final Uri data = Uri.withAppendedPath(Uri.parse("PAIN" + "://widget/id/") ,String.valueOf(appWidgetId));
+               resultIntent.setData(data);
+
+               final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext());
+               // Adds the back stack for the Intent (but not the Intent itself)
+               stackBuilder.addParentStack(WidgetConfigure.class);
+               // Adds the Intent that starts the Activity to the top of the stack
+               stackBuilder.addNextIntent(resultIntent);
+               final PendingIntent resultPendingIntent =
+                               stackBuilder.getPendingIntent(
+                                               0,
+                                               PendingIntent.FLAG_UPDATE_CURRENT
+                                               );
+               remoteView.setOnClickPendingIntent(R.id.weather_appwidget_error, resultPendingIntent);
+
+               return remoteView;
+       }
+
+       private void updateWidget(final RemoteViews remoteView, final int appWidgetId) {
+               
+               final AppWidgetManager manager = AppWidgetManager.getInstance(this.getApplicationContext());
+               manager.updateAppWidget(appWidgetId, remoteView);
+       }
+       
+//     private void updateWidgets(final RemoteViews remoteView) {
+//             
+//             final ComponentName widgets = new ComponentName(this.getApplicationContext(), WidgetProvider.class);
+//             final AppWidgetManager manager = AppWidgetManager.getInstance(this.getApplicationContext());
+//             manager.updateAppWidget(widgets, remoteView);
+//     }
+}
diff --git a/app/src/main/java/de/example/exampletdd/dummy/DummyContent.java b/app/src/main/java/de/example/exampletdd/dummy/DummyContent.java
new file mode 100644 (file)
index 0000000..6c09241
--- /dev/null
@@ -0,0 +1,55 @@
+package de.example.exampletdd.dummy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper class for providing sample content for user interfaces created by
+ * Android template wizards.
+ * <p>
+ * TODO: Replace all uses of this class before publishing your app.
+ */
+public class DummyContent {
+
+    /**
+     * An array of sample (dummy) items.
+     */
+    public static List<DummyItem> ITEMS = new ArrayList<DummyItem>();
+
+    /**
+     * A map of sample (dummy) items, by ID.
+     */
+    public static Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
+
+    static {
+        // Add 3 sample items.
+        addItem(new DummyItem("1", "Item 1"));
+        addItem(new DummyItem("2", "Item 2"));
+        addItem(new DummyItem("3", "Item 3"));
+    }
+
+    private static void addItem(DummyItem item) {
+        ITEMS.add(item);
+        ITEM_MAP.put(item.id, item);
+    }
+
+    /**
+     * A dummy item representing a piece of content.
+     */
+    public static class DummyItem {
+        public String id;
+        public String content;
+
+        public DummyItem(String id, String content) {
+            this.id = id;
+            this.content = content;
+        }
+
+        @Override
+        public String toString() {
+            return content;
+        }
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/ErrorDialogFragment.java b/app/src/main/java/de/example/exampletdd/fragment/ErrorDialogFragment.java
new file mode 100644 (file)
index 0000000..5d00707
--- /dev/null
@@ -0,0 +1,45 @@
+package de.example.exampletdd.fragment;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+
+public class ErrorDialogFragment extends DialogFragment {
+
+    public static ErrorDialogFragment newInstance(final int title) {
+        final ErrorDialogFragment frag = new ErrorDialogFragment();
+        final Bundle args = new Bundle();
+
+        args.putInt("title", title);
+        frag.setArguments(args);
+
+        return frag;
+    }
+
+    @Override
+    public Dialog onCreateDialog(final Bundle savedInstanceState) {
+        final int title = this.getArguments().getInt("title");
+
+        return new AlertDialog.Builder(this.getActivity())
+        .setIcon(android.R.drawable.ic_dialog_alert)
+        .setTitle(title)
+        .setPositiveButton(android.R.string.ok,
+                new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(final DialogInterface dialog,
+                    final int whichButton) {
+
+            }
+        }).create();
+    }
+    
+    @Override
+    public void onDestroyView() {
+       if (getDialog() != null && getRetainInstance()) {
+               getDialog().setDismissMessage(null);
+       }
+       super.onDestroyView();
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/example/exampletdd/fragment/ProgressDialogFragment.java b/app/src/main/java/de/example/exampletdd/fragment/ProgressDialogFragment.java
new file mode 100644 (file)
index 0000000..7ff9960
--- /dev/null
@@ -0,0 +1,54 @@
+package de.example.exampletdd.fragment;
+
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.view.KeyEvent;
+
+public class ProgressDialogFragment extends DialogFragment {
+
+    public static ProgressDialogFragment newInstance(final int title) {
+        return newInstance(title, null);
+    }
+
+    public static ProgressDialogFragment newInstance(final int title,
+            final String message) {
+        final ProgressDialogFragment frag = new ProgressDialogFragment();
+        final Bundle args = new Bundle();
+
+        args.putInt("title", title);
+        args.putString("message", message);
+        frag.setArguments(args);
+        return frag;
+    }
+
+    @Override
+    public Dialog onCreateDialog(final Bundle savedInstanceState) {
+        final int title = this.getArguments().getInt("title");
+        final String message = this.getArguments().getString("message");
+
+        final ProgressDialog dialog = new ProgressDialog(this.getActivity());
+        dialog.setIcon(android.R.drawable.ic_dialog_info);
+        if (title != 0) {
+            dialog.setTitle(title);
+        }
+        if (message != null) {
+            dialog.setMessage(message);
+        }
+        dialog.setCancelable(false);
+        this.setCancelable(false);
+        dialog.setIndeterminate(true);
+        dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
+
+            @Override
+            public final boolean onKey(final DialogInterface dialog,
+                    final int keyCode, final KeyEvent event) {
+                return false;
+            }
+        });
+
+        return dialog;
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/current/CurrentFragment.java b/app/src/main/java/de/example/exampletdd/fragment/current/CurrentFragment.java
new file mode 100644 (file)
index 0000000..13f9a77
--- /dev/null
@@ -0,0 +1,528 @@
+package de.example.exampletdd.fragment.current;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.http.client.ClientProtocolException;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.fasterxml.jackson.core.JsonParseException;
+
+import de.example.exampletdd.R;
+import de.example.exampletdd.WidgetIntentService;
+import de.example.exampletdd.httpclient.CustomHTTPClient;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
+import de.example.exampletdd.model.currentweather.Current;
+import de.example.exampletdd.parser.JPOSWeatherParser;
+import de.example.exampletdd.service.IconsList;
+import de.example.exampletdd.service.PermanentStorage;
+import de.example.exampletdd.service.ServiceParser;
+
+public class CurrentFragment extends Fragment {
+    private static final String TAG = "CurrentFragment";
+    private BroadcastReceiver mReceiver;
+
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+    
+       // Inflate the layout for this fragment
+        return inflater.inflate(R.layout.weather_current_fragment, container, false);
+    }
+    
+    @Override
+    public void onActivityCreated(final Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        if (savedInstanceState != null) {
+               // Restore UI state
+            final Current current = (Current) savedInstanceState.getSerializable("Current");
+
+            // TODO: Could it be better to store in global forecast data even if it is null value?
+            //       So, perhaps do not check for null value and always store in global variable.
+            if (current != null) {
+               final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+               store.saveCurrent(current);
+            }
+        }     
+        
+        this.setHasOptionsMenu(false);
+
+        this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE);
+        this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.VISIBLE);
+       this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE);   
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+
+        this.mReceiver = new BroadcastReceiver() {
+
+                       @Override
+                       public void onReceive(final Context context, final Intent intent) {
+                               final String action = intent.getAction();
+                               if (action.equals("de.example.exampletdd.UPDATECURRENT")) {
+                                       final Current currentRemote = (Current) intent.getSerializableExtra("current");
+
+                                       if (currentRemote != null) {
+
+                                               // 1. Check conditions. They must be the same as the ones that triggered the AsyncTask.
+                                               final DatabaseQueries query = new DatabaseQueries(context.getApplicationContext());
+                                   final WeatherLocation weatherLocation = query.queryDataBase();
+                                   final PermanentStorage store = new PermanentStorage(context.getApplicationContext());
+                                   final Current current = store.getCurrent();
+
+                                   if (current == null || !CurrentFragment.this.isDataFresh(weatherLocation.getLastCurrentUIUpdate())) {
+                                       // 2. Update UI.
+                                       CurrentFragment.this.updateUI(currentRemote);
+
+                                       // 3. Update Data.
+                                                       store.saveCurrent(currentRemote);
+                                           weatherLocation.setLastCurrentUIUpdate(new Date());
+                                           query.updateDataBase(weatherLocation);
+                                   }
+
+                                       } else {
+                                               // Empty UI and show error message
+                                               CurrentFragment.this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE);
+                                               CurrentFragment.this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.GONE);
+                                               CurrentFragment.this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.VISIBLE);
+                                       }
+                               }
+                       }
+        };
+
+        // Register receiver
+        final IntentFilter filter = new IntentFilter();
+        filter.addAction("de.example.exampletdd.UPDATECURRENT");
+        LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext())
+                                                       .registerReceiver(this.mReceiver, filter);
+
+        // Empty UI
+        this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE);
+        
+        final DatabaseQueries query = new DatabaseQueries(this.getActivity().getApplicationContext());
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        if (weatherLocation == null) {
+            // Nothing to do.
+               // Show error message
+               final ProgressBar progress = (ProgressBar) getActivity().findViewById(R.id.weather_current_progressbar);
+               progress.setVisibility(View.GONE);
+                       final TextView errorMessage = (TextView) getActivity().findViewById(R.id.weather_current_error_message);
+               errorMessage.setVisibility(View.VISIBLE);
+            return;
+        }
+
+        final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+        final Current current = store.getCurrent();
+
+        if (current != null && this.isDataFresh(weatherLocation.getLastCurrentUIUpdate())) {
+            this.updateUI(current);
+        } else {
+            // Load remote data (aynchronous)
+            // Gets the data from the web.
+               this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.VISIBLE);
+               this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE);
+            final CurrentTask task = new CurrentTask(
+                       this.getActivity().getApplicationContext(),
+                    new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")),
+                    new ServiceParser(new JPOSWeatherParser()));
+
+            task.execute(weatherLocation.getLatitude(), weatherLocation.getLongitude());
+            // TODO: make sure UI thread keeps running in parallel after that. I guess.
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(final Bundle savedInstanceState) {
+
+        // Save UI state
+       final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+        final Current current = store.getCurrent();
+
+        // TODO: Could it be better to save current data even if it is null value?
+        //       So, perhaps do not check for null value.
+        if (current != null) {
+            savedInstanceState.putSerializable("Current", current);
+        }
+
+        super.onSaveInstanceState(savedInstanceState);
+    }
+
+    @Override
+    public void onPause() {
+        LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext()).unregisterReceiver(this.mReceiver);
+
+        super.onPause();
+    }
+
+    private interface UnitsConversor {
+       
+       public double doConversion(final double value);
+    }
+
+    private void updateUI(final Current current) {
+       
+        final SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(this.getActivity().getApplicationContext());
+
+        // TODO: repeating the same code in Overview, Specific and Current!!!
+        // 1. Update units of measurement.
+        // 1.1 Temperature
+        String tempSymbol;
+        UnitsConversor tempUnitsConversor;
+        String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key);
+        String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
+        if (unitsPreferenceValue.equals(values[0])) {
+               tempSymbol = values[0];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value - 273.15;
+                               }
+                       
+               };
+        } else if (unitsPreferenceValue.equals(values[1])) {
+               tempSymbol = values[1];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return (value * 1.8) - 459.67;
+                               }
+                       
+               };
+        } else {
+               tempSymbol = values[2];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value;
+                               }
+                       
+               };
+        }
+
+        // 1.2 Wind
+        String windSymbol;
+        UnitsConversor windUnitsConversor;
+        keyPreference = this.getResources().getString(R.string.weather_preferences_wind_key);
+        unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        values = this.getResources().getStringArray(R.array.weather_preferences_wind);
+        if (unitsPreferenceValue.equals(values[0])) {
+               windSymbol = values[0];
+               windUnitsConversor = new UnitsConversor(){
+
+                       @Override
+                       public double doConversion(double value) {
+                               return value;
+                       }       
+               };
+        } else {
+               windSymbol = values[1];
+               windUnitsConversor = new UnitsConversor(){
+
+                       @Override
+                       public double doConversion(double value) {
+                               return value * 2.237;
+                       }       
+               };
+        }
+
+        // 1.3 Pressure
+        String pressureSymbol;
+        UnitsConversor pressureUnitsConversor;
+        keyPreference = this.getResources().getString(R.string.weather_preferences_pressure_key);
+        unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        values = this.getResources().getStringArray(R.array.weather_preferences_pressure);
+        if (unitsPreferenceValue.equals(values[0])) {
+               pressureSymbol = values[0];
+               pressureUnitsConversor = new UnitsConversor(){
+
+                       @Override
+                       public double doConversion(double value) {
+                               return value;
+                       }       
+               };
+        } else {
+               pressureSymbol = values[1];
+               pressureUnitsConversor = new UnitsConversor(){
+
+                       @Override
+                       public double doConversion(double value) {
+                               return value / 113.25d;
+                       }       
+               };
+        }
+
+
+        // 2. Formatters
+        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
+        tempFormatter.applyPattern("#####.#####");
+        final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.US);
+
+        
+        // 3. Prepare data for UI.
+        String tempMax = "";
+        if (current.getMain().getTemp_max() != null) {
+            double conversion = (Double) current.getMain().getTemp_max();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempMax = tempFormatter.format(conversion) + tempSymbol;
+        }
+        String tempMin = "";
+        if (current.getMain().getTemp_min() != null) {
+            double conversion = (Double) current.getMain().getTemp_min();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempMin = tempFormatter.format(conversion) + tempSymbol;
+        }
+        Bitmap picture;
+        if ((current.getWeather().size() > 0)
+                && (current.getWeather().get(0).getIcon() != null)
+                && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) {
+            final String icon = current.getWeather().get(0).getIcon();
+            picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
+                    .getResourceDrawable());
+        } else {
+            picture = BitmapFactory.decodeResource(this.getResources(),
+                    R.drawable.weather_severe_alert);
+        }
+
+        // TODO: static resource
+        String description = "no description available";
+        if (current.getWeather().size() > 0) {
+            description = current.getWeather().get(0).getDescription();
+        }
+
+        // TODO: units!!!!
+        String humidityValue = "";
+        if ((current.getMain() != null)
+                && (current.getMain().getHumidity() != null)) {
+            final double conversion = (Double) current.getMain().getHumidity();
+            humidityValue = tempFormatter.format(conversion);
+        }
+        String pressureValue = "";
+        if ((current.getMain() != null)
+                && (current.getMain().getPressure() != null)) {
+            double conversion = (Double) current.getMain().getPressure();
+            conversion = pressureUnitsConversor.doConversion(conversion);
+            pressureValue = tempFormatter.format(conversion);
+        }
+        String windValue = "";
+        if ((current.getWind() != null)
+                && (current.getWind().getSpeed() != null)) {
+            double conversion = (Double) current.getWind().getSpeed();
+            conversion = windUnitsConversor.doConversion(conversion);
+            windValue = tempFormatter.format(conversion);
+        }
+        String rainValue = "";
+        if ((current.getRain() != null)
+                && (current.getRain().get3h() != null)) {
+            final double conversion = (Double) current.getRain().get3h();
+            rainValue = tempFormatter.format(conversion);
+        }
+        String cloudsValue = "";
+        if ((current.getClouds() != null)
+                && (current.getClouds().getAll() != null)) {
+            final double conversion = (Double) current.getClouds().getAll();
+            cloudsValue = tempFormatter.format(conversion);
+        }
+        String snowValue = "";
+        if ((current.getSnow() != null)
+                && (current.getSnow().get3h() != null)) {
+            final double conversion = (Double) current.getSnow().get3h();
+            snowValue = tempFormatter.format(conversion);
+        }
+        String feelsLike = "";
+        if (current.getMain().getTemp() != null) {
+            double conversion = (Double) current.getMain().getTemp();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            feelsLike = tempFormatter.format(conversion);
+        }
+        String sunRiseTime = "";
+        if (current.getSys().getSunrise() != null) {
+            final long unixTime = (Long) current.getSys().getSunrise();
+            final Date unixDate = new Date(unixTime * 1000L);
+            sunRiseTime = dateFormat.format(unixDate);
+        }
+        String sunSetTime = "";
+        if (current.getSys().getSunset() != null) {
+            final long unixTime = (Long) current.getSys().getSunset();
+            final Date unixDate = new Date(unixTime * 1000L);
+            sunSetTime = dateFormat.format(unixDate);
+        }
+
+
+        // 4. Update UI.
+        final TextView tempMaxView = (TextView) getActivity().findViewById(R.id.weather_current_temp_max);
+        tempMaxView.setText(tempMax);
+        final TextView tempMinView = (TextView) getActivity().findViewById(R.id.weather_current_temp_min);
+        tempMinView.setText(tempMin);
+        final ImageView pictureView = (ImageView) getActivity().findViewById(R.id.weather_current_picture);
+        pictureView.setImageBitmap(picture);    
+        
+        final TextView descriptionView = (TextView) getActivity().findViewById(R.id.weather_current_description);
+        descriptionView.setText(description);
+        
+        ((TextView) getActivity().findViewById(R.id.weather_current_humidity_value)).setText(humidityValue);
+        ((TextView) getActivity().findViewById(R.id.weather_current_humidity_units)).setText(
+                       this.getActivity().getApplicationContext().getString(R.string.text_units_percent));
+        
+        ((TextView) getActivity().findViewById(R.id.weather_current_pressure_value)).setText(pressureValue);
+        ((TextView) getActivity().findViewById(R.id.weather_current_pressure_units)).setText(pressureSymbol);
+        
+        ((TextView) getActivity().findViewById(R.id.weather_current_wind_value)).setText(windValue);
+        ((TextView) getActivity().findViewById(R.id.weather_current_wind_units)).setText(windSymbol);
+        
+        ((TextView) getActivity().findViewById(R.id.weather_current_rain_value)).setText(rainValue);
+        ((TextView) getActivity().findViewById(R.id.weather_current_rain_units)).setText(
+                       this.getActivity().getApplicationContext().getString(R.string.text_units_mm3h));
+        
+        ((TextView) getActivity().findViewById(R.id.weather_current_clouds_value)).setText(cloudsValue);
+        ((TextView) getActivity().findViewById(R.id.weather_current_clouds_units)).setText(
+                       this.getActivity().getApplicationContext().getString(R.string.text_units_percent));
+        
+        ((TextView) getActivity().findViewById(R.id.weather_current_snow_value)).setText(snowValue);
+        ((TextView) getActivity().findViewById(R.id.weather_current_snow_units)).setText(
+                       this.getActivity().getApplicationContext().getString(R.string.text_units_mm3h));
+        
+        ((TextView) getActivity().findViewById(R.id.weather_current_feelslike_value)).setText(feelsLike);
+        ((TextView) getActivity().findViewById(R.id.weather_current_feelslike_units)).setText(tempSymbol);
+        
+        ((TextView) getActivity().findViewById(R.id.weather_current_sunrise_value)).setText(sunRiseTime);
+
+        ((TextView) getActivity().findViewById(R.id.weather_current_sunset_value)).setText(sunSetTime);
+        
+        this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.VISIBLE);
+        this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.GONE);
+        this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE);       
+    }
+    
+    private boolean isDataFresh(final Date lastUpdate) {
+       if (lastUpdate == null) {
+               return false;
+       }
+       
+       final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(
+                       this.getActivity().getApplicationContext());
+        final String keyPreference = this.getString(R.string.weather_preferences_refresh_interval_key);
+        final String refresh = sharedPreferences.getString(
+                       keyPreference,
+                       this.getResources().getStringArray(R.array.weather_preferences_refresh_interval)[0]);
+        final Date currentTime = new Date();
+       if (((currentTime.getTime() - lastUpdate.getTime())) < Long.valueOf(refresh)) {
+               return true;
+       }
+       
+       return false;
+    }
+    
+    // TODO: How could I show just one progress dialog when I have two fragments in tabs
+    //       activity doing the same in background?
+    //       I mean, if OverviewTask shows one progress dialog and CurrentTask does the same I will have
+    //       have two progress dialogs... How may I solve this problem? I HATE ANDROID.
+    private class CurrentTask extends AsyncTask<Object, Void, Current> {
+       // Store the context passed to the AsyncTask when the system instantiates it.
+        private final Context localContext;
+        final CustomHTTPClient HTTPClient;
+        final ServiceParser weatherService;
+
+        public CurrentTask(final Context context, final CustomHTTPClient HTTPClient,
+                       final ServiceParser weatherService) {
+               this.localContext = context;
+            this.HTTPClient = HTTPClient;
+            this.weatherService = weatherService;
+        }
+
+        @Override
+        protected Current doInBackground(final Object... params) {
+               final double latitude = (Double) params[0];
+            final double longitude = (Double) params[1];
+  
+            Current current = null;
+            try {
+               current = this.doInBackgroundThrowable(latitude, longitude);
+            } catch (final JsonParseException e) {
+                Log.e(TAG, "CurrentTask doInBackground exception: ", e);
+            } catch (final ClientProtocolException e) {
+                Log.e(TAG, "CurrentTask doInBackground exception: ", e);
+            } catch (final MalformedURLException e) {
+                Log.e(TAG, "CurrentTask doInBackground exception: ", e);
+            } catch (final URISyntaxException e) {
+                Log.e(TAG, "CurrentTask doInBackground exception: ", e);
+            } catch (final IOException e) {
+                // logger infrastructure swallows UnknownHostException :/
+                Log.e(TAG, "CurrentTask doInBackground exception: " + e.getMessage(), e);
+            } finally {
+               HTTPClient.close();
+            }
+
+            return current;
+        }
+
+        private Current doInBackgroundThrowable(final double latitude, final double longitude)
+                        throws URISyntaxException, ClientProtocolException, JsonParseException, IOException {
+
+               final String APIVersion = localContext.getResources().getString(R.string.api_version);
+            final String urlAPI = localContext.getResources().getString(R.string.uri_api_weather_today);
+            final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion, latitude, longitude);
+            final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
+            final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
+            final Current current = weatherService.retrieveCurrentFromJPOS(jsonData);
+            // TODO: what is this for? I guess I could skip it :/
+            final Calendar now = Calendar.getInstance();
+            current.setDate(now.getTime());
+
+            return current;
+        }
+
+        @Override
+        protected void onPostExecute(final Current current) {
+               // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method?
+               // I hope so, otherwise I must catch(Throwable) in doInBackground method :(
+
+            // Call updateUI on the UI thread.
+            final Intent currentData = new Intent("de.example.exampletdd.UPDATECURRENT");
+            currentData.putExtra("current", current);
+            LocalBroadcastManager.getInstance(this.localContext).sendBroadcastSync(currentData);
+        }
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/map/MapButtonsFragment.java b/app/src/main/java/de/example/exampletdd/fragment/map/MapButtonsFragment.java
new file mode 100644 (file)
index 0000000..a063eb5
--- /dev/null
@@ -0,0 +1,31 @@
+package de.example.exampletdd.fragment.map;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import de.example.exampletdd.R;
+
+public class MapButtonsFragment extends Fragment {
+       
+    @Override
+    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+                             final Bundle savedInstanceState) {
+    
+       // Inflate the layout for this fragment
+        return inflater.inflate(R.layout.weather_map_buttons, container, false);
+    }
+    
+    /**
+     * This method will only be called once when the retained
+     * Fragment is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+       super.onCreate(savedInstanceState);
+       
+       // Retain this fragment across configuration changes.
+       this.setRetainInstance(true);
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/map/MapProgressFragment.java b/app/src/main/java/de/example/exampletdd/fragment/map/MapProgressFragment.java
new file mode 100644 (file)
index 0000000..aa4b6e4
--- /dev/null
@@ -0,0 +1,165 @@
+package de.example.exampletdd.fragment.map;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+import android.app.Activity;
+import android.content.Context;
+import android.location.Address;
+import android.location.Geocoder;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import de.example.exampletdd.R;
+import de.example.exampletdd.model.WeatherLocation;
+
+/**
+ * {@link http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html}
+ *
+ */
+public class MapProgressFragment extends Fragment {
+
+       /**
+        * 
+        * Callback interface through which the fragment will report the
+        * task's progress and results back to the Activity.
+        */
+       public static interface TaskCallbacks {
+               void onPostExecute(final WeatherLocation weatherLocation);
+       }
+       
+       private TaskCallbacks mCallbacks;
+       
+    @Override
+    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+                             final Bundle savedInstanceState) {
+    
+       // Inflate the layout for this fragment
+        return inflater.inflate(R.layout.weather_map_progress, container, false);
+    }
+    
+    /**
+     * This method will only be called once when the retained
+     * Fragment is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+       super.onCreate(savedInstanceState);
+       
+       // Retain this fragment across configuration changes.
+       this.setRetainInstance(true);
+       
+       final Bundle bundle = this.getArguments();
+       double latitude = bundle.getDouble("latitude");
+       double longitude = bundle.getDouble("longitude");
+       
+       // Create and execute the background task.
+       new GetAddressTask(this.getActivity().getApplicationContext()).execute(latitude, longitude);
+    }
+    
+       /**
+        * Hold a reference to the parent Activity so we can report the
+        * task's current progress and results. The Android framework 
+        * will pass us a reference to the newly created Activity after 
+        * each configuration change.
+        */
+       @Override
+       public void onAttach(final Activity activity) {
+               super.onAttach(activity);
+               mCallbacks = (TaskCallbacks) activity;
+       }
+       
+       /**
+        * Set the callback to null so we don't accidentally leak the 
+        * Activity instance.
+        */
+//     @Override
+//     public void onDetach() {
+//             super.onDetach();
+//             mCallbacks = null;
+//     }
+       
+       /**
+        * I am not using onDetach because there are problems when my activity goes to background.
+        * 
+        * {@link http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html}
+        */
+       @Override
+       public void onPause() {
+               super.onPause();
+               mCallbacks = null;
+       }
+    
+    private class GetAddressTask extends AsyncTask<Object, Void, WeatherLocation> {
+        private static final String TAG = "GetAddressTask";
+        // Store the context passed to the AsyncTask when the system instantiates it.
+        private final Context localContext;
+
+        private GetAddressTask(final Context context) {
+               this.localContext = context;    
+        }
+        
+        @Override
+        protected WeatherLocation doInBackground(final Object... params) {
+            final double latitude = (Double) params[0];
+            final double longitude = (Double) params[1];
+
+            WeatherLocation weatherLocation = this.doDefaultLocation(latitude, longitude);
+            try {
+               weatherLocation = this.getLocation(latitude, longitude);
+            } catch (final Throwable e) { // Hopefully nothing goes wrong because of catching Throwable.
+                Log.e(TAG, "GetAddressTask doInBackground exception: ", e);
+            }
+
+            return weatherLocation;
+        }
+
+        @Override
+        protected void onPostExecute(final WeatherLocation weatherLocation) {
+               // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method?
+               // I hope so, otherwise I must catch(Throwable) in doInBackground method :(
+            // Call updateUI on the UI thread.
+               if (mCallbacks != null) {
+                       mCallbacks.onPostExecute(weatherLocation);
+               }
+        }
+        
+        private WeatherLocation getLocation(final double latitude, final double longitude) throws IOException {
+               // TODO: i18n Locale.getDefault()
+            final Geocoder geocoder = new Geocoder(this.localContext, Locale.US);
+            final List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
+
+            // Default values
+            WeatherLocation weatherLocation = this.doDefaultLocation(latitude, longitude);
+            
+            if (addresses != null && addresses.size() > 0) {
+               if (addresses.get(0).getLocality() != null) {
+                       weatherLocation.setCity(addresses.get(0).getLocality());
+               }
+               if(addresses.get(0).getCountryName() != null) {
+                       weatherLocation.setCountry(addresses.get(0).getCountryName());
+               }       
+            }
+
+            return weatherLocation;
+        }
+
+        private WeatherLocation doDefaultLocation(final double latitude, final double longitude) {
+               // Default values
+            String city = this.localContext.getString(R.string.city_not_found);
+            String country = this.localContext.getString(R.string.country_not_found);
+
+            return new WeatherLocation()
+                       .setLatitude(latitude)
+                       .setLongitude(longitude)
+                       .setCity(city)
+                       .setCountry(country);
+        }
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewAdapter.java b/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewAdapter.java
new file mode 100644 (file)
index 0000000..13641b6
--- /dev/null
@@ -0,0 +1,108 @@
+package de.example.exampletdd.fragment.overview;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+import de.example.exampletdd.R;
+
+public class OverviewAdapter extends ArrayAdapter<OverviewEntry> {
+    private final int resource;
+
+    public OverviewAdapter(final Context context, final int resource) {
+        super(context, 0);
+
+        this.resource = resource;
+    }
+
+    @Override
+    public View getView(final int position, final View convertView,
+            final ViewGroup parent) {
+
+        // We need to get the best view (re-used if possible) and then
+        // retrieve its corresponding ViewHolder, which optimizes lookup
+        // efficiency
+        final View view = this.getWorkingView(convertView);
+        final ViewHolder viewHolder = this.getViewHolder(view);
+        final OverviewEntry entry = this.getItem(position);
+
+
+        // Setting date
+        viewHolder.dateNameView.setText(entry.getDateName());
+        viewHolder.dateNumberView.setText(entry.getDateNumber());
+
+        // Setting temperature max/min
+        viewHolder.temperatureMaxView.setText(entry.getMaxTemp());
+        viewHolder.temperatureMinView.setText(entry.getMinTemp());
+
+        // Set image view
+        viewHolder.pictureView.setImageBitmap(entry.getPicture());
+
+
+        return view;
+    }
+
+    private View getWorkingView(final View convertView) {
+        // The workingView is basically just the convertView re-used if possible
+        // or inflated new if not possible
+        View workingView = null;
+
+        if(null == convertView) {
+            final Context context = this.getContext();
+            final LayoutInflater inflater = (LayoutInflater)context.getSystemService
+                    (Context.LAYOUT_INFLATER_SERVICE);
+
+            workingView = inflater.inflate(this.resource, null);
+        } else {
+            workingView = convertView;
+        }
+
+        return workingView;
+    }
+
+    private ViewHolder getViewHolder(final View workingView) {
+        // The viewHolder allows us to avoid re-looking up view references
+        // Since views are recycled, these references will never change
+        final Object tag = workingView.getTag();
+        ViewHolder viewHolder = null;
+
+
+        if((null == tag) || !(tag instanceof ViewHolder)) {
+            viewHolder = new ViewHolder();
+
+            viewHolder.dateNameView = (TextView) workingView
+                    .findViewById(R.id.weather_main_entry_date_name);
+            viewHolder.dateNumberView = (TextView) workingView
+                    .findViewById(R.id.weather_main_entry_date_number);
+            viewHolder.temperatureMaxView = (TextView) workingView
+                    .findViewById(R.id.weather_main_entry_temperature_max);
+            viewHolder.temperatureMinView = (TextView) workingView
+                    .findViewById(R.id.weather_main_entry_temperature_min);
+            viewHolder.pictureView = (ImageView) workingView
+                    .findViewById(R.id.weather_main_entry_image);
+
+            workingView.setTag(viewHolder);
+
+        } else {
+            viewHolder = (ViewHolder) tag;
+        }
+
+        return viewHolder;
+    }
+
+    /**
+     * ViewHolder allows us to avoid re-looking up view references
+     * Since views are recycled, these references will never change
+     */
+    private static class ViewHolder {
+        public TextView dateNameView;
+        public TextView dateNumberView;
+        public TextView temperatureMaxView;
+        public TextView temperatureMinView;
+        public ImageView pictureView;
+    }
+
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewEntry.java b/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewEntry.java
new file mode 100644 (file)
index 0000000..16135f9
--- /dev/null
@@ -0,0 +1,41 @@
+package de.example.exampletdd.fragment.overview;
+
+import android.graphics.Bitmap;
+
+public class OverviewEntry {
+    private final String dateName;
+    private final String dateNumber;
+    private final String maxTemp;
+    private final String minTemp;
+    private final Bitmap picture;
+
+    public OverviewEntry(final String dateName, final String dateNumber,
+            final String maxTemp, final String minTemp,
+            final Bitmap picture) {
+        this.dateName = dateName;
+        this.dateNumber = dateNumber;
+        this.maxTemp = maxTemp;
+        this.minTemp = minTemp;
+        this.picture = picture;
+    }
+
+    public String getDateName() {
+        return this.dateName;
+    }
+
+    public String getDateNumber() {
+        return this.dateNumber;
+    }
+
+    public String getMaxTemp() {
+        return this.maxTemp;
+    }
+
+    public String getMinTemp() {
+        return this.minTemp;
+    }
+
+    public Bitmap getPicture() {
+        return this.picture;
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewFragment.java b/app/src/main/java/de/example/exampletdd/fragment/overview/OverviewFragment.java
new file mode 100644 (file)
index 0000000..682e5bd
--- /dev/null
@@ -0,0 +1,410 @@
+package de.example.exampletdd.fragment.overview;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.http.client.ClientProtocolException;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.ListFragment;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+import com.fasterxml.jackson.core.JsonParseException;
+
+import de.example.exampletdd.R;
+import de.example.exampletdd.fragment.specific.SpecificFragment;
+import de.example.exampletdd.httpclient.CustomHTTPClient;
+import de.example.exampletdd.model.DatabaseQueries;
+import de.example.exampletdd.model.WeatherLocation;
+import de.example.exampletdd.model.forecastweather.Forecast;
+import de.example.exampletdd.parser.JPOSWeatherParser;
+import de.example.exampletdd.service.IconsList;
+import de.example.exampletdd.service.PermanentStorage;
+import de.example.exampletdd.service.ServiceParser;
+
+public class OverviewFragment extends ListFragment {
+    private static final String TAG = "OverviewFragment";
+    private BroadcastReceiver mReceiver;
+
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void onActivityCreated(final Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        final ListView listWeatherView = this.getListView();
+        listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
+
+        if (savedInstanceState != null) {
+            // Restore UI state
+            final Forecast forecast = (Forecast) savedInstanceState.getSerializable("Forecast");
+
+            // TODO: Could it be better to store in global forecast data even if it is null value?
+            //       So, perhaps do not check for null value and always store in global variable.
+            if (forecast != null) {
+               final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+               store.saveForecast(forecast);
+            }
+        }
+
+        this.setHasOptionsMenu(false);
+
+        this.setEmptyText(this.getString(R.string.text_field_remote_error));
+        this.setListShownNoAnimation(false);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        this.mReceiver = new BroadcastReceiver() {
+
+                       @Override
+                       public void onReceive(final Context context, final Intent intent) {
+                               final String action = intent.getAction();
+                               if (action.equals("de.example.exampletdd.UPDATEFORECAST")) {
+                                       final Forecast forecastRemote = (Forecast) intent.getSerializableExtra("forecast");
+
+                                       if (forecastRemote != null) {
+
+                                               // 1. Check conditions. They must be the same as the ones that triggered the AsyncTask.
+                                               final DatabaseQueries query = new DatabaseQueries(context.getApplicationContext());
+                                   final WeatherLocation weatherLocation = query.queryDataBase();
+                                   final PermanentStorage store = new PermanentStorage(context.getApplicationContext());
+                                   final Forecast forecast = store.getForecast();
+
+                                       if (forecast == null || !OverviewFragment.this.isDataFresh(weatherLocation.getLastForecastUIUpdate())) {
+                                               // 2. Update UI.
+                                               OverviewFragment.this.updateUI(forecastRemote);
+
+                                               // 3. Update Data.
+                                               store.saveForecast(forecastRemote);
+                                           weatherLocation.setLastForecastUIUpdate(new Date());
+                                           query.updateDataBase(weatherLocation);
+
+                                           // 4. Show list.
+                                           OverviewFragment.this.setListShownNoAnimation(true);
+                                       }
+
+                                       } else {
+                                               // Empty list and show error message (see setEmptyText in onCreate)
+                                               OverviewFragment.this.setListAdapter(null);
+                                               OverviewFragment.this.setListShownNoAnimation(true);
+                                       }
+                               }
+                       }
+        };
+
+        // Register receiver
+        final IntentFilter filter = new IntentFilter();
+        filter.addAction("de.example.exampletdd.UPDATEFORECAST");
+        LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext())
+                                                       .registerReceiver(this.mReceiver, filter);
+
+        final DatabaseQueries query = new DatabaseQueries(this.getActivity().getApplicationContext());
+        final WeatherLocation weatherLocation = query.queryDataBase();
+        if (weatherLocation == null) {
+            // Nothing to do.
+               // Empty list and show error message (see setEmptyText in onCreate)
+                       this.setListAdapter(null);
+                       this.setListShownNoAnimation(true);
+            return;
+        }
+
+        final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+        final Forecast forecast = store.getForecast();
+
+        // TODO: store forecast data in permanent storage and check here if there is data in permanent storage
+        if (forecast != null && this.isDataFresh(weatherLocation.getLastForecastUIUpdate())) {
+            this.updateUI(forecast);
+        } else {
+            // Load remote data (aynchronous)
+            // Gets the data from the web.
+            this.setListShownNoAnimation(false);
+            final OverviewTask task = new OverviewTask(
+                       this.getActivity().getApplicationContext(),
+                    new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")),
+                    new ServiceParser(new JPOSWeatherParser()));
+
+            task.execute(weatherLocation.getLatitude(), weatherLocation.getLongitude());
+            // TODO: make sure thread UI keeps running in parallel after that. I guess.
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(final Bundle savedInstanceState) {
+
+        // Save UI state
+       final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+        final Forecast forecast = store.getForecast();
+
+        // TODO: Could it be better to save forecast data even if it is null value?
+        //       So, perhaps do not check for null value.
+        if (forecast != null) {
+            savedInstanceState.putSerializable("Forecast", forecast);
+        }
+
+        super.onSaveInstanceState(savedInstanceState);
+    }
+
+    @Override
+    public void onPause() {
+        LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext()).unregisterReceiver(this.mReceiver);
+
+        super.onPause();
+    }
+
+    @Override
+    public void onListItemClick(final ListView l, final View v, final int position, final long id) {
+        final SpecificFragment fragment = (SpecificFragment) this
+                .getFragmentManager().findFragmentById(R.id.weather_specific_fragment);
+        if (fragment == null) {
+            // handset layout
+            final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO")
+            .setComponent(new ComponentName("de.example.exampletdd",
+                    "de.example.exampletdd.SpecificActivity"));
+            intent.putExtra("CHOSEN_DAY", (int) id);
+            OverviewFragment.this.getActivity().startActivity(intent);
+        } else {
+            // tablet layout
+            fragment.updateUIByChosenDay((int) id);
+        }
+    }
+
+    private interface UnitsConversor {
+       
+       public double doConversion(final double value);
+    }
+    
+    private void updateUI(final Forecast forecastWeatherData) {
+
+        final SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(this.getActivity().getApplicationContext());
+
+        // TODO: repeating the same code in Overview, Specific and Current!!!
+        // 1. Update units of measurement.
+        String symbol;
+        UnitsConversor unitsConversor;
+        String keyPreference = this.getResources().getString(
+                R.string.weather_preferences_temperature_key);
+        final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
+        if (unitsPreferenceValue.equals(values[0])) {
+               symbol = values[0];
+               unitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value - 273.15;
+                               }
+                       
+               };
+        } else if (unitsPreferenceValue.equals(values[1])) {
+               symbol = values[1];
+               unitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return (value * 1.8) - 459.67;
+                               }
+                       
+               };
+        } else {
+               symbol = values[2];
+               unitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value;
+                               }
+                       
+               };
+        }
+
+
+        // 2. Update number day forecast.
+        keyPreference = this.getResources().getString(R.string.weather_preferences_day_forecast_key);
+        final String dayForecast = sharedPreferences.getString(keyPreference, "5");
+        final int mDayForecast = Integer.valueOf(dayForecast);
+
+
+        // 3. Formatters
+        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
+        tempFormatter.applyPattern("#####.##");
+        final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.US);
+        final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d", Locale.US);
+
+
+        // 4. Prepare data for UI.
+        final List<OverviewEntry> entries = new ArrayList<OverviewEntry>();
+        final OverviewAdapter adapter = new OverviewAdapter(this.getActivity(),
+                R.layout.weather_main_entry_list);
+        final Calendar calendar = Calendar.getInstance();
+        int count = mDayForecast;
+        for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData
+                .getList()) {
+
+            Bitmap picture;
+
+            if ((forecast.getWeather().size() > 0) &&
+                    (forecast.getWeather().get(0).getIcon() != null) &&
+                    (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) {
+                final String icon = forecast.getWeather().get(0).getIcon();
+                picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
+                        .getResourceDrawable());
+            } else {
+                picture = BitmapFactory.decodeResource(this.getResources(),
+                        R.drawable.weather_severe_alert);
+            }
+
+            final Long forecastUNIXDate = (Long) forecast.getDt();
+            calendar.setTimeInMillis(forecastUNIXDate * 1000L);
+            final Date dayTime = calendar.getTime();
+            final String dayTextName = dayNameFormatter.format(dayTime);
+            final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime);
+
+            Double maxTemp = null;
+            if (forecast.getTemp().getMax() != null) {
+                maxTemp = (Double) forecast.getTemp().getMax();
+                maxTemp = unitsConversor.doConversion(maxTemp);
+            }
+
+            Double minTemp = null;
+            if (forecast.getTemp().getMin() != null) {
+                minTemp = (Double) forecast.getTemp().getMin();
+                minTemp = unitsConversor.doConversion(minTemp);
+            }
+
+            if ((maxTemp != null) && (minTemp != null)) {
+                entries.add(new OverviewEntry(dayTextName, monthAndDayNumberText,
+                        tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol,
+                        picture));
+            }
+
+            count = count - 1;
+            if (count == 0) {
+                break;
+            }
+        }
+
+
+        // 5. Update UI.
+        adapter.addAll(entries);
+        this.setListAdapter(adapter);
+    }
+
+    private boolean isDataFresh(final Date lastUpdate) {
+       if (lastUpdate == null) {
+               return false;
+       }
+       
+       final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(
+                       this.getActivity().getApplicationContext());
+        final String keyPreference = this.getString(R.string.weather_preferences_refresh_interval_key);
+        final String refresh = sharedPreferences.getString(
+                       keyPreference,
+                       this.getResources().getStringArray(R.array.weather_preferences_refresh_interval)[0]);
+        final Date currentTime = new Date();
+       if (((currentTime.getTime() - lastUpdate.getTime())) < Long.valueOf(refresh)) {
+               return true;
+       }
+       
+       return false;
+    }
+
+    // TODO: How could I show just one progress dialog when I have two fragments in tabs
+    //       activity doing the same in background?
+    //       I mean, if OverviewTask shows one progress dialog and CurrentTask does the same I will have
+    //       have two progress dialogs... How may I solve this problem? I HATE ANDROID.
+    private class OverviewTask extends AsyncTask<Object, Void, Forecast> {
+       // Store the context passed to the AsyncTask when the system instantiates it.
+        private final Context localContext;
+        private final CustomHTTPClient HTTPClient;
+        private final ServiceParser weatherService;
+
+        public OverviewTask(final Context context, final CustomHTTPClient HTTPClient,
+                       final ServiceParser weatherService) {
+               this.localContext = context;
+            this.HTTPClient = HTTPClient;
+            this.weatherService = weatherService;
+        }
+        
+        @Override
+        protected Forecast doInBackground(final Object... params) {
+            final double latitude = (Double) params[0];
+            final double longitude = (Double) params[1];
+
+            Forecast forecast = null;
+
+            try {
+                forecast = this.doInBackgroundThrowable(latitude, longitude);
+            } catch (final JsonParseException e) {
+                Log.e(TAG, "OverviewTask doInBackground exception: ", e);
+            } catch (final ClientProtocolException e) {
+                Log.e(TAG, "OverviewTask doInBackground exception: ", e);
+            } catch (final MalformedURLException e) {
+                Log.e(TAG, "OverviewTask doInBackground exception: ", e);
+            } catch (final URISyntaxException e) {
+                Log.e(TAG, "OverviewTask doInBackground exception: ", e);
+            } catch (final IOException e) {
+                // logger infrastructure swallows UnknownHostException :/
+                Log.e(TAG, "OverviewTask doInBackground exception: " + e.getMessage(), e);
+            } finally {
+               HTTPClient.close();
+            }
+
+            return forecast;
+        }
+
+        private Forecast doInBackgroundThrowable(final double latitude, final double longitude)
+                        throws URISyntaxException, ClientProtocolException, JsonParseException, IOException {
+
+            final String APIVersion = localContext.getResources().getString(R.string.api_version);
+            final String urlAPI = localContext.getResources().getString(R.string.uri_api_weather_forecast);
+            // TODO: number as resource
+            final String url = weatherService.createURIAPIForecast(urlAPI, APIVersion, latitude, longitude, "14");
+            final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
+            final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
+
+            return weatherService.retrieveForecastFromJPOS(jsonData);
+        }
+
+        @Override
+        protected void onPostExecute(final Forecast forecast) {
+               // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method?
+               // I hope so, otherwise I must catch(Throwable) in doInBackground method :(
+               
+            // Call updateUI on the UI thread.
+               final Intent forecastData = new Intent("de.example.exampletdd.UPDATEFORECAST");
+               forecastData.putExtra("forecast", forecast);
+            LocalBroadcastManager.getInstance(this.localContext).sendBroadcastSync(forecastData);
+        }
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java b/app/src/main/java/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java
new file mode 100644 (file)
index 0000000..ba19c5e
--- /dev/null
@@ -0,0 +1,354 @@
+package de.example.exampletdd.fragment.preferences;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.SwitchPreference;
+import de.example.exampletdd.R;
+import de.example.exampletdd.NotificationIntentService;
+
+public class WeatherInformationPreferencesFragment extends PreferenceFragment 
+                                                                                                       implements OnSharedPreferenceChangeListener {
+
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Load the preferences from an XML resource
+        this.addPreferencesFromResource(R.xml.weather_preferences);
+        
+        
+        // Temperature units
+        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
+        String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value);
+        String keyPreference = this.getActivity().getApplicationContext().getString(
+                R.string.weather_preferences_temperature_key);
+        Preference connectionPref = this.findPreference(keyPreference);
+        String value = this.getPreferenceManager().getSharedPreferences()
+                .getString(keyPreference, "");
+        String humanValue = "";
+        if (value.equals(values[0])) {
+            humanValue = humanValues[0];
+        } else if (value.equals(values[1])) {
+            humanValue = humanValues[1];
+        } else if (value.equals(values[2])) {
+            humanValue = humanValues[2];
+        }
+        connectionPref.setSummary(humanValue);
+        
+        // Wind
+        values = this.getResources().getStringArray(R.array.weather_preferences_wind);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_wind_human_value);
+        keyPreference = this.getString(R.string.weather_preferences_wind_key);
+        connectionPref = this.findPreference(keyPreference);
+        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
+        humanValue = "";
+        if (value.equals(values[0])) {
+            humanValue = humanValues[0];
+        } else if (value.equals(values[1])) {
+            humanValue = humanValues[1];
+        }
+        connectionPref.setSummary(humanValue);
+
+        // Pressure
+        values = this.getResources().getStringArray(R.array.weather_preferences_pressure);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_pressure_human_value);
+        keyPreference = this.getString(R.string.weather_preferences_pressure_key);
+        connectionPref = this.findPreference(keyPreference);
+        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
+        humanValue = "";
+        if (value.equals(values[0])) {
+            humanValue = humanValues[0];
+        } else if (value.equals(values[1])) {
+            humanValue = humanValues[1];
+        }
+        connectionPref.setSummary(humanValue);
+
+        // Forecast days number
+        values = this.getResources().getStringArray(R.array.weather_preferences_day_forecast);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_day_forecast_human_value);
+        keyPreference = this.getActivity().getApplicationContext().getString(
+                R.string.weather_preferences_day_forecast_key);
+        connectionPref = this.findPreference(keyPreference);
+        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
+        humanValue = "";
+        if (value.equals(values[0])) {
+            humanValue = humanValues[0];
+        } else if (value.equals(values[1])) {
+            humanValue = humanValues[1];
+        } else if (value.equals(values[2])) {
+            humanValue = humanValues[2];
+        }
+        connectionPref.setSummary(humanValue);
+
+        // Refresh interval
+        values = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval_human_value);
+        keyPreference = this.getActivity().getApplicationContext().getString(
+                R.string.weather_preferences_refresh_interval_key);
+        connectionPref = this.findPreference(keyPreference);
+        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
+        humanValue = "";
+        if (value.equals(values[0])) {
+            humanValue = humanValues[0];
+        } else if (value.equals(values[1])) {
+            humanValue = humanValues[1];
+        } else if (value.equals(values[2])) {
+            humanValue = humanValues[2];
+        } else if (value.equals(values[3])) {
+            humanValue = humanValues[3];
+        } else if (value.equals(values[4])) {
+            humanValue = humanValues[4];
+        } else if (value.equals(values[5])) {
+            humanValue = humanValues[5];
+        } else if (value.equals(values[6])) {
+            humanValue = humanValues[6];
+        }
+        connectionPref.setSummary(humanValue);
+
+        // Update Time Rate
+        values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate_human_value);
+        keyPreference = this.getActivity().getApplicationContext().getString(
+                R.string.weather_preferences_update_time_rate_key);
+        connectionPref = this.findPreference(keyPreference);
+        value = this.getPreferenceManager().getSharedPreferences()
+                .getString(keyPreference, "");
+        humanValue = "";
+        if (value.equals(values[0])) {
+            humanValue = humanValues[0];
+        } else if (value.equals(values[1])) {
+            humanValue = humanValues[1];
+        } else if (value.equals(values[2])) {
+            humanValue = humanValues[2];
+        } else if (value.equals(values[3])) {
+            humanValue = humanValues[3];
+        } else if (value.equals(values[4])) {
+            humanValue = humanValues[4];
+        }
+        connectionPref.setSummary(humanValue);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        this.getPreferenceManager().getSharedPreferences()
+        .registerOnSharedPreferenceChangeListener(this);
+
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        this.getPreferenceManager().getSharedPreferences()
+        .unregisterOnSharedPreferenceChangeListener(this);
+    }
+
+    @Override
+    public void onSharedPreferenceChanged(
+            final SharedPreferences sharedPreferences, final String key) {
+       
+       // Temperature units
+       String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
+       String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value);
+        String keyValue = this.getActivity().getApplicationContext().getString(
+                R.string.weather_preferences_temperature_key);
+        if (key.equals(keyValue)) {
+               final Preference connectionPref = this.findPreference(key);
+            final String value = sharedPreferences.getString(key, "");
+               String humanValue = "";
+               if (value.equals(values[0])) {
+                       humanValue = humanValues[0];
+               } else if (value.equals(values[1])) {
+                       humanValue = humanValues[1];
+               } else if (value.equals(values[2])) {
+                       humanValue = humanValues[2];
+               }
+
+               connectionPref.setSummary(humanValue);
+               return;
+        }
+
+        // Wind
+        values = this.getResources().getStringArray(R.array.weather_preferences_wind);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_wind_human_value);
+        keyValue = this.getString(R.string.weather_preferences_wind_key);
+        if (key.equals(keyValue)) {
+            final Preference connectionPref = this.findPreference(key);
+            final String value = sharedPreferences.getString(key, "");
+            String humanValue = "";
+            if (value.equals(values[0])) {
+               humanValue = humanValues[0];
+            } else if (value.equals(values[1])) {
+               humanValue = humanValues[1];
+            }
+        
+               connectionPref.setSummary(humanValue);
+               return;
+        }
+
+        // Pressure
+        values = this.getResources().getStringArray(R.array.weather_preferences_pressure);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_pressure_human_value);
+        keyValue = this.getString(R.string.weather_preferences_pressure_key);
+        if (key.equals(keyValue)) {
+            final Preference connectionPref = this.findPreference(key);
+            final String value = sharedPreferences.getString(key, "");
+            String humanValue = "";
+            if (value.equals(values[0])) {
+               humanValue = humanValues[0];
+            } else if (value.equals(values[1])) {
+               humanValue = humanValues[1];
+            }
+        
+               connectionPref.setSummary(humanValue);
+               return;
+        }
+
+        // Forecast days number
+        values = this.getResources().getStringArray(R.array.weather_preferences_day_forecast);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_day_forecast_human_value);
+        keyValue = this.getActivity().getString(
+                R.string.weather_preferences_day_forecast_key);
+        if (key.equals(keyValue)) {
+            final Preference connectionPref = this.findPreference(key);
+            final String value = sharedPreferences.getString(key, "");
+            String humanValue = "";
+            if (value.equals(values[0])) {
+                humanValue = humanValues[0];
+            } else if (value.equals(values[1])) {
+                humanValue = humanValues[1];
+            } else if (value.equals(values[2])) {
+                humanValue = humanValues[2];
+            }
+            connectionPref.setSummary(humanValue);
+            return;
+        }
+
+        // Refresh interval
+        values = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval_human_value);
+        keyValue = this.getActivity().getApplicationContext().getString(
+                R.string.weather_preferences_refresh_interval_key);
+        if (key.equals(keyValue)) {
+               final Preference connectionPref = this.findPreference(key);
+            final String value = sharedPreferences.getString(key, "");
+            String humanValue = "";
+            if (value.equals(values[0])) {
+                humanValue = humanValues[0];
+            } else if (value.equals(values[1])) {
+                humanValue = humanValues[1];
+            } else if (value.equals(values[2])) {
+                humanValue = humanValues[2];
+            } else if (value.equals(values[3])) {
+                humanValue = humanValues[3];
+            } else if (value.equals(values[4])) {
+                humanValue = humanValues[4];
+            } else if (value.equals(values[5])) {
+                humanValue = humanValues[5];
+            } else if (value.equals(values[6])) {
+                humanValue = humanValues[6];
+            }
+            connectionPref.setSummary(humanValue);
+            return;
+        }
+
+        // Notification switch
+        keyValue = this.getActivity().getApplicationContext().getString(
+                       R.string.weather_preferences_notifications_switch_key);
+        if (key.equals(keyValue)) {
+               final SwitchPreference preference = (SwitchPreference)this.findPreference(key);
+               if (preference.isChecked())
+               {
+                       keyValue = this.getActivity().getApplicationContext().getString(
+                               R.string.weather_preferences_update_time_rate_key);
+                       final String value = sharedPreferences.getString(keyValue, "");
+                       this.updateNotification(value);
+               } else {
+                       this.cancelNotification();
+               }
+        }
+        // Update Time Rate
+        values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate);
+        humanValues = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate_human_value);
+        keyValue = this.getActivity().getApplicationContext().getString(
+                       R.string.weather_preferences_update_time_rate_key);
+        if (key.equals(keyValue)) {
+            final Preference connectionPref = this.findPreference(key);
+            final String value = sharedPreferences.getString(key, "");
+            String humanValue = "";
+            if (value.equals(values[0])) {
+                humanValue = humanValues[0];
+            } else if (value.equals(values[1])) {
+                humanValue = humanValues[1];
+            } else if (value.equals(values[2])) {
+                humanValue = humanValues[2];
+            } else if (value.equals(values[3])) {
+                humanValue = humanValues[3];
+            } else if (value.equals(values[4])) {
+                humanValue = humanValues[4];
+            }
+
+            this.updateNotification(value);
+            connectionPref.setSummary(humanValue);
+            return;
+        }
+    }
+
+    private void updateNotification(final String updateTimeRate) {
+       final String[] values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate);
+        long chosenInterval = 0;
+        if (updateTimeRate.equals(values[0])) {
+               chosenInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
+        } else if (updateTimeRate.equals(values[1])) {
+               chosenInterval = AlarmManager.INTERVAL_HALF_HOUR;
+        } else if (updateTimeRate.equals(values[2])) {
+               chosenInterval = AlarmManager.INTERVAL_HOUR;
+        } else if (updateTimeRate.equals(values[3])) {
+               chosenInterval = AlarmManager.INTERVAL_HALF_DAY;
+        } else if (updateTimeRate.equals(values[4])) {
+               chosenInterval = AlarmManager.INTERVAL_DAY;
+        }
+
+        final AlarmManager alarmMgr =
+                       (AlarmManager) this.getActivity().getApplicationContext().getSystemService(Context.ALARM_SERVICE);
+        // TODO: better use some string instead of .class? In case I change the service class
+        // this could be a problem (I guess)
+        final Intent serviceIntent =
+                       new Intent(this.getActivity().getApplicationContext(), NotificationIntentService.class);
+        final PendingIntent alarmIntent =
+                       PendingIntent.getService(
+                                       this.getActivity().getApplicationContext(),
+                                       0,
+                                       serviceIntent,
+                                       PendingIntent.FLAG_UPDATE_CURRENT);
+        if (chosenInterval != 0) {   
+            alarmMgr.setInexactRepeating(
+                       AlarmManager.ELAPSED_REALTIME,
+                       SystemClock.elapsedRealtime(),
+                       chosenInterval,
+                       alarmIntent);
+        }
+    }
+
+    private void cancelNotification() {
+       final AlarmManager alarmMgr =
+                       (AlarmManager) this.getActivity().getApplicationContext().getSystemService(Context.ALARM_SERVICE);
+       final Intent serviceIntent =
+                       new Intent(this.getActivity().getApplicationContext(), NotificationIntentService.class);
+       final PendingIntent alarmIntent =
+                       PendingIntent.getService(
+                                       this.getActivity().getApplicationContext(),
+                                       0,
+                                       serviceIntent,
+                                       PendingIntent.FLAG_UPDATE_CURRENT);
+       alarmMgr.cancel(alarmIntent);
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/fragment/specific/SpecificFragment.java b/app/src/main/java/de/example/exampletdd/fragment/specific/SpecificFragment.java
new file mode 100644 (file)
index 0000000..e355c71
--- /dev/null
@@ -0,0 +1,357 @@
+package de.example.exampletdd.fragment.specific;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import de.example.exampletdd.R;
+import de.example.exampletdd.model.forecastweather.Forecast;
+import de.example.exampletdd.service.IconsList;
+import de.example.exampletdd.service.PermanentStorage;
+
+
+public class SpecificFragment extends Fragment {
+    private int mChosenDay;
+
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        final Bundle extras = this.getActivity().getIntent().getExtras();
+
+        if (extras != null) {
+               // handset layout
+            this.mChosenDay = extras.getInt("CHOSEN_DAY", 0);
+        } else {
+               // tablet layout
+               // Always 0 when tablet layout (by default shows the first day)
+            this.mChosenDay = 0;
+        }
+    }
+    
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+    
+       // Inflate the layout for this fragment
+        return inflater.inflate(R.layout.weather_specific_fragment, container, false);
+    }
+    
+    @Override
+    public void onActivityCreated(final Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        if (savedInstanceState != null) {
+               // Restore UI state
+            final Forecast forecast = (Forecast) savedInstanceState.getSerializable("Forecast");
+
+            // TODO: Could it be better to store in global data forecast even if it is null value?
+            //       So, perhaps do not check for null value and always store in global variable.
+            if (forecast != null) {
+               final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+               store.saveForecast(forecast);
+            }
+
+            this.mChosenDay = savedInstanceState.getInt("mChosenDay");
+        }
+
+        this.setHasOptionsMenu(false);
+    }
+
+    @Override
+    public void onSaveInstanceState(final Bundle savedInstanceState) {
+
+        // Save UI state
+       final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+        final Forecast forecast = store.getForecast();
+
+        // TODO: Could it be better to save forecast data even if it is null value?
+        //       So, perhaps do not check for null value.
+        if (forecast != null) {
+            savedInstanceState.putSerializable("Forecast", forecast);
+        }
+
+        savedInstanceState.putInt("mChosenDay", this.mChosenDay);
+
+        super.onSaveInstanceState(savedInstanceState);
+    }
+
+    /**
+     * This method is used by tablet layout.
+     * 
+     * @param chosenDay
+     */
+    public void updateUIByChosenDay(final int chosenDay) {
+       final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+        final Forecast forecast = store.getForecast();
+
+        if (forecast != null) {
+            this.updateUI(forecast, chosenDay);
+        }
+    }
+
+    private interface UnitsConversor {
+       
+       public double doConversion(final double value);
+    }
+
+    private void updateUI(final Forecast forecastWeatherData, final int chosenDay) {
+
+        final SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(this.getActivity());
+
+        // TODO: repeating the same code in Overview, Specific and Current!!!
+        // 1. Update units of measurement.
+        // 1.1 Temperature
+        String tempSymbol;
+        UnitsConversor tempUnitsConversor;
+        String keyPreference = this.getResources().getString(
+                R.string.weather_preferences_temperature_key);
+        String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
+        if (unitsPreferenceValue.equals(values[0])) {
+               tempSymbol = values[0];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value - 273.15;
+                               }
+                       
+               };
+        } else if (unitsPreferenceValue.equals(values[1])) {
+               tempSymbol = values[1];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return (value * 1.8) - 459.67;
+                               }
+                       
+               };
+        } else {
+               tempSymbol = values[2];
+               tempUnitsConversor = new UnitsConversor(){
+
+                               @Override
+                               public double doConversion(final double value) {
+                                       return value;
+                               }
+                       
+               };
+        }
+
+        // 1.2 Wind
+        String windSymbol;
+        UnitsConversor windUnitsConversor;
+        keyPreference = this.getResources().getString(R.string.weather_preferences_wind_key);
+        unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        values = this.getResources().getStringArray(R.array.weather_preferences_wind);
+        if (unitsPreferenceValue.equals(values[0])) {
+               windSymbol = values[0];
+               windUnitsConversor = new UnitsConversor(){
+
+                       @Override
+                       public double doConversion(double value) {
+                               return value;
+                       }       
+               };
+        } else {
+               windSymbol = values[1];
+               windUnitsConversor = new UnitsConversor(){
+
+                       @Override
+                       public double doConversion(double value) {
+                               return value * 2.237;
+                       }       
+               };
+        }
+
+        // 1.3 Pressure
+        String pressureSymbol;
+        UnitsConversor pressureUnitsConversor;
+        keyPreference = this.getResources().getString(R.string.weather_preferences_pressure_key);
+        unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
+        values = this.getResources().getStringArray(R.array.weather_preferences_pressure);
+        if (unitsPreferenceValue.equals(values[0])) {
+               pressureSymbol = values[0];
+               pressureUnitsConversor = new UnitsConversor(){
+
+                       @Override
+                       public double doConversion(double value) {
+                               return value;
+                       }       
+               };
+        } else {
+               pressureSymbol = values[1];
+               pressureUnitsConversor = new UnitsConversor(){
+
+                       @Override
+                       public double doConversion(double value) {
+                               return value / 113.25d;
+                       }       
+               };
+        }
+
+
+        // 2. Formatters
+        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
+        tempFormatter.applyPattern("#####.#####");
+        
+
+        // 3. Prepare data for UI.
+        final de.example.exampletdd.model.forecastweather.List forecast = forecastWeatherData
+                .getList().get((chosenDay));
+
+        final SimpleDateFormat dayFormatter = new SimpleDateFormat("EEEE - MMM d", Locale.US);
+        final Calendar calendar = Calendar.getInstance();
+        final Long forecastUNIXDate = (Long) forecast.getDt();
+        calendar.setTimeInMillis(forecastUNIXDate * 1000L);
+        final Date date = calendar.getTime();     
+
+        String tempMax = "";
+        if (forecast.getTemp().getMax() != null) {
+            double conversion = (Double) forecast.getTemp().getMax();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempMax = tempFormatter.format(conversion) + tempSymbol;
+        }        
+        String tempMin = "";
+        if (forecast.getTemp().getMin() != null) {
+            double conversion = (Double) forecast.getTemp().getMin();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempMin = tempFormatter.format(conversion) + tempSymbol;
+        }
+        Bitmap picture;
+        if ((forecast.getWeather().size() > 0) && (forecast.getWeather().get(0).getIcon() != null)
+                && (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) {
+            final String icon = forecast.getWeather().get(0).getIcon();
+            picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
+                    .getResourceDrawable());
+        } else {
+            picture = BitmapFactory.decodeResource(this.getResources(),
+                    R.drawable.weather_severe_alert);
+        }       
+
+        // TODO: string resource
+        String description = "no description available";
+        if (forecast.getWeather().size() > 0) {
+            description = forecast.getWeather().get(0).getDescription();
+        }
+
+        // TODO: units!!!!
+        String humidityValue = "";
+        if (forecast.getHumidity() != null) {
+            final double conversion = (Double) forecast.getHumidity();
+            humidityValue = tempFormatter.format(conversion);
+        }        
+        String pressureValue = "";
+        if (forecast.getPressure() != null) {
+            double conversion = (Double) forecast.getPressure();
+            conversion = pressureUnitsConversor.doConversion(conversion);
+            pressureValue = tempFormatter.format(conversion);
+        }
+        String windValue = "";
+        if (forecast.getSpeed() != null) {
+            double conversion = (Double) forecast.getSpeed();
+            conversion = windUnitsConversor.doConversion(conversion);
+            windValue = tempFormatter.format(conversion);
+        }
+        String rainValue = "";
+        if (forecast.getRain() != null) {
+            final double conversion = (Double) forecast.getRain();
+            rainValue = tempFormatter.format(conversion);
+        }
+        String cloudsValue = "";
+        if (forecast.getRain() != null) {
+            final double conversion = (Double) forecast.getClouds();
+            cloudsValue = tempFormatter.format(conversion);
+        }
+
+        String tempDay = "";
+        if (forecast.getTemp().getDay() != null) {
+            double conversion = (Double) forecast.getTemp().getDay();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempDay = tempFormatter.format(conversion) + tempSymbol;
+        }
+        String tempMorn = "";
+        if (forecast.getTemp().getMorn() != null) {
+            double conversion = (Double) forecast.getTemp().getMorn();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempMorn = tempFormatter.format(conversion) + tempSymbol;
+        }
+        String tempEve = "";
+        if (forecast.getTemp().getEve() != null) {
+            double conversion = (Double) forecast.getTemp().getEve();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempEve = tempFormatter.format(conversion) + tempSymbol;
+        }   
+        String tempNight = "";
+        if (forecast.getTemp().getNight() != null) {
+            double conversion = (Double) forecast.getTemp().getNight();
+            conversion = tempUnitsConversor.doConversion(conversion);
+            tempNight = tempFormatter.format(conversion) + tempSymbol;
+        }   
+
+
+        // 4. Update UI.
+        this.getActivity().getActionBar().setSubtitle(dayFormatter.format(date).toUpperCase());
+        
+        final TextView tempMaxView = (TextView) getActivity().findViewById(R.id.weather_specific_temp_max);
+        tempMaxView.setText(tempMax);
+        final TextView tempMinView = (TextView) getActivity().findViewById(R.id.weather_specific_temp_min);
+        tempMinView.setText(tempMin);
+        final ImageView pictureView = (ImageView) getActivity().findViewById(R.id.weather_specific_picture);
+        pictureView.setImageBitmap(picture);    
+        
+        final TextView descriptionView = (TextView) getActivity().findViewById(R.id.weather_specific_description);
+        descriptionView.setText(description);
+        
+        final TextView humidityValueView = (TextView) getActivity().findViewById(R.id.weather_specific_humidity_value);
+        humidityValueView.setText(humidityValue);
+        ((TextView) getActivity().findViewById(R.id.weather_specific_pressure_value)).setText(pressureValue);
+        ((TextView) getActivity().findViewById(R.id.weather_specific_pressure_units)).setText(pressureSymbol);
+        ((TextView) getActivity().findViewById(R.id.weather_specific_wind_value)).setText(windValue);;
+        ((TextView) getActivity().findViewById(R.id.weather_specific_wind_units)).setText(windSymbol);
+        final TextView rainValueView = (TextView) getActivity().findViewById(R.id.weather_specific_rain_value);
+        rainValueView.setText(rainValue);
+        final TextView cloudsValueView = (TextView) getActivity().findViewById(R.id.weather_specific_clouds_value);
+        cloudsValueView.setText(cloudsValue); 
+        
+        final TextView tempDayView = (TextView) getActivity().findViewById(R.id.weather_specific_day_temperature);
+        tempDayView.setText(tempDay);
+        final TextView tempMornView = (TextView) getActivity().findViewById(R.id.weather_specific_morn_temperature);
+        tempMornView.setText(tempMorn);
+        final TextView tempEveView = (TextView) getActivity().findViewById(R.id.weather_specific_eve_temperature);
+        tempEveView.setText(tempEve);
+        final TextView tempNightView = (TextView) getActivity().findViewById(R.id.weather_specific_night_temperature);
+        tempNightView.setText(tempNight);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
+        final Forecast forecast = store.getForecast();
+
+        if (forecast != null) {
+            this.updateUI(forecast, this.mChosenDay);
+        }
+        
+        // TODO: Overview is doing things with mListState... Why not here?
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/httpclient/Consts.java b/app/src/main/java/de/example/exampletdd/httpclient/Consts.java
new file mode 100644 (file)
index 0000000..614849f
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package de.example.exampletdd.httpclient;
+
+import java.nio.charset.Charset;
+
+/**
+ * Commons constants.
+ *
+ * @since 4.2
+ */
+public final class Consts {
+
+    public static final int CR = 13; // <US-ASCII CR, carriage return (13)>
+    public static final int LF = 10; // <US-ASCII LF, linefeed (10)>
+    public static final int SP = 32; // <US-ASCII SP, space (32)>
+    public static final int HT = 9;  // <US-ASCII HT, horizontal-tab (9)>
+
+    public static final Charset UTF_8 = Charset.forName("UTF-8");
+    public static final Charset ASCII = Charset.forName("US-ASCII");
+    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+
+    private Consts() {
+    }
+
+}
diff --git a/app/src/main/java/de/example/exampletdd/httpclient/ContentType.java b/app/src/main/java/de/example/exampletdd/httpclient/ContentType.java
new file mode 100644 (file)
index 0000000..8c02532
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package de.example.exampletdd.httpclient;
+
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Locale;
+
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.ParseException;
+import org.apache.http.message.BasicHeaderValueParser;
+
+/**
+ * Content type information consisting of a MIME type and an optional charset.
+ * <p/>
+ * This class makes no attempts to verify validity of the MIME type.
+ * The input parameters of the {@link #create(String, String)} method, however, may not
+ * contain characters <">, <;>, <,> reserved by the HTTP specification.
+ *
+ * @since 4.2
+ */
+
+public final class ContentType {
+
+    // constants
+    public static final ContentType APPLICATION_ATOM_XML = create(
+            "application/atom+xml", Consts.ISO_8859_1);
+    public static final ContentType APPLICATION_FORM_URLENCODED = create(
+            "application/x-www-form-urlencoded", Consts.ISO_8859_1);
+    public static final ContentType APPLICATION_JSON = create(
+            "application/json", Consts.UTF_8);
+    public static final ContentType APPLICATION_OCTET_STREAM = create(
+            "application/octet-stream", (Charset) null);
+    public static final ContentType APPLICATION_SVG_XML = create(
+            "application/svg+xml", Consts.ISO_8859_1);
+    public static final ContentType APPLICATION_XHTML_XML = create(
+            "application/xhtml+xml", Consts.ISO_8859_1);
+    public static final ContentType APPLICATION_XML = create(
+            "application/xml", Consts.ISO_8859_1);
+    public static final ContentType MULTIPART_FORM_DATA = create(
+            "multipart/form-data", Consts.ISO_8859_1);
+    public static final ContentType TEXT_HTML = create(
+            "text/html", Consts.ISO_8859_1);
+    public static final ContentType TEXT_PLAIN = create(
+            "text/plain", Consts.ISO_8859_1);
+    public static final ContentType TEXT_XML = create(
+            "text/xml", Consts.ISO_8859_1);
+    public static final ContentType WILDCARD = create(
+            "*/*", (Charset) null);
+
+    // defaults
+    public static final ContentType DEFAULT_TEXT = TEXT_PLAIN;
+    public static final ContentType DEFAULT_BINARY = APPLICATION_OCTET_STREAM;
+
+    private final String mimeType;
+    private final Charset charset;
+
+    /**
+     * Given a MIME type and a character set, constructs a ContentType.
+     * @param mimeType The MIME type to use for the ContentType header.
+     * @param charset The optional character set to use with the ContentType header.
+     * @throws  UnsupportedCharsetException
+     *          If no support for the named charset is available in this Java virtual machine
+     */
+    ContentType(final String mimeType, final Charset charset) {
+        this.mimeType = mimeType;
+        this.charset = charset;
+    }
+
+    public String getMimeType() {
+        return this.mimeType;
+    }
+
+    public Charset getCharset() {
+        return this.charset;
+    }
+
+    /**
+     * Converts a ContentType to a string which can be used as a ContentType header.
+     * If a charset is provided by the ContentType, it will be included in the string.
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buf = new StringBuilder();
+        buf.append(this.mimeType);
+        if (this.charset != null) {
+            buf.append("; charset=");
+            buf.append(this.charset);
+        }
+        return buf.toString();
+    }
+
+    private static boolean valid(final String s) {
+        for (int i = 0; i < s.length(); i++) {
+            final char ch = s.charAt(i);
+            if ((ch == '"') || (ch == ',') || (ch == ';')) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Creates a new instance of {@link ContentType}.
+     *
+     * @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
+     *        characters <">, <;>, <,> reserved by the HTTP specification.
+     * @param charset charset.
+     * @return content type
+     */
+    public static ContentType create(final String mimeType, final Charset charset) {
+        if (mimeType == null) {
+            throw new IllegalArgumentException("MIME type may not be null");
+        }
+        final String type = mimeType.trim().toLowerCase(Locale.US);
+        if (type.length() == 0) {
+            throw new IllegalArgumentException("MIME type may not be empty");
+        }
+        if (!valid(type)) {
+            throw new IllegalArgumentException("MIME type may not contain reserved characters");
+        }
+        return new ContentType(type, charset);
+    }
+
+    /**
+     * Creates a new instance of {@link ContentType} without a charset.
+     *
+     * @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
+     *        characters <">, <;>, <,> reserved by the HTTP specification.
+     * @return content type
+     */
+    public static ContentType create(final String mimeType) {
+        return new ContentType(mimeType, (Charset) null);
+    }
+
+    /**
+     * Creates a new instance of {@link ContentType}.
+     *
+     * @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
+     *        characters <">, <;>, <,> reserved by the HTTP specification.
+     * @param charset charset. It may not contain characters <">, <;>, <,> reserved by the HTTP
+     *        specification. This parameter is optional.
+     * @return content type
+     */
+    public static ContentType create(
+            final String mimeType, final String charset) throws UnsupportedCharsetException {
+        return create(mimeType, charset != null ? Charset.forName(charset) : null);
+    }
+
+    private static ContentType create(final HeaderElement helem) {
+        final String mimeType = helem.getName();
+        String charset = null;
+        final NameValuePair param = helem.getParameterByName("charset");
+        if (param != null) {
+            charset = param.getValue();
+        }
+        return create(mimeType, charset);
+    }
+
+    /**
+     * Parses textual representation of <code>Content-Type</code> value.
+     *
+     * @param s text
+     * @return content type
+     * @throws ParseException if the given text does not represent a valid
+     * <code>Content-Type</code> value.
+     */
+    public static ContentType parse(
+            final String s) throws ParseException, UnsupportedCharsetException {
+        if (s == null) {
+            throw new IllegalArgumentException("Content type may not be null");
+        }
+        final HeaderElement[] elements = BasicHeaderValueParser.parseElements(s, null);
+        if (elements.length > 0) {
+            return create(elements[0]);
+        } else {
+            throw new ParseException("Invalid content type: " + s);
+        }
+    }
+
+    /**
+     * Extracts <code>Content-Type</code> value from {@link HttpEntity} exactly as
+     * specified by the <code>Content-Type</code> header of the entity. Returns <code>null</code>
+     * if not specified.
+     *
+     * @param entity HTTP entity
+     * @return content type
+     * @throws ParseException if the given text does not represent a valid
+     * <code>Content-Type</code> value.
+     */
+    public static ContentType get(
+            final HttpEntity entity) throws ParseException, UnsupportedCharsetException {
+        if (entity == null) {
+            return null;
+        }
+        final Header header = entity.getContentType();
+        if (header != null) {
+            final HeaderElement[] elements = header.getElements();
+            if (elements.length > 0) {
+                return create(elements[0]);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Extracts <code>Content-Type</code> value from {@link HttpEntity} or returns default value
+     * if not explicitly specified.
+     *
+     * @param entity HTTP entity
+     * @return content type
+     * @throws ParseException if the given text does not represent a valid
+     * <code>Content-Type</code> value.
+     */
+    public static ContentType getOrDefault(final HttpEntity entity) throws ParseException {
+        final ContentType contentType = get(entity);
+        return contentType != null ? contentType : DEFAULT_TEXT;
+    }
+
+}
diff --git a/app/src/main/java/de/example/exampletdd/httpclient/CustomHTTPClient.java b/app/src/main/java/de/example/exampletdd/httpclient/CustomHTTPClient.java
new file mode 100644 (file)
index 0000000..ba1bb99
--- /dev/null
@@ -0,0 +1,126 @@
+package de.example.exampletdd.httpclient;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpGet;
+
+import android.net.http.AndroidHttpClient;
+
+public class CustomHTTPClient {
+    private final AndroidHttpClient httpClient;
+
+    public CustomHTTPClient(final AndroidHttpClient httpClient) {
+        this.httpClient = httpClient;
+    }
+
+    public String retrieveDataAsString(final URL url)
+            throws URISyntaxException, ClientProtocolException, IOException {
+
+        final ResponseHandler<String> handler = new ResponseHandler<String>() {
+            @Override
+            public String handleResponse(
+                    final HttpResponse response)
+                            throws UnsupportedEncodingException, IOException {
+
+                if (response != null) {
+                    final HttpEntity entity = response.getEntity();
+                    if (entity != null) {
+                        try {
+                            final ContentType contentType = ContentType.getOrDefault(entity);
+                            final ByteArrayOutputStream buffer = CustomHTTPClient.this
+                                    .sortResponse(response);
+                            return new String(buffer.toByteArray(), contentType.getCharset());
+                        } finally {
+                            entity.consumeContent();
+                        }
+                    }
+
+                    throw new IOException("There is no entity");
+                }
+
+                throw new IOException("There is no response");
+            }
+        };
+
+        final HttpGet httpGet = new HttpGet();
+        httpGet.setURI(url.toURI());
+
+        return this.httpClient.execute(httpGet, handler);
+    }
+
+    public ByteArrayOutputStream retrieveRawData(final URL url)
+            throws URISyntaxException, ClientProtocolException, IOException {
+        final ResponseHandler<ByteArrayOutputStream> handler = new ResponseHandler<ByteArrayOutputStream>() {
+
+            @Override
+            public ByteArrayOutputStream handleResponse(
+                    final HttpResponse response)
+                            throws UnsupportedEncodingException, IOException {
+
+                if (response != null) {
+                    final HttpEntity entity = response.getEntity();
+                    if (entity != null) {
+                        try {
+                            return CustomHTTPClient.this.sortResponse(response);
+                        } finally {
+                            entity.consumeContent();
+                        }
+                    }
+
+                    throw new IOException("There is no entity");
+                }
+
+                throw new IOException("There is no response");
+            }
+        };
+
+        final HttpGet httpGet = new HttpGet();
+        httpGet.setURI(url.toURI());
+
+        return this.httpClient.execute(httpGet, handler);
+    }
+
+    public void close() {
+        this.httpClient.close();
+    }
+
+    private ByteArrayOutputStream sortResponse(final HttpResponse httpResponse) throws IOException {
+
+        if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+            throw new IOException("Unexpected response code: "
+                    + httpResponse.getStatusLine().getStatusCode());
+        }
+
+        final HttpEntity entity = httpResponse.getEntity();
+        final InputStream inputStream = entity.getContent();
+        try {
+            return this.readInputStream(inputStream);
+        } finally {
+            inputStream.close();
+        }
+
+    }
+
+    private ByteArrayOutputStream readInputStream (final InputStream inputStream) throws IOException {
+        final ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
+        final int bufferSize = 1024;
+        final byte[] buffer = new byte[bufferSize];
+
+        int len = 0;
+        while ((len = inputStream.read(buffer)) != -1) {
+            byteBuffer.write(buffer, 0, len);
+        }
+
+        return byteBuffer;
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/DatabaseQueries.java b/app/src/main/java/de/example/exampletdd/model/DatabaseQueries.java
new file mode 100644 (file)
index 0000000..e53f97d
--- /dev/null
@@ -0,0 +1,44 @@
+package de.example.exampletdd.model;
+
+import android.content.Context;
+
+public class DatabaseQueries {
+       private final Context localContext;
+
+       public DatabaseQueries(final Context context) {
+               this.localContext = context;
+       }
+       
+       public WeatherLocation queryDataBase() {
+        
+        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
+        try {
+               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
+               return queryDb.queryDataBase();
+        } finally {
+               dbHelper.close();
+        } 
+    }
+    
+       public long insertIntoDataBase(final WeatherLocation weatherLocation) {
+        
+        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
+        try {
+               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
+               return queryDb.insertIntoDataBase(weatherLocation);
+        } finally {
+               dbHelper.close();
+        } 
+    }
+    
+       public void updateDataBase(final WeatherLocation weatherLocation) {
+        
+        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
+        try {
+               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
+               queryDb.updateDataBase(weatherLocation);
+        } finally {
+               dbHelper.close();
+        } 
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/WeatherLocation.java b/app/src/main/java/de/example/exampletdd/model/WeatherLocation.java
new file mode 100644 (file)
index 0000000..f20b0b6
--- /dev/null
@@ -0,0 +1,89 @@
+package de.example.exampletdd.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+public class WeatherLocation implements Serializable {
+       private static final long serialVersionUID = -1469725417020355109L;
+       private int id;
+       private String city;
+    private String country;
+    private boolean isSelected;
+    private double latitude;
+    private double longitude;
+    private Date lastCurrentUIUpdate;
+    private Date lastForecastUIUpdate;
+
+    public WeatherLocation setId(int id) {
+               this.id = id;
+               return this;
+       }
+
+       public WeatherLocation setCity(String city) {
+               this.city = city;
+               return this;
+       }
+
+       public WeatherLocation setCountry(String country) {
+               this.country = country;
+               return this;
+       }
+
+       public WeatherLocation setIsSelected(boolean isSelected) {
+               this.isSelected = isSelected;
+               return this;
+       }
+
+       public WeatherLocation setLatitude(double latitude) {
+               this.latitude = latitude;
+               return this;
+       }
+
+       public WeatherLocation setLongitude(double longitude) {
+               this.longitude = longitude;
+               return this;
+       }
+
+       public WeatherLocation setLastCurrentUIUpdate(Date lastCurrentUIUpdate) {
+               this.lastCurrentUIUpdate = lastCurrentUIUpdate;
+               return this;
+       }
+
+       public WeatherLocation setLastForecastUIUpdate(Date lastForecastUIUpdate) {
+               this.lastForecastUIUpdate = lastForecastUIUpdate;
+               return this;
+       }
+
+       public int getId() {
+       return this.id;
+    }
+    
+    public String getCity() {
+        return this.city;
+    }
+
+    public String getCountry() {
+        return this.country;
+    }
+    
+    public boolean getIsSelected() {
+       return this.isSelected;
+    }
+
+    public double getLatitude() {
+        return this.latitude;
+    }
+
+    public double getLongitude() {
+        return this.longitude;
+    }
+    
+    public Date getLastCurrentUIUpdate() {
+       return this.lastCurrentUIUpdate;
+    }
+    
+    public Date getLastForecastUIUpdate() {
+       return this.lastForecastUIUpdate;
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/WeatherLocationContract.java b/app/src/main/java/de/example/exampletdd/model/WeatherLocationContract.java
new file mode 100644 (file)
index 0000000..91e3472
--- /dev/null
@@ -0,0 +1,32 @@
+package de.example.exampletdd.model;
+
+import android.provider.BaseColumns;
+
+public class WeatherLocationContract {
+
+       // This class can't be instantiated
+       private WeatherLocationContract() {}
+       
+       public static final class WeatherLocation implements BaseColumns {
+               
+               // This class can't be instantiated
+               private WeatherLocation() {}
+               
+               public static final String TABLE_NAME = "locations";
+               
+               public static final String COLUMN_NAME_IS_SELECTED = "isSelected";
+               
+               public static final String COLUMN_NAME_LATITUDE = "latitude";
+               
+               public static final String COLUMN_NAME_LONGITUDE = "longitude";
+               
+               public static final String COLUMN_NAME_COUNTRY = "country";
+               
+               public static final String COLUMN_NAME_CITY = "city";
+               
+               public static final String COLUMN_NAME_LAST_FORECAST_UI_UPDATE = "lastForecastUpdate";
+               
+               public static final String COLUMN_NAME_LAST_CURRENT_UI_UPDATE = "lastCurrentUpdate";
+       }
+
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbHelper.java b/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbHelper.java
new file mode 100644 (file)
index 0000000..8083516
--- /dev/null
@@ -0,0 +1,43 @@
+package de.example.exampletdd.model;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+public class WeatherLocationDbHelper extends SQLiteOpenHelper {
+       private static final String TAG = "LocationDbHelper";
+       public static final int DATABASE_VERSION = 1;
+    public static final String DATABASE_NAME = "Location.db";
+    
+    public WeatherLocationDbHelper(final Context context) {
+        super(context, DATABASE_NAME, null, DATABASE_VERSION);
+    }
+    
+       @Override
+       public void onCreate(final SQLiteDatabase db) {
+               db.execSQL("CREATE TABLE " + WeatherLocationContract.WeatherLocation.TABLE_NAME + " ("
+                               + WeatherLocationContract.WeatherLocation._ID + " INTEGER PRIMARY KEY, "
+                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY + " TEXT" + " NOT NULL, "
+                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY + " TEXT" + " NOT NULL, "
+                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " INTEGER" + " NOT NULL, "
+                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE + " INTEGER, "
+                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE + " INTEGER, "
+                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE + " REAL" + " NOT NULL, "
+                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE + " REAL" + " NOT NULL "
+                               + ");");
+       }
+
+       @Override
+       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                + newVersion + ", which will destroy all old data");
+
+        // Kills the table and existing data
+        db.execSQL("DROP TABLE IF EXISTS " + WeatherLocationContract.WeatherLocation.TABLE_NAME);
+
+        // Recreates the database with a new version
+        onCreate(db);
+       }
+
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbQueries.java b/app/src/main/java/de/example/exampletdd/model/WeatherLocationDbQueries.java
new file mode 100644 (file)
index 0000000..fa97ca2
--- /dev/null
@@ -0,0 +1,176 @@
+package de.example.exampletdd.model;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class WeatherLocationDbQueries {
+       private final SQLiteOpenHelper mDbHelper;
+
+       public interface DoQuery {
+               
+               public WeatherLocation doQuery(final Cursor cursor);
+       }
+
+       public WeatherLocationDbQueries(final SQLiteOpenHelper dbHelper) {
+               this.mDbHelper = dbHelper;
+       }
+       
+       public WeatherLocation queryDataBase() {
+        final String selection = WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " = ?";
+        final String[] selectionArgs = { "1" };
+        final String[] projection = {
+                       WeatherLocationContract.WeatherLocation._ID,
+                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY,
+                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY,
+                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED,
+                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE,
+                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE,
+                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE,
+                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE
+                   };
+        
+
+        final WeatherLocationDbQueries.DoQuery doQuery = new WeatherLocationDbQueries.DoQuery() {
+
+               @Override
+               public WeatherLocation doQuery(final Cursor cursor) {                   
+                       final int id = cursor.getInt(cursor.getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation._ID));
+                       final String city = cursor.getString(cursor.
+                                       getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY));
+                       final String country = cursor.getString(cursor.
+                                       getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY));
+                       final boolean isSelected = (cursor.getInt(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED)) == 0) ? false : true;  
+                       Date lastCurrentUIUpdate = null;
+                       if (!cursor.isNull(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE))) {
+                       final long javaTime = cursor.getLong(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE));
+                       lastCurrentUIUpdate = new Date(javaTime);
+                       }
+                       Date lasForecastUIUpdate = null;
+                       if (!cursor.isNull(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE))) {
+                       final long javaTime = cursor.getLong(cursor
+                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE));
+                       lasForecastUIUpdate = new Date(javaTime);
+                       }
+                       final double latitude = cursor.getDouble(cursor.
+                                       getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE));
+                       final double longitude = cursor.getDouble(cursor.
+                                       getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE));
+                       
+                       
+                       return new WeatherLocation()
+                                       .setId(id)
+                                       .setCity(city)
+                                       .setCountry(country)
+                                       .setIsSelected(isSelected)
+                                       .setLastCurrentUIUpdate(lastCurrentUIUpdate)
+                                       .setLastForecastUIUpdate(lasForecastUIUpdate)
+                                       .setLatitude(latitude)
+                                       .setLongitude(longitude);
+               }
+        };
+
+        return this.queryDataBase(
+                       WeatherLocationContract.WeatherLocation.TABLE_NAME, projection,
+                       selectionArgs, selection, doQuery);
+    }
+       
+       public long insertIntoDataBase(final WeatherLocation weatherLocation) {
+               // Create a new map of values, where column names are the keys
+               final ContentValues values = new ContentValues();
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, weatherLocation.getCity());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, weatherLocation.getCountry());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, weatherLocation.getIsSelected());
+               Date javaTime = weatherLocation.getLastCurrentUIUpdate();
+               if (javaTime != null) {
+                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE, javaTime.getTime());
+               }
+               javaTime = weatherLocation.getLastForecastUIUpdate();
+               if (javaTime != null) {
+                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE, javaTime.getTime());
+               }
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, weatherLocation.getLatitude());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE, weatherLocation.getLongitude());
+               
+               return this.insertIntoDataBase(WeatherLocationContract.WeatherLocation.TABLE_NAME, values);
+       }
+       
+       public void updateDataBase(final WeatherLocation weatherLocation) {
+               final String selection = WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " = ?";
+        final String[] selectionArgs = { "1" };
+               // Create a new map of values, where column names are the keys
+               final ContentValues values = new ContentValues();
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, weatherLocation.getCity());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, weatherLocation.getCountry());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, weatherLocation.getIsSelected());
+               Date javaTime = weatherLocation.getLastCurrentUIUpdate();
+               if (javaTime != null) {
+                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE, javaTime.getTime());
+               } else {
+                       values.putNull(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE);
+               }
+               javaTime = weatherLocation.getLastForecastUIUpdate();
+               if (javaTime != null) {
+                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE, javaTime.getTime());
+               } else {
+                       values.putNull(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE);
+               }
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, weatherLocation.getLatitude());
+               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE, weatherLocation.getLongitude());
+               
+               this.updateDataBase(WeatherLocationContract.WeatherLocation.TABLE_NAME, selectionArgs, selection, values);
+       }
+       
+       // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
+       private WeatherLocation queryDataBase(final String table,
+                       final String[] projection, final String[] selectionArgs,
+                       final String selection, final DoQuery doQuery) {
+        // TODO: execute around idiom? I miss try/finally with resources
+        final SQLiteDatabase db = this.mDbHelper.getReadableDatabase();
+        try {
+               final Cursor cursor = db.query(table, projection, selection, selectionArgs, null, null, null);
+               try {
+                       if (!cursor.moveToFirst()) {
+                       return null;
+                       }
+                       else {
+                               return doQuery.doQuery(cursor);
+                       }
+               } finally {
+                       cursor.close();
+               }
+        } finally {
+               db.close();
+        }
+    }
+       
+       // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
+       private long insertIntoDataBase(final String table, final ContentValues values) {
+        final SQLiteDatabase db = this.mDbHelper.getWritableDatabase();
+        try {
+               return db.insert(table, null, values);
+        } finally {
+               db.close();
+        }
+    }
+       
+       // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
+       private long updateDataBase(final String table, final String[] selectionArgs,
+                       final String selection, final ContentValues values) {
+        final SQLiteDatabase db = this.mDbHelper.getWritableDatabase();
+        try {
+               return db.update(table, values, selection, selectionArgs);
+        } finally {
+               db.close();
+        }
+    }
+       
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Clouds.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Clouds.java
new file mode 100644 (file)
index 0000000..8da14c3
--- /dev/null
@@ -0,0 +1,22 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+
+public class Clouds implements Serializable {
+    private static final long serialVersionUID = 3034435739326030899L;
+    private Number all;
+
+    public Number getAll(){
+        return this.all;
+    }
+    public void setAll(final Number all){
+        this.all = all;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Clouds [all=").append(this.all).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Coord.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Coord.java
new file mode 100644 (file)
index 0000000..9eececd
--- /dev/null
@@ -0,0 +1,30 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+
+public class Coord implements Serializable {
+    private static final long serialVersionUID = 7151637605146377486L;
+    private Number lat;
+    private Number lon;
+
+    public Number getLat(){
+        return this.lat;
+    }
+    public void setLat(final Number lat){
+        this.lat = lat;
+    }
+    public Number getLon(){
+        return this.lon;
+    }
+    public void setLon(final Number lon){
+        this.lon = lon;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Coord [lat=").append(this.lat).append(", lon=").append(this.lon)
+        .append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Current.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Current.java
new file mode 100644 (file)
index 0000000..a7bc22e
--- /dev/null
@@ -0,0 +1,139 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Auto generated by: http://jsongen.byingtondesign.com/
+ * (with my own modifications)
+ *
+ */
+public class Current implements Serializable {
+    private static final long serialVersionUID = -730690341739860818L;
+    private String base;
+    private Clouds clouds;
+    private Number cod;
+    private Coord coord;
+    private Number dt;
+    private Number id;
+    private Main main;
+    private String name;
+    private Rain rain;
+    private Snow snow;
+    private Sys sys;
+    private List<Weather> weather;
+    private Wind wind;
+    private byte[] iconData;
+    private Date date;
+
+    public String getBase(){
+        return this.base;
+    }
+    public void setBase(final String base){
+        this.base = base;
+    }
+    public Clouds getClouds(){
+        return this.clouds;
+    }
+    public void setClouds(final Clouds clouds){
+        this.clouds = clouds;
+    }
+
+    public Number getCod() {
+        return this.cod;
+    }
+
+    public void setCod(final Number cod) {
+        this.cod = cod;
+    }
+    public Coord getCoord(){
+        return this.coord;
+    }
+    public void setCoord(final Coord coord){
+        this.coord = coord;
+    }
+    public Number getDt(){
+        return this.dt;
+    }
+    public void setDt(final Number dt){
+        this.dt = dt;
+    }
+    public Number getId(){
+        return this.id;
+    }
+    public void setId(final Number id){
+        this.id = id;
+    }
+    public Main getMain(){
+        return this.main;
+    }
+    public void setMain(final Main main){
+        this.main = main;
+    }
+    public String getName(){
+        return this.name;
+    }
+    public void setName(final String name){
+        this.name = name;
+    }
+    public Rain getRain(){
+        return this.rain;
+    }
+    public void setRain(final Rain rain){
+        this.rain = rain;
+    }
+    public Snow getSnow() {
+        return this.snow;
+    }
+    public void setSnow(final Snow snow) {
+        this.snow = snow;
+    }
+    public Sys getSys(){
+        return this.sys;
+    }
+    public void setSys(final Sys sys){
+        this.sys = sys;
+    }
+    public List<Weather> getWeather(){
+        return this.weather;
+    }
+    public void setWeather(final List<Weather> weather){
+        this.weather = weather;
+    }
+    public Wind getWind(){
+        return this.wind;
+    }
+    public void setWind(final Wind wind){
+        this.wind = wind;
+    }
+
+    public byte[] getIconData() {
+        return this.iconData;
+    }
+
+    public void setIconData(final byte[] iconData) {
+        this.iconData = iconData;
+    }
+
+    public Date getDate() {
+        return this.date;
+    }
+
+    public void setDate(final Date date) {
+        this.date = date;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Current [base=").append(this.base).append(", clouds=")
+        .append(this.clouds).append(", cod=").append(this.cod).append(", coord=")
+        .append(this.coord).append(", dt=").append(this.dt).append(", id=").append(this.id)
+        .append(", main=").append(this.main).append(", name=").append(this.name)
+        .append(", rain=").append(this.rain).append(", snow=").append(this.snow)
+        .append(", sys=").append(this.sys).append(", weather=").append(this.weather)
+        .append(", wind=").append(this.wind).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Main.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Main.java
new file mode 100644 (file)
index 0000000..397f71b
--- /dev/null
@@ -0,0 +1,73 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+
+public class Main implements Serializable {
+    private static final long serialVersionUID = -6000879164436289447L;
+    private Number grnd_level;
+    private Number humidity;
+    private Number pressure;
+    private Number sea_level;
+    private Number temp;
+    private Number temp_max;
+    private Number temp_min;
+
+    public Number getGrnd_level() {
+        return this.grnd_level;
+    }
+
+    public void setGrnd_level(final Number grnd_level) {
+        this.grnd_level = grnd_level;
+    }
+
+    public Number getHumidity(){
+        return this.humidity;
+    }
+    public void setHumidity(final Number humidity){
+        this.humidity = humidity;
+    }
+    public Number getPressure(){
+        return this.pressure;
+    }
+    public void setPressure(final Number pressure){
+        this.pressure = pressure;
+    }
+
+    public Number getSea_level() {
+        return this.sea_level;
+    }
+
+    public void setSea_level(final Number sea_level) {
+        this.sea_level = sea_level;
+    }
+
+    public Number getTemp(){
+        return this.temp;
+    }
+    public void setTemp(final Number temp){
+        this.temp = temp;
+    }
+    public Number getTemp_max(){
+        return this.temp_max;
+    }
+    public void setTemp_max(final Number temp_max){
+        this.temp_max = temp_max;
+    }
+    public Number getTemp_min(){
+        return this.temp_min;
+    }
+    public void setTemp_min(final Number temp_min){
+        this.temp_min = temp_min;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Main [grnd_level=").append(this.grnd_level).append(", humidity=")
+        .append(this.humidity).append(", pressure=").append(this.pressure)
+        .append(", sea_level=").append(this.sea_level).append(", temp=").append(this.temp)
+        .append(", temp_max=").append(this.temp_max).append(", temp_min=")
+        .append(this.temp_min).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Rain.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Rain.java
new file mode 100644 (file)
index 0000000..0e151ef
--- /dev/null
@@ -0,0 +1,23 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+
+public class Rain implements Serializable {
+    private static final long serialVersionUID = 1318464783605029435L;
+    private Number three;
+
+    public Number get3h(){
+        return this.three;
+    }
+
+    public void set3h(final Number threeh) {
+        this.three = threeh;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Rain [three=").append(this.three).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Snow.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Snow.java
new file mode 100644 (file)
index 0000000..5174763
--- /dev/null
@@ -0,0 +1,23 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+
+public class Snow implements Serializable {
+    private static final long serialVersionUID = 6769716772818311879L;
+    private Number three;
+
+    public Number get3h() {
+        return this.three;
+    }
+
+    public void set3h(final Number threeh) {
+        this.three = threeh;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Snow [three=").append(this.three).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Sys.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Sys.java
new file mode 100644 (file)
index 0000000..3e20bef
--- /dev/null
@@ -0,0 +1,46 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+
+
+public class Sys implements Serializable {
+    private static final long serialVersionUID = 5333083785731053139L;
+    private String country;
+    private Number message;
+    private Number sunrise;
+    private Number sunset;
+
+    public String getCountry(){
+        return this.country;
+    }
+    public void setCountry(final String country){
+        this.country = country;
+    }
+    public Number getMessage(){
+        return this.message;
+    }
+    public void setMessage(final Number message){
+        this.message = message;
+    }
+    public Number getSunrise(){
+        return this.sunrise;
+    }
+    public void setSunrise(final Number sunrise){
+        this.sunrise = sunrise;
+    }
+    public Number getSunset(){
+        return this.sunset;
+    }
+    public void setSunset(final Number sunset){
+        this.sunset = sunset;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Sys [country=").append(this.country).append(", message=")
+        .append(this.message).append(", sunrise=").append(this.sunrise).append(", sunset=")
+        .append(this.sunset).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Weather.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Weather.java
new file mode 100644 (file)
index 0000000..fc44d20
--- /dev/null
@@ -0,0 +1,45 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+
+public class Weather implements Serializable {
+    private static final long serialVersionUID = -34336548786316655L;
+    private String description;
+    private String icon;
+    private Number id;
+    private String main;
+
+    public String getDescription(){
+        return this.description;
+    }
+    public void setDescription(final String description){
+        this.description = description;
+    }
+    public String getIcon(){
+        return this.icon;
+    }
+    public void setIcon(final String icon){
+        this.icon = icon;
+    }
+    public Number getId(){
+        return this.id;
+    }
+    public void setId(final Number id){
+        this.id = id;
+    }
+    public String getMain(){
+        return this.main;
+    }
+    public void setMain(final String main){
+        this.main = main;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Weather [description=").append(this.description).append(", icon=")
+        .append(this.icon).append(", id=").append(this.id).append(", main=")
+        .append(this.main).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/currentweather/Wind.java b/app/src/main/java/de/example/exampletdd/model/currentweather/Wind.java
new file mode 100644 (file)
index 0000000..4edc55d
--- /dev/null
@@ -0,0 +1,30 @@
+package de.example.exampletdd.model.currentweather;
+
+import java.io.Serializable;
+
+public class Wind implements Serializable {
+    private static final long serialVersionUID = 5495842422633674631L;
+    private Number deg;
+    private Number speed;
+
+    public Number getDeg(){
+        return this.deg;
+    }
+    public void setDeg(final Number deg){
+        this.deg = deg;
+    }
+    public Number getSpeed(){
+        return this.speed;
+    }
+    public void setSpeed(final Number speed){
+        this.speed = speed;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Wind [deg=").append(this.deg).append(", speed=").append(this.speed)
+        .append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/forecastweather/City.java b/app/src/main/java/de/example/exampletdd/model/forecastweather/City.java
new file mode 100644 (file)
index 0000000..904ff5d
--- /dev/null
@@ -0,0 +1,53 @@
+package de.example.exampletdd.model.forecastweather;
+
+import java.io.Serializable;
+
+
+public class City implements Serializable {
+    private static final long serialVersionUID = 3079687975077030704L;
+    private Coord coord;
+    private String country;
+    private Number id;
+    private String name;
+    private Number population;
+
+    public Coord getCoord(){
+        return this.coord;
+    }
+    public void setCoord(final Coord coord){
+        this.coord = coord;
+    }
+    public String getCountry(){
+        return this.country;
+    }
+    public void setCountry(final String country){
+        this.country = country;
+    }
+    public Number getId(){
+        return this.id;
+    }
+    public void setId(final Number id){
+        this.id = id;
+    }
+    public String getName(){
+        return this.name;
+    }
+    public void setName(final String name){
+        this.name = name;
+    }
+    public Number getPopulation(){
+        return this.population;
+    }
+    public void setPopulation(final Number population){
+        this.population = population;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("City [coord=").append(this.coord).append(", country=").append(this.country)
+        .append(", id=").append(this.id).append(", name=").append(this.name)
+        .append(", population=").append(this.population).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/forecastweather/Coord.java b/app/src/main/java/de/example/exampletdd/model/forecastweather/Coord.java
new file mode 100644 (file)
index 0000000..fcfee58
--- /dev/null
@@ -0,0 +1,30 @@
+package de.example.exampletdd.model.forecastweather;
+
+import java.io.Serializable;
+
+public class Coord implements Serializable {
+    private static final long serialVersionUID = 8069257976701986700L;
+    private Number lat;
+    private Number lon;
+
+    public Number getLat(){
+        return this.lat;
+    }
+    public void setLat(final Number lat){
+        this.lat = lat;
+    }
+    public Number getLon(){
+        return this.lon;
+    }
+    public void setLon(final Number lon){
+        this.lon = lon;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Coord [lat=").append(this.lat).append(", lon=").append(this.lon)
+        .append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/forecastweather/Forecast.java b/app/src/main/java/de/example/exampletdd/model/forecastweather/Forecast.java
new file mode 100644 (file)
index 0000000..5a59a02
--- /dev/null
@@ -0,0 +1,62 @@
+package de.example.exampletdd.model.forecastweather;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Auto generated by: http://jsongen.byingtondesign.com/
+ * (with my own modifications)
+ *
+ */
+public class Forecast implements Serializable {
+    private static final long serialVersionUID = 5095443678019686190L;
+    private City city;
+    private Number cnt;
+    private Number cod;
+    private List<de.example.exampletdd.model.forecastweather.List> list;
+    private Number message;
+
+    public City getCity(){
+        return this.city;
+    }
+    public void setCity(final City city){
+        this.city = city;
+    }
+    public Number getCnt(){
+        return this.cnt;
+    }
+    public void setCnt(final Number cnt){
+        this.cnt = cnt;
+    }
+
+    public Number getCod() {
+        return this.cod;
+    }
+
+    public void setCod(final Number cod) {
+        this.cod = cod;
+    }
+
+    public List<de.example.exampletdd.model.forecastweather.List> getList() {
+        return this.list;
+    }
+
+    public void setList(final List<de.example.exampletdd.model.forecastweather.List> list) {
+        this.list = list;
+    }
+    public Number getMessage(){
+        return this.message;
+    }
+    public void setMessage(final Number message){
+        this.message = message;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Forecast [city=").append(this.city).append(", cnt=")
+        .append(this.cnt).append(", cod=").append(this.cod).append(", list=")
+        .append(this.list).append(", message=").append(this.message).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/forecastweather/List.java b/app/src/main/java/de/example/exampletdd/model/forecastweather/List.java
new file mode 100644 (file)
index 0000000..2104579
--- /dev/null
@@ -0,0 +1,93 @@
+package de.example.exampletdd.model.forecastweather;
+
+import java.io.Serializable;
+
+
+public class List implements Serializable {
+    private static final long serialVersionUID = 838468273188666785L;
+    private Number clouds;
+    private Number deg;
+    private Number dt;
+    private Number humidity;
+    private Number pressure;
+    private Number rain;
+    private Number snow;
+    private Number speed;
+    private Temp temp;
+    private java.util.List<Weather> weather;
+
+    public Number getClouds(){
+        return this.clouds;
+    }
+    public void setClouds(final Number clouds){
+        this.clouds = clouds;
+    }
+    public Number getDeg(){
+        return this.deg;
+    }
+    public void setDeg(final Number deg){
+        this.deg = deg;
+    }
+    public Number getDt(){
+        return this.dt;
+    }
+    public void setDt(final Number dt){
+        this.dt = dt;
+    }
+    public Number getHumidity(){
+        return this.humidity;
+    }
+    public void setHumidity(final Number humidity){
+        this.humidity = humidity;
+    }
+    public Number getPressure(){
+        return this.pressure;
+    }
+    public void setPressure(final Number pressure){
+        this.pressure = pressure;
+    }
+    public Number getRain(){
+        return this.rain;
+    }
+    public void setRain(final Number rain){
+        this.rain = rain;
+    }
+    public Number getSnow() {
+        return this.snow;
+    }
+    public void setSnow(final Number snow) {
+        this.snow = snow;
+    }
+    public Number getSpeed(){
+        return this.speed;
+    }
+    public void setSpeed(final Number speed){
+        this.speed = speed;
+    }
+    public Temp getTemp(){
+        return this.temp;
+    }
+    public void setTemp(final Temp temp){
+        this.temp = temp;
+    }
+
+    public java.util.List<Weather> getWeather() {
+        return this.weather;
+    }
+
+    public void setWeather(final java.util.List<Weather> weather) {
+        this.weather = weather;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("List [clouds=").append(this.clouds).append(", deg=").append(this.deg)
+        .append(", dt=").append(this.dt).append(", humidity=").append(this.humidity)
+        .append(", pressure=").append(this.pressure).append(", rain=").append(this.rain)
+        .append(", snow=").append(this.snow).append(", speed=").append(this.speed)
+        .append(", temp=").append(this.temp).append(", weather=").append(this.weather)
+        .append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/forecastweather/Temp.java b/app/src/main/java/de/example/exampletdd/model/forecastweather/Temp.java
new file mode 100644 (file)
index 0000000..e4b1a7a
--- /dev/null
@@ -0,0 +1,60 @@
+package de.example.exampletdd.model.forecastweather;
+
+import java.io.Serializable;
+
+public class Temp implements Serializable {
+    private static final long serialVersionUID = -7614799035018271127L;
+    private Number day;
+    private Number eve;
+    private Number max;
+    private Number min;
+    private Number morn;
+    private Number night;
+
+    public Number getDay(){
+        return this.day;
+    }
+    public void setDay(final Number day){
+        this.day = day;
+    }
+    public Number getEve(){
+        return this.eve;
+    }
+    public void setEve(final Number eve){
+        this.eve = eve;
+    }
+    public Number getMax(){
+        return this.max;
+    }
+    public void setMax(final Number max){
+        this.max = max;
+    }
+    public Number getMin(){
+        return this.min;
+    }
+    public void setMin(final Number min){
+        this.min = min;
+    }
+    public Number getMorn(){
+        return this.morn;
+    }
+    public void setMorn(final Number morn){
+        this.morn = morn;
+    }
+    public Number getNight(){
+        return this.night;
+    }
+    public void setNight(final Number night){
+        this.night = night;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Temp [day=").append(this.day).append(", eve=").append(this.eve)
+        .append(", max=").append(this.max).append(", min=").append(this.min)
+        .append(", morn=").append(this.morn).append(", night=").append(this.night)
+        .append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/model/forecastweather/Weather.java b/app/src/main/java/de/example/exampletdd/model/forecastweather/Weather.java
new file mode 100644 (file)
index 0000000..f0de236
--- /dev/null
@@ -0,0 +1,45 @@
+package de.example.exampletdd.model.forecastweather;
+
+import java.io.Serializable;
+
+public class Weather implements Serializable {
+    private static final long serialVersionUID = -5066357704517363241L;
+    private String description;
+    private String icon;
+    private Number id;
+    private String main;
+
+    public String getDescription(){
+        return this.description;
+    }
+    public void setDescription(final String description){
+        this.description = description;
+    }
+    public String getIcon(){
+        return this.icon;
+    }
+    public void setIcon(final String icon){
+        this.icon = icon;
+    }
+    public Number getId(){
+        return this.id;
+    }
+    public void setId(final Number id){
+        this.id = id;
+    }
+    public String getMain(){
+        return this.main;
+    }
+    public void setMain(final String main){
+        this.main = main;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("Weather [description=").append(this.description).append(", icon=")
+        .append(this.icon).append(", id=").append(this.id).append(", main=")
+        .append(this.main).append("]");
+        return builder.toString();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/parser/IJPOSParser.java b/app/src/main/java/de/example/exampletdd/parser/IJPOSParser.java
new file mode 100644 (file)
index 0000000..14a1d55
--- /dev/null
@@ -0,0 +1,17 @@
+package de.example.exampletdd.parser;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonParseException;
+
+import de.example.exampletdd.model.currentweather.Current;
+import de.example.exampletdd.model.forecastweather.Forecast;
+
+public interface IJPOSParser {
+
+    public Current retrieveCurrenFromJPOS(final String jsonData)
+            throws JsonParseException, IOException;
+
+    public Forecast retrieveForecastFromJPOS(final String jsonData)
+            throws JsonParseException, IOException;
+}
diff --git a/app/src/main/java/de/example/exampletdd/parser/JPOSWeatherParser.java b/app/src/main/java/de/example/exampletdd/parser/JPOSWeatherParser.java
new file mode 100644 (file)
index 0000000..b71e342
--- /dev/null
@@ -0,0 +1,405 @@
+package de.example.exampletdd.parser;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+
+import de.example.exampletdd.model.currentweather.Clouds;
+import de.example.exampletdd.model.currentweather.Coord;
+import de.example.exampletdd.model.currentweather.Current;
+import de.example.exampletdd.model.currentweather.Main;
+import de.example.exampletdd.model.currentweather.Rain;
+import de.example.exampletdd.model.currentweather.Sys;
+import de.example.exampletdd.model.currentweather.Wind;
+import de.example.exampletdd.model.forecastweather.City;
+import de.example.exampletdd.model.forecastweather.Forecast;
+import de.example.exampletdd.model.forecastweather.Temp;
+
+public class JPOSWeatherParser implements IJPOSParser {
+
+    @Override
+    public Current retrieveCurrenFromJPOS(final String jsonData)
+            throws JsonParseException, IOException {
+        final JsonFactory f = new JsonFactory();
+
+        final Current currentWeatherData = new Current();
+        currentWeatherData.setClouds(new Clouds());
+        currentWeatherData.setCoord(new Coord());
+        currentWeatherData.setMain(new Main());
+        currentWeatherData.setRain(new Rain());
+        currentWeatherData.setSys(new Sys());
+        currentWeatherData
+        .setWeather(new ArrayList<de.example.exampletdd.model.currentweather.Weather>());
+        currentWeatherData.setWind(new Wind());
+        final JsonParser jParser = f.createParser(jsonData);
+
+        this.getCurrentWeatherData(currentWeatherData, jParser);
+
+        return currentWeatherData;
+    }
+
+    @Override
+    public Forecast retrieveForecastFromJPOS(final String jsonData)
+            throws JsonParseException, IOException {
+        final JsonFactory f = new JsonFactory();
+
+        final Forecast forecastWeatherData = new Forecast();
+        forecastWeatherData
+        .setList(new ArrayList<de.example.exampletdd.model.forecastweather.List>(15));
+        final City city = new City();
+        city.setCoord(new de.example.exampletdd.model.forecastweather.Coord());
+        forecastWeatherData.setCity(city);
+        final JsonParser jParser = f.createParser(jsonData);
+
+        this.getForecastWeatherData(forecastWeatherData, jParser);
+
+        return forecastWeatherData;
+    }
+
+    private void getCurrentWeatherData(final Current currentWeatherData,
+            final JsonParser jParser) throws JsonParseException, IOException {
+        if (jParser.nextToken() == JsonToken.START_OBJECT) {
+
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String fieldname = jParser.getCurrentName();
+                final JsonToken nextToken = jParser.nextToken();
+                if (nextToken == JsonToken.START_OBJECT) {
+                    this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname);
+                }
+                if (nextToken == JsonToken.START_ARRAY) {
+                    JsonToken tokenNext = jParser.nextToken();
+                    while (tokenNext != JsonToken.END_ARRAY) {
+                        if (tokenNext == JsonToken.START_OBJECT) {
+                            this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname);
+                        }
+                        tokenNext = jParser.nextToken();
+                    }
+                }
+                if ((nextToken == JsonToken.VALUE_NUMBER_INT)
+                        || (nextToken == JsonToken.VALUE_STRING)) {
+                    this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname);
+                }
+            }
+        }
+    }
+
+    private void getCurrentWeatherDataObjects(final Current currentWeatherData,
+            final JsonParser jParser, final String fieldname) throws JsonParseException,
+            IOException {
+        if (fieldname == "coord") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("lon".equals(namefield)) {
+                    currentWeatherData.getCoord().setLon(jParser.getDoubleValue());
+                }
+                if ("lat".equals(namefield)) {
+                    currentWeatherData.getCoord().setLat(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "sys") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("message".equals(namefield)) {
+                    currentWeatherData.getSys().setMessage(jParser.getDoubleValue());
+                }
+                if ("country".equals(namefield)) {
+                    currentWeatherData.getSys().setCountry(jParser.getValueAsString());
+                }
+                if ("sunrise".equals(namefield)) {
+                    currentWeatherData.getSys().setSunrise(jParser.getValueAsLong());
+                }
+                if ("sunset".equals(namefield)) {
+                    currentWeatherData.getSys().setSunset(jParser.getValueAsLong());
+                }
+            }
+        }
+        if (fieldname == "weather") {
+            final de.example.exampletdd.model.currentweather.Weather weather = new de.example.exampletdd.model.currentweather.Weather();
+            currentWeatherData.getWeather().add(weather);
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("id".equals(namefield)) {
+                    weather.setId(jParser.getIntValue());
+                }
+                if ("main".equals(namefield)) {
+                    weather.setMain(jParser.getText());
+                }
+                if ("description".equals(namefield)) {
+                    weather.setDescription(jParser.getText());
+                }
+                if ("icon".equals(namefield)) {
+                    weather.setIcon(jParser.getText());
+                }
+
+            }
+        }
+        if (fieldname == "base") {
+            currentWeatherData.setBase(jParser.getText());
+        }
+        if (fieldname == "main") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("temp".equals(namefield)) {
+                    currentWeatherData.getMain().setTemp(jParser.getDoubleValue());
+                }
+                if ("temp_min".equals(namefield)) {
+                    currentWeatherData.getMain().setTemp_min(jParser.getDoubleValue());
+                }
+                if ("temp_max".equals(namefield)) {
+                    currentWeatherData.getMain().setTemp_max(jParser.getDoubleValue());
+                }
+                if ("pressure".equals(namefield)) {
+                    currentWeatherData.getMain().setPressure(jParser.getDoubleValue());
+                }
+                if ("sea_level".equals(namefield)) {
+                    currentWeatherData.getMain().setSea_level(jParser.getDoubleValue());
+                }
+                if ("grnd_level".equals(namefield)) {
+                    currentWeatherData.getMain().setGrnd_level(jParser.getDoubleValue());
+                }
+                if ("humidity".equals(namefield)) {
+                    currentWeatherData.getMain().setHumidity(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "wind") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("speed".equals(namefield)) {
+                    currentWeatherData.getWind().setSpeed(jParser.getDoubleValue());
+                }
+                if ("deg".equals(namefield)) {
+                    currentWeatherData.getWind().setDeg(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "clouds") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("all".equals(namefield)) {
+                    currentWeatherData.getClouds().setAll(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "dt") {
+            currentWeatherData.setDt(jParser.getLongValue());
+        }
+        if (fieldname == "rain") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("3h".equals(namefield)) {
+                    currentWeatherData.getRain().set3h(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "snow") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("3h".equals(namefield)) {
+                    currentWeatherData.getSnow().set3h(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "id") {
+            currentWeatherData.setId(jParser.getLongValue());
+        }
+        if (fieldname == "name") {
+            currentWeatherData.setName(jParser.getText());
+        }
+        if (fieldname == "cod") {
+            currentWeatherData.setCod(jParser.getIntValue());
+        }
+    }
+
+    private void getForecastWeatherData(final Forecast forecastWeatherData,
+            final JsonParser jParser) throws JsonParseException, IOException {
+        if (jParser.nextToken() == JsonToken.START_OBJECT) {
+
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String fieldname = jParser.getCurrentName();
+                final JsonToken nextToken = jParser.nextToken();
+                if (nextToken == JsonToken.START_OBJECT) {
+                    this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname);
+                }
+                if (nextToken == JsonToken.START_ARRAY) {
+                    JsonToken tokenNext = jParser.nextToken();
+                    while (tokenNext != JsonToken.END_ARRAY) {
+                        if (tokenNext == JsonToken.START_OBJECT) {
+                            this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname);
+                        }
+                        tokenNext = jParser.nextToken();
+                    }
+                }
+                if ((nextToken == JsonToken.VALUE_NUMBER_INT)
+                        || (nextToken == JsonToken.VALUE_STRING)) {
+                    this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname);
+                }
+            }
+        }
+    }
+
+    private void getForecastWeatherDataObjects(final Forecast forecastWeatherData,
+            final JsonParser jParser, final String fieldname) throws JsonParseException,
+            IOException {
+
+        if (fieldname == "cod") {
+            final String stringCod = jParser.getText();
+            forecastWeatherData.setCod(Long.valueOf(stringCod));
+        }
+        if (fieldname == "message") {
+            forecastWeatherData.setMessage(jParser.getDoubleValue());
+        }
+        if (fieldname == "city") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                final JsonToken nextToken = jParser.nextToken(); // move to
+                // value
+                if ("id".equals(namefield)) {
+                    forecastWeatherData.getCity().setId(jParser.getLongValue());
+                }
+                if ("name".equals(namefield)) {
+                    forecastWeatherData.getCity().setName(jParser.getText());
+                }
+                if ("coord".equals(namefield)) {
+                    if (nextToken == JsonToken.START_OBJECT) {
+                        this.getForecastWeatherDataObjects(forecastWeatherData, jParser, namefield);
+                    }
+                }
+                if ("country".equals(namefield)) {
+                    forecastWeatherData.getCity().setCountry(jParser.getText());
+                }
+                if ("population".equals(namefield)) {
+                    forecastWeatherData.getCity().setPopulation(jParser.getLongValue());
+                }
+            }
+        }
+        if (fieldname == "cnt") {
+            forecastWeatherData.setCnt(jParser.getIntValue());
+        }
+        if (fieldname == "coord") {
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("lon".equals(namefield)) {
+                    forecastWeatherData.getCity().getCoord().setLon(jParser.getDoubleValue());
+                }
+                if ("lat".equals(namefield)) {
+                    forecastWeatherData.getCity().getCoord().setLat(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "list") {
+            final de.example.exampletdd.model.forecastweather.List list = new de.example.exampletdd.model.forecastweather.List();
+            list.setTemp(new Temp());
+            list.setWeather(new ArrayList<de.example.exampletdd.model.forecastweather.Weather>());
+            forecastWeatherData.getList().add(list);
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                final JsonToken nextToken = jParser.nextToken(); // move to
+                // value
+                if ("dt".equals(namefield)) {
+                    list.setDt(jParser.getLongValue());
+                }
+                if ("temp".equals(namefield)) {
+                    if (nextToken == JsonToken.START_OBJECT) {
+                        this.getForecastWeatherDataObjects(forecastWeatherData, jParser, namefield);
+                    }
+                }
+                if ("pressure".equals(namefield)) {
+                    list.setPressure(jParser.getDoubleValue());
+                }
+                if ("humidity".equals(namefield)) {
+                    list.setHumidity(jParser.getDoubleValue());
+                }
+                if ("weather".equals(namefield)) {
+                    if (nextToken == JsonToken.START_ARRAY) {
+                        JsonToken tokenNext = jParser.nextToken();
+                        while (tokenNext != JsonToken.END_ARRAY) {
+                            if (tokenNext == JsonToken.START_OBJECT) {
+                                this.getForecastWeatherDataObjects(forecastWeatherData, jParser,
+                                        namefield);
+                            }
+                            tokenNext = jParser.nextToken();
+                        }
+                    }
+                }
+                if ("speed".equals(namefield)) {
+                    list.setSpeed(jParser.getDoubleValue());
+                }
+                if ("deg".equals(namefield)) {
+                    list.setDeg(jParser.getDoubleValue());
+                }
+                if ("clouds".equals(namefield)) {
+                    list.setClouds(jParser.getDoubleValue());
+                }
+                if ("rain".equals(namefield)) {
+                    list.setRain(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "temp") {
+            final de.example.exampletdd.model.forecastweather.List list = forecastWeatherData
+                    .getList().get(
+                            (forecastWeatherData.getList().size() - 1));
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+                if ("day".equals(namefield)) {
+                    list.getTemp().setDay(jParser.getDoubleValue());
+                }
+                if ("min".equals(namefield)) {
+                    list.getTemp().setMin(jParser.getDoubleValue());
+                }
+                if ("max".equals(namefield)) {
+                    list.getTemp().setMax(jParser.getDoubleValue());
+                }
+                if ("night".equals(namefield)) {
+                    list.getTemp().setNight(jParser.getDoubleValue());
+                }
+                if ("eve".equals(namefield)) {
+                    list.getTemp().setEve(jParser.getDoubleValue());
+                }
+                if ("morn".equals(namefield)) {
+                    list.getTemp().setMorn(jParser.getDoubleValue());
+                }
+            }
+        }
+        if (fieldname == "weather") {
+            final de.example.exampletdd.model.forecastweather.List list = forecastWeatherData
+                    .getList().get(
+                            (forecastWeatherData.getList().size() - 1));
+            final de.example.exampletdd.model.forecastweather.Weather weather = new de.example.exampletdd.model.forecastweather.Weather();
+            while (jParser.nextToken() != JsonToken.END_OBJECT) {
+                final String namefield = jParser.getCurrentName();
+                jParser.nextToken(); // move to value
+
+                if ("id".equals(namefield)) {
+                    weather.setId(jParser.getIntValue());
+                }
+                if ("main".equals(namefield)) {
+                    weather.setMain(jParser.getText());
+                }
+                if ("description".equals(namefield)) {
+                    weather.setDescription(jParser.getText());
+                }
+                if ("icon".equals(namefield)) {
+                    weather.setIcon(jParser.getText());
+                }
+            }
+            list.getWeather().add(weather);
+        }
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/service/IconsList.java b/app/src/main/java/de/example/exampletdd/service/IconsList.java
new file mode 100644 (file)
index 0000000..ea53085
--- /dev/null
@@ -0,0 +1,143 @@
+package de.example.exampletdd.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import de.example.exampletdd.R;
+
+public enum IconsList {
+    ICON_01d("01d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_clear;
+        }
+    },
+    ICON_01n("01n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_clear_night;
+        }
+    },
+    ICON_02d("02d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_few_clouds;
+        }
+    },
+    ICON_02n("02n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_few_clouds_night;
+        }
+    },
+    ICON_03d("03d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_few_clouds;
+        }
+    },
+    ICON_03n("03n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_few_clouds;
+        }
+    },
+    ICON_04d("04d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_overcast;
+        }
+    },
+    ICON_04n("04n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_overcast;
+        }
+    },
+    ICON_09d("09d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_showers;
+        }
+    },
+    ICON_09n("09n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_showers;
+        }
+    },
+    ICON_10d("10d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_showers_scattered;
+        }
+    },
+    ICON_10n("10n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_showers_scattered;
+        }
+    },
+    ICON_11d("11d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_storm;
+        }
+    },
+    ICON_11n("11n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_storm;
+        }
+    },
+    ICON_13d("13d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_snow;
+        }
+    },
+    ICON_13n("13n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_snow;
+        }
+    },
+    ICON_50d("50d") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_fog;
+        }
+    },
+    ICON_50n("50n") {
+        @Override
+        public int getResourceDrawable() {
+            return R.drawable.weather_fog;
+        }
+    };
+
+    private final String icon;
+    // Map with every enum constant. Class variable initializer. JLS§12.4.2
+    // Executed in textual order.
+    private static final Map<String, IconsList> codeMap = new HashMap<String, IconsList>();
+
+    // Static initializer. JLS§12.4.2 Executed in textual order.
+    static {
+        for (final IconsList code : IconsList.values()) {
+            codeMap.put(code.getIcon(), code);
+        }
+    }
+
+    private IconsList(final String icon) {
+        this.icon = icon;
+    }
+
+    public static final IconsList getIcon(final String icon) {
+        return codeMap.get(icon);
+    }
+
+    private String getIcon() {
+        return this.icon;
+    }
+
+    public abstract int getResourceDrawable();
+}
diff --git a/app/src/main/java/de/example/exampletdd/service/PermanentStorage.java b/app/src/main/java/de/example/exampletdd/service/PermanentStorage.java
new file mode 100644 (file)
index 0000000..49eac40
--- /dev/null
@@ -0,0 +1,140 @@
+package de.example.exampletdd.service;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.StreamCorruptedException;
+
+import android.content.Context;
+import android.util.Log;
+import de.example.exampletdd.model.currentweather.Current;
+import de.example.exampletdd.model.forecastweather.Forecast;
+
+
+/**
+ * TODO: show some error message when there is no enough space for saving files. :/
+ *
+ */
+public class PermanentStorage {
+       private static final String TAG = "PermanentStorage";
+    private static final String CURRENT_DATA_FILE = "current.file";
+    private static final String FORECAST_DATA_FILE = "forecast.file";
+    private final Context context;
+
+    public PermanentStorage(final Context context) {
+        this.context = context;
+    }
+
+    public void saveCurrent(final Current current) {
+       
+        try {
+                       this.saveObject(CURRENT_DATA_FILE, current);
+               } catch (FileNotFoundException e) {
+                       Log.e(TAG, "saveCurrent exception: ", e);
+               } catch (IOException e) {
+                       Log.e(TAG, "saveCurrent exception: ", e);
+               }
+    }
+
+    public Current getCurrent() {
+       
+       try {
+                       return (Current) this.getObject(CURRENT_DATA_FILE);
+               } catch (final StreamCorruptedException e) {
+                       Log.e(TAG, "getCurrent exception: ", e);
+               } catch (final FileNotFoundException e) {
+                       Log.e(TAG, "getCurrent exception: ", e);
+               } catch (final IOException e) {
+                       Log.e(TAG, "getCurrent exception: ", e);
+               } catch (final ClassNotFoundException e) {
+                       Log.e(TAG, "getCurrent exception: ", e);
+               }
+       
+       return null;
+    }
+
+    public void saveForecast(final Forecast forecast) {
+
+       try {
+                       this.saveObject(FORECAST_DATA_FILE, forecast);
+               } catch (FileNotFoundException e) {
+                       Log.e(TAG, "saveForecast exception: ", e);
+               } catch (IOException e) {
+                       Log.e(TAG, "saveForecast exception: ", e);
+               }
+    }
+
+    public Forecast getForecast() {
+        
+       try {
+                       return (Forecast) this.getObject(FORECAST_DATA_FILE);
+               } catch (final StreamCorruptedException e) {
+                       Log.e(TAG, "getForecast exception: ", e);
+               } catch (final FileNotFoundException e) {
+                       Log.e(TAG, "getForecast exception: ", e);
+               } catch (final IOException e) {
+                       Log.e(TAG, "getForecast exception: ", e);
+               } catch (final ClassNotFoundException e) {
+                       Log.e(TAG, "getForecast exception: ", e);
+               }
+       
+       return null;
+    }
+
+    private void saveObject(final String fileName, final Object objectToStore)
+               throws FileNotFoundException, IOException {
+       final String temporaryFileName = fileName.concat(".tmp");
+       
+        final FileOutputStream tmpPersistFile = this.context.openFileOutput(
+                       temporaryFileName, Context.MODE_PRIVATE);
+        try {
+               final ObjectOutputStream oos = new ObjectOutputStream(tmpPersistFile);
+               try {
+                       oos.writeObject(objectToStore);
+                       
+                       // Don't fear the fsync!
+                       // http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/
+                       tmpPersistFile.flush();
+                       tmpPersistFile.getFD().sync();
+               } finally {
+                       oos.close();
+               }
+        } finally {
+               tmpPersistFile.close();
+        }
+
+        this.renameFile(temporaryFileName, fileName);
+    }
+    private Object getObject(final String fileName) throws StreamCorruptedException, FileNotFoundException,
+                                                                                                          IOException, ClassNotFoundException {
+       final InputStream persistFile = this.context.openFileInput(fileName);
+       try {
+               final ObjectInputStream ois = new ObjectInputStream(persistFile);
+               try {
+                       return ois.readObject();
+               } finally {
+                       ois.close();
+               }
+       } finally {
+               persistFile.close();
+       }
+    } 
+    
+    private void renameFile(final String fromFileName, final String toFileName) throws IOException {
+        final File filesDir = this.context.getFilesDir();
+        final File fromFile = new File(filesDir, fromFileName);
+        final File toFile = new File(filesDir, toFileName);
+        if (!fromFile.renameTo(toFile)) {
+               if (!fromFile.delete()) {
+                       throw new IOException("PermanentStorage, delete file error");
+               }       
+               throw new IOException("PermanentStorage, rename file error");
+        }
+    }
+}
+
diff --git a/app/src/main/java/de/example/exampletdd/service/ServiceParser.java b/app/src/main/java/de/example/exampletdd/service/ServiceParser.java
new file mode 100644 (file)
index 0000000..e05a67f
--- /dev/null
@@ -0,0 +1,64 @@
+package de.example.exampletdd.service;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Locale;
+
+import com.fasterxml.jackson.core.JsonParseException;
+
+import de.example.exampletdd.model.currentweather.Current;
+import de.example.exampletdd.model.forecastweather.Forecast;
+import de.example.exampletdd.parser.IJPOSParser;
+
+public class ServiceParser {
+    private final IJPOSParser JPOSParser;
+
+    public ServiceParser(final IJPOSParser JPOSWeatherParser) {
+        this.JPOSParser = JPOSWeatherParser;
+    }
+
+    public Current retrieveCurrentFromJPOS(final String jsonData)
+            throws JsonParseException, IOException {
+        return this.JPOSParser.retrieveCurrenFromJPOS(jsonData);
+    }
+
+    public Forecast retrieveForecastFromJPOS(final String jsonData)
+            throws JsonParseException, IOException {
+        return this.JPOSParser.retrieveForecastFromJPOS(jsonData);
+    }
+
+    public String createURIAPIForecast(final String urlAPI, final String APIVersion,
+            final double latitude, final double longitude, final String resultsNumber) {
+
+        final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US);
+        final Object[] values = new Object[4];
+        values[0] = APIVersion;
+        values[1] = latitude;
+        values[2] = longitude;
+        values[3] = resultsNumber;
+
+        return formatURIAPI.format(values);
+    }
+
+    public String createURIAPICurrent(final String urlAPI, final String APIVersion,
+            final double latitude, final double longitude) {
+
+        final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US);
+        final Object[] values = new Object[3];
+        values[0] = APIVersion;
+        values[1] = latitude;
+        values[2] = longitude;
+
+        return formatURIAPI.format(values);
+    }
+
+    public String createURIAPIicon(final String icon, final String urlAPI) {
+
+        final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US);
+        final Object[] values = new Object[1];
+        values[0] = icon;
+
+        return formatURIAPI.format(values);
+    }
+
+}
diff --git a/app/src/main/java/de/example/exampletdd/widget/WidgetConfigure.java b/app/src/main/java/de/example/exampletdd/widget/WidgetConfigure.java
new file mode 100644 (file)
index 0000000..bb5d8ca
--- /dev/null
@@ -0,0 +1,88 @@
+package de.example.exampletdd.widget;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.Fragment;
+import android.appwidget.AppWidgetManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import de.example.exampletdd.R;
+
+public class WidgetConfigure extends Activity {
+       private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+       
+    final View.OnClickListener mOnClickListener = new View.OnClickListener() {
+        public void onClick(View v) {
+
+               
+            // When the button is clicked, save the string in our prefs and return that they
+            // clicked OK.
+            // Push widget update to surface with newly set prefix
+            final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(
+                       WidgetConfigure.this.getApplicationContext());
+            WidgetProvider.updateAppWidget(
+                       WidgetConfigure.this.getApplicationContext(),
+                       appWidgetManager,
+                    mAppWidgetId);
+
+            // Make sure we pass back the original appWidgetId
+            final Intent resultValue = new Intent();
+            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+            WidgetConfigure.this.setResult(RESULT_OK, resultValue);
+            finish();
+        }
+    };
+
+    @Override
+    public void onCreate(final Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Find the widget id from the intent. 
+        final Intent intent = getIntent();
+        final Bundle extras = intent.getExtras();
+        boolean isActionFromUser = false;
+
+        if (extras != null) {
+            mAppWidgetId = extras.getInt(
+                    AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+            
+            isActionFromUser = extras.getBoolean("actionFromUser", false);
+        }
+        
+        // If they gave us an intent without the widget id, just bail.
+       if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+               this.finish();
+       }
+       
+        if (!isActionFromUser) {
+            // Set the result to CANCELED.  This will cause the widget host to cancel
+            // out of the widget placement if they press the back button.
+            this.setResult(RESULT_CANCELED);
+        }
+        
+        // Set the view layout resource to use.
+        this.setContentView(R.layout.appwidget_configure);
+        
+       final Bundle args = new Bundle();
+       args.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+       final Fragment preferences = new WidgetPreferences();
+        preferences.setRetainInstance(true);
+       preferences.setArguments(args);
+        this.getFragmentManager()
+        .beginTransaction()
+        .replace(R.id.weather_appwidget_configure_preferences, preferences)
+        .commit();
+        
+        // Bind the action for the save button.
+        this.findViewById(R.id.weather_appwidget_configure_save_button).setOnClickListener(mOnClickListener);
+    }
+    
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final ActionBar actionBar = this.getActionBar();
+        actionBar.setTitle(this.getString(R.string.widget_preferences_action_settings));
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/widget/WidgetPreferences.java b/app/src/main/java/de/example/exampletdd/widget/WidgetPreferences.java
new file mode 100644 (file)
index 0000000..7744ea8
--- /dev/null
@@ -0,0 +1,172 @@
+package de.example.exampletdd.widget;
+
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.PreferenceFragment;
+import android.preference.SwitchPreference;
+import de.example.exampletdd.R;
+
+/**
+ * TODO:
+ * IT DOES NOT WORK IF USER IS WORKING WITH TWO OR MORE WIDGET PREFERENCE WINDOWS AT THE SAME TIME
+ * (hopefully nobody will realize...)
+ * How to implement custom preference activities (no extending from PreferenceActivity or PreferenceFragment)
+ * without pain?
+ */
+public class WidgetPreferences extends PreferenceFragment implements OnSharedPreferenceChangeListener {
+       private int appWidgetId;
+       
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Retain this fragment across configuration changes.
+       this.setRetainInstance(true);
+       
+       final Bundle bundle = this.getArguments();
+       appWidgetId = bundle.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+       
+        // Load the preferences from an XML resource
+        this.addPreferencesFromResource(R.xml.appwidget_preferences);
+
+
+        /******************* Show/hide country field *******************/
+        String keyPreference = this.getActivity().getApplicationContext().getString(
+                R.string.widget_preferences_country_switch_key);
+        String realKeyPreference = keyPreference + "_" + appWidgetId;
+        
+        // What was saved to permanent storage (or default values if it is the first time)
+        boolean countryValue = this.getActivity().getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE)
+                       .getBoolean(realKeyPreference, false);
+        
+        // What is shown on the screen
+        final SwitchPreference countryPref = (SwitchPreference) this.findPreference(keyPreference);
+        countryPref.setChecked(countryValue);
+
+        /********************* Temperature units  **********************/
+        final String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
+        final String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value);
+
+        keyPreference = this.getActivity().getApplicationContext().getString(
+                R.string.widget_preferences_temperature_key);
+        realKeyPreference = keyPreference + "_" + appWidgetId;
+
+
+        // What was saved to permanent storage (or default values if it is the first time)
+        final String tempValue = this.getActivity().getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE)
+                       .getString(realKeyPreference, this.getString(R.string.weather_preferences_temperature_celsius));
+        String humanValue = this.getString(R.string.weather_preferences_temperature_celsius_human_value);
+        int index = 0;
+        if (tempValue.equals(values[0])) {
+               index = 0;
+            humanValue = humanValues[0];
+        } else if (tempValue.equals(values[1])) {
+               index = 1;
+            humanValue = humanValues[1];
+        } else if (tempValue.equals(values[2])) {
+               index = 2;
+            humanValue = humanValues[2];
+        }
+
+
+        // What is shown on the screen
+        final ListPreference listPref = (ListPreference) this.findPreference(keyPreference);
+        listPref.setSummary(humanValue);
+        listPref.setValueIndex(index);
+        listPref.setValue(tempValue);
+    }
+
+    @Override
+       public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
+
+       /******************* Show/hide country field *******************/
+        String keyPreference = this.getActivity().getApplicationContext().getString(
+                       R.string.widget_preferences_country_switch_key);
+        if (key.equals(keyPreference)) {
+               final String realKeyPreference = keyPreference + "_" + appWidgetId;
+               // Saving to permanent storage.
+               final SharedPreferences.Editor prefs =
+                               this.getActivity().getSharedPreferences(
+                                               "WIDGET_PREFERENCES", 
+                                               Context.MODE_PRIVATE).edit();
+               // What is shown on the screen
+               final SwitchPreference preference = (SwitchPreference) this.findPreference(key);
+               if (preference.isChecked())
+               {
+                       // Saving to permanent storage.
+                       prefs.putBoolean(realKeyPreference, true); 
+               } else {
+                       // Saving to permanent storage.
+                       prefs.putBoolean(realKeyPreference, false); 
+               }
+               prefs.commit();
+        }
+
+       /********************* Temperature units  **********************/
+        keyPreference = this.getActivity().getApplicationContext().getString(
+                R.string.widget_preferences_temperature_key);
+        if (key.equals(keyPreference)) {
+               final String[] values = this.getResources().getStringArray(
+                               R.array.weather_preferences_temperature);
+               final String[] humanValues = this.getResources().getStringArray(
+                               R.array.weather_preferences_temperature_human_value);
+               
+               // What is shown on the screen
+               final ListPreference listPref = (ListPreference) this.findPreference(key);
+               final String value = listPref.getValue();
+               String humanValue = "";
+               if (value.equals(values[0])) {
+                       humanValue = humanValues[0];
+               } else if (value.equals(values[1])) {
+                       humanValue = humanValues[1];
+               } else if (value.equals(values[2])) {
+                       humanValue = humanValues[2];
+               }
+               // Update data on screen
+               listPref.setSummary(humanValue);
+               
+               
+               // Saving to permanent storage.
+            final String realKeyPreference = keyPreference + "_" + appWidgetId;
+            
+               final SharedPreferences.Editor prefs =
+                               this.getActivity().getSharedPreferences(
+                                               "WIDGET_PREFERENCES", 
+                                               Context.MODE_PRIVATE).edit();
+            prefs.putString(realKeyPreference, value);
+            prefs.commit();
+               return;
+        }
+        
+        
+
+       }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        this.getPreferenceManager().getSharedPreferences()
+        .registerOnSharedPreferenceChangeListener(this);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        this.getPreferenceManager().getSharedPreferences()
+        .unregisterOnSharedPreferenceChangeListener(this);
+    }
+    
+    public static void deletePreference(final Context context, final int appWidgetId) {
+       final String keyPreference = context.getApplicationContext().getString(
+                R.string.widget_preferences_temperature_key);
+        final String realKeyPreference = keyPreference + "_" + appWidgetId;
+
+       final SharedPreferences.Editor prefs = context.getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE).edit();
+       prefs.remove(realKeyPreference);
+       prefs.commit();
+    }
+}
diff --git a/app/src/main/java/de/example/exampletdd/widget/WidgetProvider.java b/app/src/main/java/de/example/exampletdd/widget/WidgetProvider.java
new file mode 100644 (file)
index 0000000..b5126f6
--- /dev/null
@@ -0,0 +1,64 @@
+package de.example.exampletdd.widget;
+
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import de.example.exampletdd.WidgetIntentService;
+
+public class WidgetProvider extends AppWidgetProvider {
+
+    @Override
+    public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
+        // For each widget that needs an update, get the text that we should display:
+        //   - Create a RemoteViews object for it
+        //   - Set the text in the RemoteViews object
+        //   - Tell the AppWidgetManager to show that views object for the widget.
+        final int N = appWidgetIds.length;
+        for (int i=0; i<N; i++) {
+            int appWidgetId = appWidgetIds[i];
+            // To prevent any ANR timeouts, we perform the update in a service
+               final Intent intent = new Intent(context.getApplicationContext(), WidgetIntentService.class);
+               intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+               intent.putExtra("updateByApp", false);
+            context.startService(intent);
+        }
+    }
+    
+    @Override
+    public void onDeleted(final Context context, final int[] appWidgetIds) {
+        // When the user deletes the widget, delete the preference associated with it.
+        final int N = appWidgetIds.length;
+        for (int i=0; i<N; i++) {
+               WidgetPreferences.deletePreference(context, appWidgetIds[i]);
+        }
+    }
+    
+    static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager, final int appWidgetId) {
+
+        int widgetId;
+        Bundle myOptions = appWidgetManager.getAppWidgetOptions(appWidgetId);
+
+        // Get the value of OPTION_APPWIDGET_HOST_CATEGORY
+        int category = myOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1);
+
+        // If the value is WIDGET_CATEGORY_KEYGUARD, it's a lockscreen widget
+        boolean isKeyguard = category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
+        
+        // Once you know the widget's category, you can optionally load a different base layout, set different 
+        // properties, and so on. For example:
+        //int baseLayout = isKeyguard ? R.layout.keyguard_widget_layout : R.layout.widget_layout;
+        
+        // Construct the RemoteViews object.  It takes the package name (in our case, it's our
+        // package, but it needs this because on the other side it's the widget host inflating
+        // the layout from our package).
+        //final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget);
+        
+        final Intent intent = new Intent(context.getApplicationContext(), WidgetIntentService.class);
+       intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+        context.startService(intent);
+    }
+}
diff --git a/app/src/main/res/anim/weather_map_enter_progress.xml b/app/src/main/res/anim/weather_map_enter_progress.xml
new file mode 100644 (file)
index 0000000..c747270
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set>
+    <translate xmlns:android="http://schemas.android.com/apk/res/android"
+               android:fromYDelta="100%"
+               android:toYDelta="0%"
+               android:interpolator="@android:anim/decelerate_interpolator"
+               android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/app/src/main/res/anim/weather_map_exit_progress.xml b/app/src/main/res/anim/weather_map_exit_progress.xml
new file mode 100644 (file)
index 0000000..f425b7e
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set>
+    <translate xmlns:android="http://schemas.android.com/apk/res/android"
+               android:fromYDelta="0%"
+               android:toYDelta="-100%"
+               android:interpolator="@android:anim/accelerate_interpolator"
+               android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/app/src/main/res/drawable-hdpi/ic_action_import_export.png b/app/src/main/res/drawable-hdpi/ic_action_import_export.png
new file mode 100644 (file)
index 0000000..18c0fe7
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_import_export.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_map.png b/app/src/main/res/drawable-hdpi/ic_action_map.png
new file mode 100644 (file)
index 0000000..370cf5c
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_map.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_place.png b/app/src/main/res/drawable-hdpi/ic_action_place.png
new file mode 100644 (file)
index 0000000..dba994d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_place.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_refresh.png b/app/src/main/res/drawable-hdpi/ic_action_refresh.png
new file mode 100644 (file)
index 0000000..dae2790
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_refresh.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_search.png b/app/src/main/res/drawable-hdpi/ic_action_search.png
new file mode 100644 (file)
index 0000000..772e359
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_search.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_action_settings.png b/app/src/main/res/drawable-hdpi/ic_action_settings.png
new file mode 100644 (file)
index 0000000..54eecde
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_settings.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..288b665
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_menu_settings_holo_light.png b/app/src/main/res/drawable-hdpi/ic_menu_settings_holo_light.png
new file mode 100644 (file)
index 0000000..577e055
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_menu_settings_holo_light.png differ
diff --git a/app/src/main/res/drawable-hdpi/thermometer.png b/app/src/main/res/drawable-hdpi/thermometer.png
new file mode 100644 (file)
index 0000000..89f39a8
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/thermometer.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_clear.png b/app/src/main/res/drawable-hdpi/weather_clear.png
new file mode 100644 (file)
index 0000000..974da61
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_clear.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_clear_night.png b/app/src/main/res/drawable-hdpi/weather_clear_night.png
new file mode 100644 (file)
index 0000000..2db4d82
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_clear_night.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_few_clouds.png b/app/src/main/res/drawable-hdpi/weather_few_clouds.png
new file mode 100644 (file)
index 0000000..ab3e430
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_few_clouds.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_few_clouds_night.png b/app/src/main/res/drawable-hdpi/weather_few_clouds_night.png
new file mode 100644 (file)
index 0000000..67ee004
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_few_clouds_night.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_fog.png b/app/src/main/res/drawable-hdpi/weather_fog.png
new file mode 100644 (file)
index 0000000..bc3c429
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_fog.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_overcast.png b/app/src/main/res/drawable-hdpi/weather_overcast.png
new file mode 100644 (file)
index 0000000..8075b13
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_overcast.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_severe_alert.png b/app/src/main/res/drawable-hdpi/weather_severe_alert.png
new file mode 100644 (file)
index 0000000..42334e8
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_severe_alert.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_showers.png b/app/src/main/res/drawable-hdpi/weather_showers.png
new file mode 100644 (file)
index 0000000..d2a456a
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_showers.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_showers_scattered.png b/app/src/main/res/drawable-hdpi/weather_showers_scattered.png
new file mode 100644 (file)
index 0000000..e58ade9
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_showers_scattered.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_snow.png b/app/src/main/res/drawable-hdpi/weather_snow.png
new file mode 100644 (file)
index 0000000..4812c8c
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_snow.png differ
diff --git a/app/src/main/res/drawable-hdpi/weather_storm.png b/app/src/main/res/drawable-hdpi/weather_storm.png
new file mode 100644 (file)
index 0000000..b829abf
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/weather_storm.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_import_export.png b/app/src/main/res/drawable-mdpi/ic_action_import_export.png
new file mode 100644 (file)
index 0000000..95914cc
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_import_export.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_map.png b/app/src/main/res/drawable-mdpi/ic_action_map.png
new file mode 100644 (file)
index 0000000..50a9100
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_map.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_place.png b/app/src/main/res/drawable-mdpi/ic_action_place.png
new file mode 100644 (file)
index 0000000..ce055ca
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_place.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_refresh.png b/app/src/main/res/drawable-mdpi/ic_action_refresh.png
new file mode 100644 (file)
index 0000000..94ab6f4
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_refresh.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_search.png b/app/src/main/res/drawable-mdpi/ic_action_search.png
new file mode 100644 (file)
index 0000000..4edb1ff
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_search.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_action_settings.png b/app/src/main/res/drawable-mdpi/ic_action_settings.png
new file mode 100644 (file)
index 0000000..25c36db
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_settings.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..6ae570b
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-mdpi/thermometer.png b/app/src/main/res/drawable-mdpi/thermometer.png
new file mode 100644 (file)
index 0000000..f645657
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/thermometer.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_clear.png b/app/src/main/res/drawable-mdpi/weather_clear.png
new file mode 100644 (file)
index 0000000..0bdb0da
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_clear.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_clear_night.png b/app/src/main/res/drawable-mdpi/weather_clear_night.png
new file mode 100644 (file)
index 0000000..2617ec1
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_clear_night.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_few_clouds.png b/app/src/main/res/drawable-mdpi/weather_few_clouds.png
new file mode 100644 (file)
index 0000000..5a78bd0
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_few_clouds.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_few_clouds_night.png b/app/src/main/res/drawable-mdpi/weather_few_clouds_night.png
new file mode 100644 (file)
index 0000000..3dcd13f
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_few_clouds_night.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_fog.png b/app/src/main/res/drawable-mdpi/weather_fog.png
new file mode 100644 (file)
index 0000000..7d99916
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_fog.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_overcast.png b/app/src/main/res/drawable-mdpi/weather_overcast.png
new file mode 100644 (file)
index 0000000..79303a5
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_overcast.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_severe_alert.png b/app/src/main/res/drawable-mdpi/weather_severe_alert.png
new file mode 100644 (file)
index 0000000..308931b
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_severe_alert.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_showers.png b/app/src/main/res/drawable-mdpi/weather_showers.png
new file mode 100644 (file)
index 0000000..6dce4e1
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_showers.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_showers_scattered.png b/app/src/main/res/drawable-mdpi/weather_showers_scattered.png
new file mode 100644 (file)
index 0000000..0e0b43e
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_showers_scattered.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_snow.png b/app/src/main/res/drawable-mdpi/weather_snow.png
new file mode 100644 (file)
index 0000000..9364b58
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_snow.png differ
diff --git a/app/src/main/res/drawable-mdpi/weather_storm.png b/app/src/main/res/drawable-mdpi/weather_storm.png
new file mode 100644 (file)
index 0000000..5e37b51
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/weather_storm.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_import_export.png b/app/src/main/res/drawable-xhdpi/ic_action_import_export.png
new file mode 100644 (file)
index 0000000..b247eda
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_import_export.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_map.png b/app/src/main/res/drawable-xhdpi/ic_action_map.png
new file mode 100644 (file)
index 0000000..537c5a4
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_map.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_place.png b/app/src/main/res/drawable-xhdpi/ic_action_place.png
new file mode 100644 (file)
index 0000000..5e93aeb
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_place.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_refresh.png b/app/src/main/res/drawable-xhdpi/ic_action_refresh.png
new file mode 100644 (file)
index 0000000..ab4ab9d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_refresh.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_search.png b/app/src/main/res/drawable-xhdpi/ic_action_search.png
new file mode 100644 (file)
index 0000000..19658e4
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_search.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_action_settings.png b/app/src/main/res/drawable-xhdpi/ic_action_settings.png
new file mode 100644 (file)
index 0000000..425a8bc
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_settings.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..d4fb7cd
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-xhdpi/thermometer.png b/app/src/main/res/drawable-xhdpi/thermometer.png
new file mode 100644 (file)
index 0000000..bd86520
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/thermometer.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_clear.png b/app/src/main/res/drawable-xhdpi/weather_clear.png
new file mode 100644 (file)
index 0000000..42bad9c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_clear.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_clear_night.png b/app/src/main/res/drawable-xhdpi/weather_clear_night.png
new file mode 100644 (file)
index 0000000..a9ab2dc
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_clear_night.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_few_clouds.png b/app/src/main/res/drawable-xhdpi/weather_few_clouds.png
new file mode 100644 (file)
index 0000000..954a7fd
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_few_clouds.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_few_clouds_night.png b/app/src/main/res/drawable-xhdpi/weather_few_clouds_night.png
new file mode 100644 (file)
index 0000000..be93567
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_few_clouds_night.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_fog.png b/app/src/main/res/drawable-xhdpi/weather_fog.png
new file mode 100644 (file)
index 0000000..bcca0a8
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_fog.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_overcast.png b/app/src/main/res/drawable-xhdpi/weather_overcast.png
new file mode 100644 (file)
index 0000000..5096963
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_overcast.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_severe_alert.png b/app/src/main/res/drawable-xhdpi/weather_severe_alert.png
new file mode 100644 (file)
index 0000000..c074f4e
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_severe_alert.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_showers.png b/app/src/main/res/drawable-xhdpi/weather_showers.png
new file mode 100644 (file)
index 0000000..28264f2
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_showers.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_showers_scattered.png b/app/src/main/res/drawable-xhdpi/weather_showers_scattered.png
new file mode 100644 (file)
index 0000000..f76f4e9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_showers_scattered.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_snow.png b/app/src/main/res/drawable-xhdpi/weather_snow.png
new file mode 100644 (file)
index 0000000..5226484
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_snow.png differ
diff --git a/app/src/main/res/drawable-xhdpi/weather_storm.png b/app/src/main/res/drawable-xhdpi/weather_storm.png
new file mode 100644 (file)
index 0000000..7539dee
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/weather_storm.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_import_export.png b/app/src/main/res/drawable-xxhdpi/ic_action_import_export.png
new file mode 100644 (file)
index 0000000..2dccb24
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_import_export.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_map.png b/app/src/main/res/drawable-xxhdpi/ic_action_map.png
new file mode 100644 (file)
index 0000000..ed72ce9
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_map.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_place.png b/app/src/main/res/drawable-xxhdpi/ic_action_place.png
new file mode 100644 (file)
index 0000000..25623c7
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_place.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_refresh.png b/app/src/main/res/drawable-xxhdpi/ic_action_refresh.png
new file mode 100644 (file)
index 0000000..44ee117
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_refresh.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_search.png b/app/src/main/res/drawable-xxhdpi/ic_action_search.png
new file mode 100644 (file)
index 0000000..a108638
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_search.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_settings.png b/app/src/main/res/drawable-xxhdpi/ic_action_settings.png
new file mode 100644 (file)
index 0000000..fe5fec4
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_settings.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..85a6081
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/thermometer.png b/app/src/main/res/drawable-xxhdpi/thermometer.png
new file mode 100644 (file)
index 0000000..37b3747
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/thermometer.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_clear.png b/app/src/main/res/drawable-xxhdpi/weather_clear.png
new file mode 100644 (file)
index 0000000..73a5bbd
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_clear.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_clear_night.png b/app/src/main/res/drawable-xxhdpi/weather_clear_night.png
new file mode 100644 (file)
index 0000000..2c60054
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_clear_night.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_few_clouds.png b/app/src/main/res/drawable-xxhdpi/weather_few_clouds.png
new file mode 100644 (file)
index 0000000..2d38702
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_few_clouds.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_few_clouds_night.png b/app/src/main/res/drawable-xxhdpi/weather_few_clouds_night.png
new file mode 100644 (file)
index 0000000..333afa7
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_few_clouds_night.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_fog.png b/app/src/main/res/drawable-xxhdpi/weather_fog.png
new file mode 100644 (file)
index 0000000..1bebc54
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_fog.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_overcast.png b/app/src/main/res/drawable-xxhdpi/weather_overcast.png
new file mode 100644 (file)
index 0000000..e3101eb
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_overcast.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_severe_alert.png b/app/src/main/res/drawable-xxhdpi/weather_severe_alert.png
new file mode 100644 (file)
index 0000000..b0ac4b7
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_severe_alert.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_showers.png b/app/src/main/res/drawable-xxhdpi/weather_showers.png
new file mode 100644 (file)
index 0000000..6a1860c
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_showers.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_showers_scattered.png b/app/src/main/res/drawable-xxhdpi/weather_showers_scattered.png
new file mode 100644 (file)
index 0000000..97d0f77
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_showers_scattered.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_snow.png b/app/src/main/res/drawable-xxhdpi/weather_snow.png
new file mode 100644 (file)
index 0000000..ac714cc
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_snow.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/weather_storm.png b/app/src/main/res/drawable-xxhdpi/weather_storm.png
new file mode 100644 (file)
index 0000000..c339221
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/weather_storm.png differ
diff --git a/app/src/main/res/layout-large/weather_main.xml b/app/src/main/res/layout-large/weather_main.xml
new file mode 100644 (file)
index 0000000..95e773e
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="de.example.exampletdd.WeatherInformationActivity"
+    tools:ignore="MergeRootFrame" >
+
+    <fragment
+        android:id="@+id/weather_overview_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        class="de.example.exampletdd.fragment.overview.OverviewFragment" />
+    
+    <fragment
+        android:id="@+id/weather_specific_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        class="de.example.exampletdd.fragment.specific.SpecificFragment" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/appwidget.xml b/app/src/main/res/layout/appwidget.xml
new file mode 100644 (file)
index 0000000..08f33cc
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/weather_appwidget"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="fill"
+    android:orientation="horizontal"
+    android:baselineAligned="false"
+    android:background="@color/widget_background_holo_dark"
+    android:padding="@dimen/widget_margin" >
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:padding="4dp"
+        android:orientation="vertical" >
+    
+       <ImageView
+               android:id="@+id/weather_appwidget_image"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="start"
+               android:contentDescription="@string/icon_weather_description"
+               android:orientation="vertical"
+               android:src="@drawable/weather_showers" />
+    
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:padding="4dp"
+        android:orientation="vertical" >
+        
+        <TextView
+            android:id="@+id/weather_appwidget_temperature_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="12ºC"
+            android:textAlignment="center"
+            android:textAllCaps="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textStyle="bold" />
+    
+       <TextView
+               android:id="@+id/weather_appwidget_temperature_min"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="center"
+               android:text="5ºC"
+               android:textAlignment="center"
+               android:textAllCaps="true"
+               android:textAppearance="?android:attr/textAppearanceMedium"
+               android:textStyle="normal" />
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:orientation="vertical"
+        android:padding="4dp" >
+        
+        <TextView
+            android:id="@+id/weather_appwidget_city"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="Morata de Tajuña"
+            android:textAlignment="center"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textStyle="bold" />
+    
+        <TextView
+            android:id="@+id/weather_appwidget_country"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="Spain"
+            android:textAlignment="center"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textStyle="normal" />
+    </LinearLayout>
+            
+
+    
+
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/appwidget_configure.xml b/app/src/main/res/layout/appwidget_configure.xml
new file mode 100644 (file)
index 0000000..f5df9a0
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="fill_vertical|fill_horizontal" >
+
+    <LinearLayout android:id="@+id/weather_appwidget_configure_preferences"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_gravity="center"
+        android:orientation="horizontal" >
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/weather_appwidget_configure_preferences"
+        android:layout_centerHorizontal="true"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:baselineAligned="false"
+        android:orientation="horizontal" >
+
+        <Button
+            android:id="@+id/weather_appwidget_configure_refresh_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:textAlignment="center"
+            android:text="@string/widget_preferences_button_refresh" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:baselineAligned="false"
+        android:orientation="horizontal" >
+        
+        <Button
+            android:id="@+id/weather_appwidget_configure_save_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:textAlignment="center"
+            android:text="@android:string/ok" />
+    </LinearLayout>
+
+</RelativeLayout>
+
diff --git a/app/src/main/res/layout/appwidget_error.xml b/app/src/main/res/layout/appwidget_error.xml
new file mode 100644 (file)
index 0000000..4b6c90f
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/weather_appwidget_error"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="fill"
+    android:orientation="horizontal"
+    android:baselineAligned="false"
+    android:background="@color/widget_background_holo_dark"
+    android:padding="@dimen/widget_margin" >
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:padding="4dp"
+        android:orientation="vertical" >
+    
+       <ImageView
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="start"
+               android:contentDescription="@string/icon_weather_description"
+               android:orientation="vertical"
+               android:src="@drawable/ic_launcher" />
+    
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:orientation="vertical"
+        android:padding="4dp" >
+        
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="@string/text_field_remote_error"
+            android:textAlignment="center"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textStyle="bold" />
+    </LinearLayout>
+            
+
+    
+
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/fragment_pager.xml b/app/src/main/res/layout/fragment_pager.xml
new file mode 100644 (file)
index 0000000..07cf7a6
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical" android:padding="4dip"
+        android:gravity="center_horizontal"
+        android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <android.support.v4.view.ViewPager
+            android:id="@+id/pager"
+            android:layout_width="match_parent"
+            android:layout_height="0px"
+            android:layout_weight="1">
+    </android.support.v4.view.ViewPager>
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/notification.xml b/app/src/main/res/layout/notification.xml
new file mode 100644 (file)
index 0000000..fd6bf80
--- /dev/null
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="fill"
+    android:baselineAligned="false"
+    android:orientation="horizontal" >
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:orientation="vertical" >
+    
+       <ImageView
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="start"
+               android:contentDescription="@string/icon_weather_description"
+               android:orientation="vertical"
+               android:src="@drawable/ic_launcher" />
+    </LinearLayout>
+    
+
+       
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:layout_weight="2"
+        android:gravity="center"
+        android:orientation="vertical" >
+        
+        <TextView
+            android:id="@+id/weather_notification_city"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="Morata de Tajuña"
+            android:textAlignment="center"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textStyle="bold" />
+    
+        <TextView
+            android:id="@+id/weather_notification_country"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="Spain"
+            android:textAlignment="center"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textStyle="normal" />
+    </LinearLayout>
+            
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:orientation="vertical" >
+        
+        <TextView
+            android:id="@+id/weather_notification_temperature_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="12ºC"
+            android:textAlignment="center"
+            android:textAllCaps="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textStyle="bold" />
+    
+       <TextView
+               android:id="@+id/weather_notification_temperature_min"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="center"
+               android:text="5ºC"
+               android:textAlignment="center"
+               android:textAllCaps="true"
+               android:textAppearance="?android:attr/textAppearanceMedium"
+               android:textStyle="normal" />
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:orientation="vertical" >
+    
+       <ImageView
+               android:id="@+id/weather_notification_image"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="end"
+               android:contentDescription="@string/icon_weather_description"
+               android:orientation="vertical"
+               android:src="@drawable/ic_launcher" />
+    
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/weather_current_fragment.xml b/app/src/main/res/layout/weather_current_fragment.xml
new file mode 100644 (file)
index 0000000..e6618b6
--- /dev/null
@@ -0,0 +1,562 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/weather_current_fragment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center">
+        
+    <!-- TODO: align start/end feels like-snow humidity-rain wind-clouds -->
+    <LinearLayout android:id="@+id/weather_current_data_container"
+        android:layout_width="match_parent"
+       android:layout_height="wrap_content"
+       android:gravity="center"
+       android:layout_gravity="fill_vertical|center_horizontal"
+       android:orientation="vertical" >
+       
+        <!-- TODO: http://developer.android.com/guide/topics/manifest/supports-screens-element.html -->
+       <!-- TODO: supporting multiple layouts/languages http://developer.android.com/guide/practices/screens_support.html -->
+       <!-- TODO: Should I use RelativeLayout for long texts (I18N) and RTL/LTR UI?
+                With long texts, many times, text will not fit... The same for WP8 :/ -->
+       <LinearLayout
+               android:layout_width="match_parent"
+               android:layout_height="match_parent"
+               android:gravity="center"
+               android:layout_gravity="top|center"
+               android:padding="50dp"
+               android:orientation="horizontal" >
+
+               <ImageView
+                               android:id="@+id/weather_current_picture"
+                       android:layout_width="0dp"
+                       android:layout_weight="1"
+                       android:layout_height="wrap_content"
+                       android:contentDescription="@string/icon_weather_description"
+                       android:scaleType="fitCenter"
+                       android:gravity="center"
+                       android:layout_gravity="center"
+                       android:src="@drawable/weather_showers" />
+
+               <LinearLayout
+                       android:layout_width="0dp"
+                       android:layout_weight="1"
+                       android:layout_height="wrap_content"
+                       android:gravity="center"
+                       android:layout_gravity="center"
+                       android:orientation="vertical" >
+
+                       <TextView
+                           android:id="@+id/weather_current_temp_max"
+                           android:layout_width="wrap_content"
+                           android:layout_height="wrap_content"
+                           android:paddingEnd="10dp"
+                           android:paddingStart="20dp"
+                           android:singleLine="true"
+                           android:text="55ºC"
+                           android:textAlignment="textStart"
+                           android:textAppearance="?android:attr/textAppearanceLarge"
+                           android:textStyle="bold" />
+
+                       <TextView
+                       android:id="@+id/weather_current_temp_min"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:textAlignment="textStart"
+                       android:paddingEnd="10dp"
+                       android:paddingStart="20dp"
+                       android:singleLine="true"
+                       android:text="25ºC"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="normal" />
+               </LinearLayout>
+               </LinearLayout>
+       
+       <LinearLayout
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:gravity="center"
+               android:padding="25dp"
+               android:layout_gravity="top|center"
+               android:orientation="horizontal" >
+
+               <TextView
+                       android:id="@+id/weather_current_description"
+                       android:layout_width="match_parent"
+                       android:layout_height="wrap_content"
+                       android:gravity="center"
+                       android:text="Light rain"
+                       android:textAppearance="?android:attr/textAppearanceLarge"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:textStyle="bold" />    
+               </LinearLayout>
+
+       <LinearLayout
+           android:baselineAligned="false"
+               android:layout_width="match_parent"
+                       android:layout_height="wrap_content"
+               android:layout_gravity="top|fill_horizontal"
+               android:orientation="horizontal" >
+                               
+           <LinearLayout
+                       android:layout_width="0dp"
+                       android:layout_weight="1"
+                               android:layout_height="wrap_content"
+                       android:gravity="center"
+                       android:layout_gravity="center"
+                       android:orientation="horizontal" >
+                               <!-- Feels like -->
+                               <TextView
+                               android:id="@+id/weather_current_feelslike"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:layout_gravity="start"
+                               android:layout_margin="5dp"
+                               android:gravity="start"
+                               android:text="@string/text_field_feels_like"
+                               android:textAlignment="textStart"
+                               android:textAppearance="?android:attr/textAppearanceMedium"
+                               android:textColor="@color/weather_time_of_day_color_title"
+                               android:textStyle="bold" />
+        
+                               <!-- Feels like Value-->
+                               <TextView
+                               android:id="@+id/weather_current_feelslike_value"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="83"
+                               android:layout_gravity="start"
+                               android:gravity="start"
+                               android:textAlignment="textStart"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="normal" />
+        
+                               <!-- Feels like Units-->
+                               <TextView
+                               android:id="@+id/weather_current_feelslike_units"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="ºC"
+                               android:layout_gravity="start"
+                               android:gravity="start"
+                               android:textAlignment="textStart"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:layout_marginEnd="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="bold" />
+                       </LinearLayout>
+
+               <LinearLayout
+                       android:layout_width="0dp"
+                       android:layout_height="wrap_content"
+                       android:gravity="center"
+                               android:layout_gravity="center"
+                       android:layout_weight="1"
+                       android:orientation="horizontal" >
+                       <!-- Snow -->
+                               <TextView
+                               android:id="@+id/weather_current_snow"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                                       android:text="@string/text_field_snow"
+                                       android:gravity="end"
+                               android:layout_gravity="end"
+                               android:textAlignment="textEnd"
+                               android:textColor="@color/weather_time_of_day_color_title"
+                                       android:layout_margin="5dp"
+                               android:textAppearance="?android:attr/textAppearanceMedium"
+                               android:textStyle="bold" />
+          
+                               <!-- Snow Value-->
+                               <TextView
+                               android:id="@+id/weather_current_snow_value"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="1.22"
+                               android:layout_gravity="end"
+                               android:gravity="end"
+                               android:textAlignment="textEnd"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="normal" />
+        
+                               <!-- Snow Units -->
+                               <TextView
+                               android:id="@+id/weather_current_snow_units"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text=" mm 3h"
+                               android:layout_gravity="end"
+                               android:gravity="end"
+                               android:textAlignment="textEnd"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                                       android:layout_marginEnd="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="bold" />
+                       </LinearLayout>
+        </LinearLayout>
+        
+        <LinearLayout
+            android:baselineAligned="false"
+               android:layout_width="match_parent"
+                       android:layout_height="wrap_content"
+               android:layout_gravity="top|fill_horizontal"
+               android:orientation="horizontal" >
+               
+               <LinearLayout
+                               android:layout_width="0dp"
+                               android:layout_weight="1"
+                                       android:layout_height="wrap_content"
+                               android:gravity="center"
+                               android:layout_gravity="center"
+                               android:orientation="horizontal" >
+                               <!-- Humidity -->
+                               <TextView
+                               android:id="@+id/weather_current_humidity"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:layout_gravity="start"
+                               android:layout_margin="5dp"
+                               android:gravity="start"
+                               android:text="@string/text_field_humidity"
+                               android:textAlignment="textStart"
+                               android:textAppearance="?android:attr/textAppearanceMedium"
+                               android:textColor="@color/weather_time_of_day_color_title"
+                               android:textStyle="bold" />
+        
+                               <!-- Humidity Value-->
+                               <TextView
+                               android:id="@+id/weather_current_humidity_value"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="83"
+                               android:layout_gravity="start"
+                               android:gravity="start"
+                               android:textAlignment="textStart"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="normal" />
+        
+                               <!-- Humidity Units-->
+                               <TextView
+                               android:id="@+id/weather_current_humidity_units"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="%"
+                               android:layout_gravity="start"
+                               android:gravity="start"
+                               android:textAlignment="textStart"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:layout_marginEnd="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="bold" />
+                       </LinearLayout>
+
+               <LinearLayout
+                       android:layout_width="0dp"
+                       android:layout_height="wrap_content"
+                       android:gravity="center"
+                               android:layout_gravity="center"
+                       android:layout_weight="1"
+                       android:orientation="horizontal" >
+                       <!-- Rain -->
+                               <TextView
+                               android:id="@+id/weather_current_rain"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                                       android:text="@string/text_field_rain"
+                               android:layout_gravity="end"
+                               android:gravity="end"
+                               android:textAlignment="textEnd"
+                               android:textColor="@color/weather_time_of_day_color_title"
+                                       android:layout_margin="5dp"
+                               android:textAppearance="?android:attr/textAppearanceMedium"
+                               android:textStyle="bold" />
+          
+                               <!-- Rain Value-->
+                               <TextView
+                               android:id="@+id/weather_current_rain_value"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="1.24"
+                               android:layout_gravity="end"
+                               android:gravity="end"
+                               android:textAlignment="textEnd"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="normal" />
+        
+                               <!-- Rain Units -->
+                               <TextView
+                               android:id="@+id/weather_current_rain_units"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text=" mm 3h"
+                               android:layout_gravity="end"
+                               android:gravity="end"
+                               android:textAlignment="textEnd"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                                       android:layout_marginEnd="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="bold" />
+                       </LinearLayout>
+        </LinearLayout>   
+            
+        <LinearLayout
+            android:baselineAligned="false"
+               android:layout_width="match_parent"
+                       android:layout_height="wrap_content"
+               android:layout_gravity="top|fill_horizontal"
+               android:orientation="horizontal" >
+                       
+                <LinearLayout
+                               android:layout_width="0dp"
+                               android:layout_weight="1"
+                                       android:layout_height="wrap_content"
+                               android:gravity="center"
+                               android:layout_gravity="center"
+                               android:orientation="horizontal" >
+                               <!-- Wind -->
+                               <TextView
+                               android:id="@+id/weather_current_wind"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="@string/text_field_wind"
+                               android:layout_gravity="start"
+                               android:gravity="start"
+                               android:textAlignment="textStart"
+                               android:textColor="@color/weather_time_of_day_color_title"
+                               android:layout_margin="5dp"
+                               android:textAppearance="?android:attr/textAppearanceMedium"
+                               android:textStyle="bold" />
+        
+                               <!-- Wind Value-->
+                               <TextView
+                               android:id="@+id/weather_current_wind_value"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                                       android:text="6.36"
+                               android:layout_gravity="start"
+                               android:gravity="start"
+                               android:textAlignment="textStart"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="normal" />
+        
+                               <!-- Wind Units -->
+                               <TextView
+                               android:id="@+id/weather_current_wind_units"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text=" m/s"
+                               android:layout_gravity="start"
+                               android:gravity="start"
+                               android:textAlignment="textStart"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:layout_marginEnd="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="bold" />
+                       </LinearLayout>
+                       
+                <LinearLayout
+                       android:layout_width="0dp"
+                       android:layout_height="wrap_content"
+                       android:gravity="center"
+                               android:layout_gravity="center"
+                       android:layout_weight="1"
+                       android:orientation="horizontal" >
+                       <!-- Clouds -->
+                               <TextView
+                               android:id="@+id/weather_current_clouds"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="@string/text_field_clouds"
+                               android:layout_gravity="end"
+                               android:gravity="end"
+                               android:textAlignment="textEnd"
+                               android:textColor="@color/weather_time_of_day_color_title"
+                               android:layout_margin="5dp"
+                               android:textAppearance="?android:attr/textAppearanceMedium"
+                               android:textStyle="bold" />
+        
+                               <!-- Clouds Value-->
+                               <TextView
+                               android:id="@+id/weather_current_clouds_value"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="6.36"
+                               android:layout_gravity="end"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:gravity="end"
+                               android:textAlignment="textEnd"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="normal" />
+        
+                               <!-- Clouds Units -->
+                               <TextView
+                               android:id="@+id/weather_current_clouds_units"
+                               android:layout_width="wrap_content"
+                               android:layout_height="wrap_content"
+                               android:text="%"
+                               android:layout_gravity="end"
+                               android:gravity="end"
+                               android:textAlignment="textEnd"
+                               android:layout_marginTop="5dp"
+                               android:layout_marginBottom="5dp"
+                               android:layout_marginEnd="5dp"
+                               android:textAppearance="?android:attr/textAppearanceSmall"
+                               android:textStyle="bold" />
+                       </LinearLayout>
+               </LinearLayout>
+        <LinearLayout
+                       android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="top|center"
+               android:orientation="horizontal" >
+        
+                       <!-- Pressure -->
+                       <TextView
+                       android:id="@+id/weather_current_pressure"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="@string/text_field_pressure"
+                       android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:layout_margin="5dp"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="bold" />
+        
+                       <!-- Pressure Value-->
+                       <TextView
+                       android:id="@+id/weather_current_pressure_value"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="1036.05"
+                       android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="normal" />
+        
+                       <!-- Pressure Units-->
+                       <TextView
+                       android:id="@+id/weather_current_pressure_units"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text=" hpa"
+                               android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:layout_marginEnd="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="bold" />
+        </LinearLayout>
+        <LinearLayout
+                       android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="top|center"
+               android:orientation="horizontal" >
+        
+                       <!-- Sun rise -->
+                       <TextView
+                       android:id="@+id/weather_current_sunrise"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="@string/text_field_sun_rise"
+                       android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:layout_margin="5dp"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="bold" />
+        
+                       <!-- Sun rise Value-->
+                       <TextView
+                       android:id="@+id/weather_current_sunrise_value"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="2014.04.20 10:29:33"
+                       android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="normal" />
+        </LinearLayout>
+        <LinearLayout
+                       android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="top|center"
+               android:orientation="horizontal" >
+        
+                       <!-- Sun rise -->
+                       <TextView
+                       android:id="@+id/weather_current_sunset"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="@string/text_field_sun_set"
+                       android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:layout_margin="5dp"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="bold" />
+        
+                       <!-- Sun rise Value-->
+                       <TextView
+                       android:id="@+id/weather_current_sunset_value"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="2014.04.20 10:29:33"
+                       android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="normal" />
+        </LinearLayout>
+       </LinearLayout>
+       
+    <ProgressBar
+        android:id="@+id/weather_current_progressbar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:visibility="gone"
+        style="?android:attr/progressBarStyleLarge" />
+
+    <TextView
+        android:id="@+id/weather_current_error_message"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="@string/text_field_remote_error"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:visibility="gone" />
+
+       </FrameLayout>
+</ScrollView>
diff --git a/app/src/main/res/layout/weather_main_entry_list.xml b/app/src/main/res/layout/weather_main_entry_list.xml
new file mode 100644 (file)
index 0000000..017f8d0
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:baselineAligned="false"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="center_horizontal"
+    android:orientation="horizontal"
+    android:padding="5dp" >
+
+    <LinearLayout
+    android:layout_width="0dp"
+    android:layout_weight="1"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:layout_gravity="center"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/weather_main_entry_date_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="SUN"
+        android:textAlignment="center"
+        android:textAllCaps="true"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textStyle="bold" />
+
+    <TextView
+        android:id="@+id/weather_main_entry_date_number"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="APR 23"
+        android:textAlignment="center"
+        android:textAllCaps="true"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textStyle="normal" />
+    
+    </LinearLayout>
+    
+
+    <LinearLayout
+    android:layout_width="0dp"
+    android:layout_weight="1"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:layout_gravity="center"
+    android:orientation="vertical" >
+    
+        <TextView
+            android:id="@+id/weather_main_entry_temperature_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="12ºC"
+            android:textAlignment="center"
+            android:textAllCaps="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="@color/weather_time_of_day_color_title"
+            android:textStyle="bold" />
+    
+    <TextView
+        android:id="@+id/weather_main_entry_temperature_min"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="5ºC"
+        android:textAlignment="center"
+        android:textAllCaps="true"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="@color/weather_time_of_day_color_title"
+        android:textStyle="normal" />
+    
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:orientation="vertical" >
+    
+    <ImageView
+        android:id="@+id/weather_main_entry_image"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:contentDescription="@string/icon_weather_description"
+        android:orientation="vertical"
+        android:src="@drawable/ic_launcher" />
+    
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/weather_map.xml b/app/src/main/res/layout/weather_map.xml
new file mode 100644 (file)
index 0000000..2e442c1
--- /dev/null
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>    
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/weather_map"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="center"
+    tools:context="de.example.exampletdd.MapActivity" >
+
+    <LinearLayout
+        android:id="@+id/weather_map_citycountry_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentStart="true" >
+       <LinearLayout
+               android:id="@+id/weather_map_city_container"
+               android:layout_width="0dp"
+               android:layout_weight="1"
+               android:layout_gravity="center"
+               android:gravity="center"
+               android:layout_height="wrap_content">     
+               <TextView
+                       android:id="@+id/weather_map_city"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="City"
+                       android:layout_gravity="center"
+                       android:textAlignment="center"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textIsSelectable="false"
+                       android:textStyle="bold|normal" />  
+       </LinearLayout>
+       
+       <ProgressBar
+           android:id="@+id/weather_map_progress"
+           android:layout_width="0dp"
+           android:layout_height="wrap_content"
+           android:layout_gravity="center"
+           android:layout_weight="1"
+           android:indeterminateBehavior="repeat"
+           android:indeterminateDuration="3500"
+           android:indeterminateOnly="true"
+           android:visibility="gone" />
+    
+       <LinearLayout
+               android:id="@+id/weather_map_country_container"
+               android:layout_width="0dp"
+               android:layout_weight="1"
+               android:layout_gravity="center"
+               android:gravity="center"
+               android:layout_height="wrap_content" >
+               <TextView
+                       android:id="@+id/weather_map_country"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="Country"
+                       android:layout_gravity="center"
+                       android:textAlignment="center"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textIsSelectable="false"
+                       android:textStyle="bold|normal" />
+               </LinearLayout>
+       </LinearLayout>
+
+    <fragment
+        android:id="@+id/weather_map_fragment_map"
+        android:name="com.google.android.gms.maps.MapFragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_below="@+id/weather_map_citycountry_container"
+        android:layout_above="@+id/weather_map_buttons_container" />
+
+    <LinearLayout
+        android:id="@+id/weather_map_buttons_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentStart="true"
+        android:orientation="horizontal"
+        android:baselineAligned="false" >
+    </LinearLayout>
+
+</RelativeLayout>
diff --git a/app/src/main/res/layout/weather_map_buttons.xml b/app/src/main/res/layout/weather_map_buttons.xml
new file mode 100644 (file)
index 0000000..4f81887
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:baselineAligned="false" >
+    
+       <LinearLayout
+               android:id="@+id/weather_map_button_savelocation_container"
+               android:layout_width="0dp"
+               android:layout_weight="1"
+               android:layout_gravity="center"
+               android:gravity="center"
+               android:layout_height="wrap_content">     
+               <Button
+                       android:id="@+id/weather_map_button_savelocation"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:layout_gravity="center"
+                       android:onClick="onClickSaveLocation"
+                       android:textAlignment="center"
+                       android:text="@string/weather_map_button_savelocation" />
+       </LinearLayout>
+       
+       <LinearLayout
+               android:id="@+id/weather_map_button_getlocation_container"
+               android:layout_width="0dp"
+               android:layout_weight="1"
+               android:layout_gravity="center"
+               android:gravity="center"
+               android:layout_height="wrap_content" >
+               <Button
+                       android:id="@+id/weather_map_button_getlocation"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:layout_gravity="center"
+                       android:onClick="onClickGetLocation"
+                       android:textAlignment="center"
+                       android:enabled="false"
+                       android:text="@string/weather_map_button_getlocation" />
+               </LinearLayout> 
+</LinearLayout>
diff --git a/app/src/main/res/layout/weather_map_progress.xml b/app/src/main/res/layout/weather_map_progress.xml
new file mode 100644 (file)
index 0000000..b8eb00e
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal" >
+    
+       <ProgressBar
+           android:id="@+id/weather_map_progressbar"
+           android:layout_width="0dp"
+           android:layout_height="wrap_content"
+           android:layout_gravity="center"
+           android:layout_weight="1"
+           android:indeterminateBehavior="repeat"
+           android:indeterminateDuration="3500"
+           android:indeterminateOnly="true"
+           android:visibility="visible" />
+    
+</LinearLayout>
diff --git a/app/src/main/res/layout/weather_specific.xml b/app/src/main/res/layout/weather_specific.xml
new file mode 100644 (file)
index 0000000..6147006
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/weather_specific"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:orientation="vertical"
+    tools:context="de.example.exampletdd.SpecificActivity"
+    tools:ignore="MergeRootFrame" >
+
+
+     <fragment
+        android:id="@+id/specific_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        class="de.example.exampletdd.fragment.specific.SpecificFragment" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/weather_specific_fragment.xml b/app/src/main/res/layout/weather_specific_fragment.xml
new file mode 100644 (file)
index 0000000..fd80c01
--- /dev/null
@@ -0,0 +1,496 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/weather_specific_fragment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <!-- TODO: align start/end humidity-rain wind-clouds -->
+    <LinearLayout
+        android:layout_width="match_parent"
+       android:layout_height="wrap_content"
+       android:gravity="center"
+       android:layout_gravity="fill_vertical|center_horizontal"
+       android:orientation="vertical" >
+       
+        <!-- TODO: http://developer.android.com/guide/topics/manifest/supports-screens-element.html -->
+       <!-- TODO: supporting multiple layouts/languages http://developer.android.com/guide/practices/screens_support.html -->
+       <!-- TODO: Should I use RelativeLayout for long texts (I18N) and RTL/LTR UI?
+                With long texts, many times, text will not fit... The same for WP8 :/ -->
+       <LinearLayout
+               android:layout_width="match_parent"
+               android:layout_height="match_parent"
+               android:gravity="center"
+               android:layout_gravity="top|center"
+               android:padding="50dp"
+               android:orientation="horizontal" >
+
+               <ImageView
+                               android:id="@+id/weather_specific_picture"
+                       android:layout_width="0dp"
+                       android:layout_weight="1"
+                       android:layout_height="wrap_content"
+                       android:contentDescription="@string/icon_weather_description"
+                       android:scaleType="fitCenter"
+                       android:gravity="center"
+                       android:layout_gravity="center"
+                       android:src="@drawable/weather_showers" />
+
+               <LinearLayout
+                       android:layout_width="0dp"
+                       android:layout_weight="1"
+                       android:layout_height="wrap_content"
+                       android:gravity="center"
+                       android:layout_gravity="center"
+                       android:orientation="vertical" >
+
+                       <TextView
+                           android:id="@+id/weather_specific_temp_max"
+                           android:layout_width="wrap_content"
+                           android:layout_height="wrap_content"
+                           android:paddingEnd="10dp"
+                           android:paddingStart="20dp"
+                           android:singleLine="true"
+                           android:text="55ºC"
+                           android:textAlignment="textStart"
+                           android:textAppearance="?android:attr/textAppearanceLarge"
+                           android:textStyle="bold" />
+
+                       <TextView
+                       android:id="@+id/weather_specific_temp_min"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:textAlignment="textStart"
+                       android:paddingEnd="10dp"
+                       android:paddingStart="20dp"
+                       android:singleLine="true"
+                       android:text="25ºC"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="normal" />
+               </LinearLayout>
+               </LinearLayout>
+       
+       <LinearLayout
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:gravity="center"
+               android:padding="25dp"
+               android:layout_gravity="top|center"
+               android:orientation="horizontal" >
+
+               <TextView
+                       android:id="@+id/weather_specific_description"
+                       android:layout_width="match_parent"
+                       android:layout_height="wrap_content"
+                       android:gravity="center"
+                       android:text="Light rain"
+                       android:textAppearance="?android:attr/textAppearanceLarge"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:textStyle="bold" />    
+               </LinearLayout>
+
+        <LinearLayout
+            android:baselineAligned="false"
+               android:layout_width="match_parent"
+                       android:layout_height="wrap_content"
+               android:layout_gravity="top|center"
+               android:orientation="horizontal" >
+                               
+            <LinearLayout
+                       android:layout_width="0dp"
+                       android:layout_weight="1"
+                               android:layout_height="wrap_content"
+                       android:gravity="center"
+                       android:layout_gravity="center"
+                       android:orientation="horizontal" >
+                       <!-- Humidity -->
+                       <TextView
+                       android:id="@+id/weather_specific_humidity"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:layout_gravity="start"
+                       android:layout_margin="5dp"
+                       android:gravity="start"
+                       android:text="@string/text_field_humidity"
+                       android:textAlignment="textStart"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:textStyle="bold" />
+        
+                       <!-- Humidity Value-->
+                       <TextView
+                       android:id="@+id/weather_specific_humidity_value"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="83"
+                       android:layout_gravity="start"
+                       android:gravity="start"
+                       android:textAlignment="textStart"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="normal" />
+        
+                       <!-- Humidity Units-->
+                       <TextView
+                       android:id="@+id/weather_specific_humidity_units"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="%"
+                       android:layout_gravity="start"
+                       android:gravity="start"
+                       android:textAlignment="textStart"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:layout_marginEnd="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="bold" />
+                       </LinearLayout>
+
+           <LinearLayout
+               android:layout_width="0dp"
+               android:layout_height="wrap_content"
+               android:gravity="center"
+                       android:layout_gravity="center"
+               android:layout_weight="1"
+               android:orientation="horizontal" >
+                <!-- Rain -->
+                       <TextView
+                       android:id="@+id/weather_specific_rain"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                               android:text="@string/text_field_rain"
+                       android:layout_gravity="end"
+                       android:gravity="end"
+                       android:textAlignment="textEnd"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                               android:layout_margin="5dp"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="bold" />
+          
+                       <!-- Rain Value-->
+                       <TextView
+                       android:id="@+id/weather_specific_rain_value"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="1.24"
+                       android:layout_gravity="end"
+                       android:gravity="end"
+                       android:textAlignment="textEnd"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="normal" />
+        
+                       <!-- Rain Units -->
+                       <TextView
+                       android:id="@+id/weather_specific_rain_units"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text=" mm 3h"
+                       android:layout_gravity="end"
+                       android:gravity="end"
+                       android:textAlignment="textEnd"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                               android:layout_marginEnd="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="bold" />
+               </LinearLayout>
+        </LinearLayout>
+    
+            
+        <LinearLayout
+            android:baselineAligned="false"
+               android:layout_width="match_parent"
+                       android:layout_height="wrap_content"
+               android:layout_gravity="top|center"
+               android:orientation="horizontal" >
+                               
+            <LinearLayout
+                       android:layout_width="0dp"
+                       android:layout_weight="1"
+                               android:layout_height="wrap_content"
+                       android:gravity="center"
+                       android:layout_gravity="center"
+                       android:orientation="horizontal" >
+                       
+                       <!-- Wind -->
+                       <TextView
+                       android:id="@+id/weather_specific_wind"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="@string/text_field_wind"
+                       android:layout_gravity="start"
+                       android:gravity="start"
+                       android:textAlignment="textStart"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:layout_margin="5dp"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="bold" />
+        
+                       <!-- Wind Value-->
+                       <TextView
+                       android:id="@+id/weather_specific_wind_value"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                               android:text="6.36"
+                       android:layout_gravity="start"
+                       android:gravity="start"
+                       android:textAlignment="textStart"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="normal" />
+        
+                       <!-- Wind Units -->
+                       <TextView
+                       android:id="@+id/weather_specific_wind_units"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text=" m/s"
+                       android:layout_gravity="start"
+                       android:gravity="start"
+                       android:textAlignment="textStart"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:layout_marginEnd="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="bold" />
+                       </LinearLayout>
+
+           <LinearLayout
+               android:layout_width="0dp"
+               android:layout_height="wrap_content"
+               android:gravity="center"
+                       android:layout_gravity="center"
+               android:layout_weight="1"
+               android:orientation="horizontal" >                      
+                <!-- Clouds -->
+                       <TextView
+                       android:id="@+id/weather_specific_clouds"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="@string/text_field_clouds"
+                       android:layout_gravity="end"
+                       android:gravity="end"
+                       android:textAlignment="textEnd"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:layout_margin="5dp"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="bold" />
+        
+                       <!-- Clouds Value-->
+                       <TextView
+                       android:id="@+id/weather_specific_clouds_value"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="6.36"
+                       android:layout_gravity="end"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:gravity="end"
+                       android:textAlignment="textEnd"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="normal" />
+        
+                       <!-- Clouds Units -->
+                       <TextView
+                       android:id="@+id/weather_specific_clouds_units"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="%"
+                       android:layout_gravity="end"
+                       android:gravity="end"
+                       android:textAlignment="textEnd"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:layout_marginEnd="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="bold" />
+                       </LinearLayout>
+               </LinearLayout>
+        <LinearLayout
+                       android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="top|center"
+               android:orientation="horizontal" >
+        
+                       <!-- Pressure -->
+                       <TextView
+                       android:id="@+id/weather_specific_pressure"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="@string/text_field_pressure"
+                       android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:textColor="@color/weather_time_of_day_color_title"
+                       android:layout_margin="5dp"
+                       android:textAppearance="?android:attr/textAppearanceMedium"
+                       android:textStyle="bold" />
+        
+                       <!-- Pressure Value-->
+                       <TextView
+                       android:id="@+id/weather_specific_pressure_value"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="1036.05"
+                       android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="normal" />
+        
+                       <!-- Pressure Units-->
+                       <TextView
+                       android:id="@+id/weather_specific_pressure_units"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text=" hpa"
+                               android:layout_gravity="center"
+                       android:gravity="center"
+                       android:textAlignment="center"
+                       android:layout_marginTop="5dp"
+                       android:layout_marginBottom="5dp"
+                       android:layout_marginEnd="5dp"
+                       android:textAppearance="?android:attr/textAppearanceSmall"
+                       android:textStyle="bold" />
+        </LinearLayout>
+        
+        <HorizontalScrollView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|start"
+            android:layout_margin="10dp"
+            android:fadingEdge="none"
+            android:scrollbars="horizontal|none" >
+                       
+               <LinearLayout
+                   android:layout_width="wrap_content"
+                   android:layout_height="wrap_content"
+                   android:layout_gravity="center"
+                   android:fadingEdge="none"
+                   android:orientation="horizontal"
+                   android:scrollbarAlwaysDrawVerticalTrack="false"
+                   android:scrollbars="none" >
+
+                               <LinearLayout
+                                       android:layout_width="wrap_content"
+                                       android:layout_height="wrap_content"
+                                       android:paddingStart="20dp"
+                                       android:paddingEnd="20dp"
+                                       android:orientation="vertical" >
+                       
+                                       <!-- Time of day -->
+                                       <TextView
+                                       android:id="@+id/weather_specific_morn"
+                                               android:layout_width="wrap_content"
+                                               android:layout_height="wrap_content"
+                                       android:text="MORNING"
+                                       android:textColor="@color/weather_time_of_day_color_title"
+                                       android:textAlignment="center"
+                                       android:layout_gravity="top|center"
+                                       android:textAppearance="?android:attr/textAppearanceMedium" />
+                               
+                                       <!-- Temperature -->
+                                       <TextView
+                                               android:id="@+id/weather_specific_morn_temperature"
+                                               android:layout_width="wrap_content"
+                                               android:layout_height="wrap_content"
+                                       android:text="55ºC"
+                                       android:textAlignment="center"
+                                       android:layout_gravity="bottom|center"
+                                       android:textAppearance="?android:attr/textAppearanceMedium"
+                                       android:textStyle="bold" />
+                               </LinearLayout>
+                               <LinearLayout
+                                       android:layout_width="wrap_content"
+                                       android:layout_height="wrap_content"
+                                       android:orientation="vertical" >
+                               
+                                       <!-- Time of day -->
+                                       <TextView
+                                       android:id="@+id/weather_specific_day"
+                                               android:layout_width="wrap_content"
+                                               android:layout_height="wrap_content"
+                                       android:text="DAY"
+                                       android:textColor="@color/weather_time_of_day_color_title"
+                                       android:textAlignment="center"
+                                       android:layout_gravity="top|center"
+                                       android:textAppearance="?android:attr/textAppearanceMedium" />
+                               
+                                       <!-- Temperature -->
+                                       <TextView
+                                               android:id="@+id/weather_specific_day_temperature"
+                                               android:layout_width="wrap_content"
+                                               android:layout_height="wrap_content"
+                                       android:text="55ºC"
+                                       android:textAlignment="center"
+                                       android:layout_gravity="bottom|center"
+                                       android:textAppearance="?android:attr/textAppearanceMedium"
+                                       android:textStyle="bold" />
+                               </LinearLayout>
+                               <LinearLayout
+                                       android:layout_width="wrap_content"
+                                       android:layout_height="wrap_content"
+                                       android:paddingStart="20dp"
+                                       android:paddingEnd="20dp"
+                                       android:orientation="vertical" >
+                       
+                                       <!-- Time of day -->
+                                       <TextView
+                                       android:id="@+id/weather_specific_eve"
+                                               android:layout_width="wrap_content"
+                                               android:layout_height="wrap_content"
+                                       android:text="EVENING"
+                                       android:textColor="@color/weather_time_of_day_color_title"
+                                       android:textAlignment="center"
+                                       android:layout_gravity="top|center"
+                                       android:textAppearance="?android:attr/textAppearanceMedium" />
+                               
+                                       <!-- Temperature -->
+                                       <TextView
+                                               android:id="@+id/weather_specific_eve_temperature"
+                                               android:layout_width="wrap_content"
+                                               android:layout_height="wrap_content"
+                                       android:text="55ºC"
+                                       android:textAlignment="center"
+                                       android:layout_gravity="bottom|center"
+                                       android:textAppearance="?android:attr/textAppearanceMedium"
+                                       android:textStyle="bold" />
+                               </LinearLayout>
+                               <LinearLayout
+                                       android:layout_width="wrap_content"
+                                       android:layout_height="wrap_content"
+                                       android:paddingStart="20dp"
+                                       android:paddingEnd="20dp"
+                                       android:orientation="vertical" >
+                       
+                                       <!-- Time of day -->
+                                       <TextView
+                                       android:id="@+id/weather_specific_night"
+                                               android:layout_width="wrap_content"
+                                               android:layout_height="wrap_content"
+                                       android:text="NIGHT"
+                                       android:textColor="@color/weather_time_of_day_color_title"
+                                       android:textAlignment="center"
+                                       android:layout_gravity="top|center"
+                                       android:textAppearance="?android:attr/textAppearanceMedium" />
+                               
+                                       <!-- Temperature -->
+                                       <TextView
+                                               android:id="@+id/weather_specific_night_temperature"
+                                               android:layout_width="wrap_content"
+                                               android:layout_height="wrap_content"
+                                       android:text="55ºC"
+                                       android:textAlignment="center"
+                                       android:layout_gravity="bottom|center"
+                                       android:textAppearance="?android:attr/textAppearanceMedium"
+                                       android:textStyle="bold" />
+                               </LinearLayout>
+                       </LinearLayout>
+               </HorizontalScrollView>
+       </LinearLayout>
+</ScrollView>
diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml
new file mode 100644 (file)
index 0000000..5d21935
--- /dev/null
@@ -0,0 +1,11 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context="de.example.exampletdd.MainActivity" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="@string/weather_preferences_action_settings"/>
+
+</menu>
diff --git a/app/src/main/res/menu/weather_main_menu.xml b/app/src/main/res/menu/weather_main_menu.xml
new file mode 100644 (file)
index 0000000..f3f36c8
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+    
+    
+    <item
+        android:id="@+id/weather_menu_settings"
+        android:menuCategory="system"
+        android:title="@string/weather_preferences_action_settings"
+        android:titleCondensed="@string/weather_preferences_action_settings"
+        android:checked="false"
+        android:visible="true"
+        android:checkable="false"
+        android:enabled="true"
+        android:icon="@drawable/ic_action_settings"
+        android:showAsAction="ifRoom">
+    </item>
+    <item
+        android:id="@+id/weather_menu_map"
+        android:icon="@drawable/ic_action_map"
+        android:showAsAction="ifRoom"
+        android:visible="true"
+        android:checkable="false"
+        android:enabled="true"
+        android:checked="false"
+        android:title="@string/weather_map_action_map"
+        android:titleCondensed="@string/weather_map_action_map">
+    </item>
+    
+
+</menu>
diff --git a/app/src/main/res/values-v11/styles.xml b/app/src/main/res/values-v11/styles.xml
new file mode 100644 (file)
index 0000000..4460dcf
--- /dev/null
@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>
diff --git a/app/src/main/res/values-v14/dimens.xml b/app/src/main/res/values-v14/dimens.xml
new file mode 100644 (file)
index 0000000..94bb2e6
--- /dev/null
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+    <dimen name="widget_margin">0dp</dimen>
+</resources>
diff --git a/app/src/main/res/values-v14/styles.xml b/app/src/main/res/values-v14/styles.xml
new file mode 100644 (file)
index 0000000..3e61a52
--- /dev/null
@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644 (file)
index 0000000..f3e7020
--- /dev/null
@@ -0,0 +1,10 @@
+<resources>
+
+    <!--
+         Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
+    -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+
+</resources>
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
new file mode 100644 (file)
index 0000000..2de335e
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string-array name="weather_preferences_day_forecast">
+        <item>5</item>
+        <item>10</item>
+        <item>14</item>
+    </string-array>
+    <string-array name="weather_preferences_day_forecast_human_value">
+        <item>5 day forecast</item>
+        <item>10 day forecast</item>
+        <item>14 day forecast</item>
+    </string-array>
+    <string-array name="weather_preferences_update_time_rate">
+        <item>900</item>
+        <item>1800</item>
+        <item>3600</item>       
+        <item>43200</item>
+        <item>86400</item>    
+    </string-array>
+    <string-array name="weather_preferences_update_time_rate_human_value">
+        <item>fifteen minutes</item>
+        <item>half hour</item>
+        <item>one hour</item>   
+        <item>half day</item>
+        <item>one day</item>     
+    </string-array>
+    <string-array name="weather_preferences_refresh_interval">
+        <item>300000</item>
+        <item>900000</item>
+        <item>1800000</item>
+        <item>3600000</item>
+        <item>7200000</item>
+        <item>43200000</item>
+        <item>86400000</item>
+    </string-array>
+    <string-array name="weather_preferences_refresh_interval_human_value">
+        <item>five minutes</item>
+        <item>fifteen minutes</item>
+        <item>half hour</item>
+        <item>one hour</item>
+        <item>two hours</item>
+        <item>half day</item>
+        <item>one day</item>
+    </string-array>
+    <string-array name="weather_preferences_temperature">
+        <item>@string/weather_preferences_temperature_celsius</item>
+        <item>@string/weather_preferences_temperature_fahrenheit</item>
+        <item>@string/weather_preferences_temperature_kelvin</item>
+    </string-array>
+    <string-array name="weather_preferences_temperature_human_value">
+        <item>@string/weather_preferences_temperature_celsius_human_value</item>
+        <item>@string/weather_preferences_temperature_fahrenheit_human_value</item>
+        <item>@string/weather_preferences_temperature_kelvin_human_value</item>
+    </string-array>
+    <string-array name="weather_preferences_wind">
+        <item>@string/weather_preferences_wind_meters</item>
+        <item>@string/weather_preferences_wind_miles</item>
+    </string-array>
+    <string-array name="weather_preferences_wind_human_value">
+        <item>@string/weather_preferences_wind_human_value_meters</item>
+        <item>@string/weather_preferences_wind_human_value_miles</item>
+    </string-array>
+    <string-array name="weather_preferences_pressure">
+        <item>@string/weather_preferences_pressure_pascal</item>
+        <item>@string/weather_preferences_pressure_standard_atm</item>
+    </string-array>
+    <string-array name="weather_preferences_pressure_human_value">
+        <item>@string/weather_preferences_pressure_human_value_pascal</item>
+        <item>@string/weather_preferences_pressure_human_value_standard_atm</item>
+    </string-array>
+</resources>
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..063ada2
--- /dev/null
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+    <dimen name="widget_margin">8dp</dimen>
+</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..dea5420
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <string name="app_name">Weather Information</string>
+    <string name="icon_weather_description">Icon weather</string> 
+
+
+    <!-- Activities Current, Overview and Specific -->
+    <string name="text_field_sun_rise">SUN RISE</string>
+    <string name="text_field_sun_set">SUN SET</string>
+    <string name="text_field_feels_like">FEELS LIKE</string>
+    <string name="text_field_clouds">CLOUDS</string>
+    <string name="text_field_rain">RAIN</string>
+    <string name="text_field_wind">WIND</string>
+    <string name="text_field_snow">SNOW</string>
+    <string name="text_field_pressure">PRESSURE</string>
+    <string name="text_field_humidity">HUMIDITY</string>
+    <string name="text_units_mm3h">mm 3h</string>
+    <string name="text_units_percent">%</string>
+    <string name="text_field_remote_error">No data available</string>
+
+
+    <!-- Preferences Acitivity -->
+    <string name="weather_preferences_action_settings">Settings</string>
+    <string name="weather_preferences_units">Units</string>
+    <string name="weather_preferences_temperature_key">weather_preferences_temperature</string>
+    <string name="weather_preferences_temperature">Temperature</string>
+    <string name="weather_preferences_temperature_celsius">ºC</string>
+    <string name="weather_preferences_temperature_fahrenheit">ºF</string>
+    <string name="weather_preferences_temperature_kelvin">K</string>
+    <string name="weather_preferences_temperature_celsius_human_value">celsius</string>
+    <string name="weather_preferences_temperature_fahrenheit_human_value">fahrenheit</string>
+    <string name="weather_preferences_temperature_kelvin_human_value">kelvin</string>
+    <string name="weather_preferences_notifications">Notifications</string>
+    <string name="weather_preferences_notifications_switch_off_summary">Disabled</string>
+    <string name="weather_preferences_notifications_switch_on_summary">Enabled</string>
+    <string name="weather_preferences_notifications_switch_off">OFF</string>
+    <string name="weather_preferences_notifications_switch_on">ON</string>
+    <string name="weather_preferences_notifications_switch_key">weather_preferences_notifications_switch</string>
+    <string name="weather_preferences_update_time_rate_key">weather_preferences_update_time_rate</string>
+    <string name="weather_preferences_update_time_rate">Update time rate</string>
+    <string name="weather_preferences_day_forecast_key">weather_preferences_day_forecast</string>
+    <string name="weather_preferences_day_forecast">Forecast days number</string>
+    <string name="weather_preferences_refresh_interval_key">weather_preferences_refresh_interval</string>
+    <string name="weather_preferences_refresh_interval">Refresh interval</string>
+    <string name="weather_preferences_wind_key">weather_preferences_wind</string>
+    <string name="weather_preferences_wind">Wind</string>
+    <string name="weather_preferences_wind_meters">m/s</string>
+    <string name="weather_preferences_wind_miles">mph</string>
+    <string name="weather_preferences_wind_human_value_meters">meter per second</string>
+    <string name="weather_preferences_wind_human_value_miles">miles per hour</string>
+    <string name="weather_preferences_pressure_key">weather_preferences_pressure</string>
+    <string name="weather_preferences_pressure">Pressure</string>
+    <string name="weather_preferences_pressure_pascal">hpa</string>
+    <string name="weather_preferences_pressure_standard_atm">atm</string>
+    <string name="weather_preferences_pressure_human_value_pascal">pascal</string>
+    <string name="weather_preferences_pressure_human_value_standard_atm">standard atmosphere</string>
+
+
+    <!-- Widget Preferences Activity -->
+    <string name="widget_preferences_action_settings">Settings</string>
+    <string name="widget_preferences_button_refresh">Refresh</string>
+    <string name="widget_preferences_country">Country</string>
+    <string name="widget_preferences_units">Units</string>
+    <string name="widget_preferences_temperature_key">widget_preferences_temperature</string>
+    <string name="widget_preferences_country_switch_key">widget_preferences_countries_switch</string>
+    <string name="widget_preferences_country_switch_off_summary">Hide</string>
+    <string name="widget_preferences_country_switch_on_summary">Show</string>
+    <string name="widget_preferences_country_switch_off">OFF</string>
+    <string name="widget_preferences_country_switch_on">ON</string>
+
+
+    <!-- Map Activity -->
+    <string name="weather_map_action_map">Select Location</string>
+    <string name="city_not_found">city not found</string>
+    <string name="country_not_found">country not found</string>
+    <string name="progress_dialog_generic_message">Please wait&#8230;</string>
+    <string name="weather_map_button_savelocation">Save Location</string>
+       <string name="weather_map_button_getlocation">Get Location</string>
+       
+       
+       <!-- DO NOT TRANSLATE -->
+       <string name="uri_api_weather_today">http://api.openweathermap.org/data/{0}/weather?lat={1}&amp;lon={2}&amp;cnt=1</string>
+    <string name="uri_api_weather_forecast">http://api.openweathermap.org/data/{0}/forecast/daily?lat={1}&amp;lon={2}&amp;cnt={3}&amp;mode=json</string>
+    <string name="api_version">2.5</string>
+</resources>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..034465a
--- /dev/null
@@ -0,0 +1,24 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="android:Theme.Holo">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+    
+
+    <color name="weather_time_of_day_color_title">#48aed4</color>
+    <color name="widget_background_holo_dark">#ff000000</color>
+
+</resources>
diff --git a/app/src/main/res/xml/appwidget_preferences.xml b/app/src/main/res/xml/appwidget_preferences.xml
new file mode 100644 (file)
index 0000000..db489da
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+    <PreferenceCategory android:title="@string/widget_preferences_country">
+        <SwitchPreference android:key="@string/widget_preferences_country_switch_key"
+            android:summaryOn="@string/widget_preferences_country_switch_on_summary"
+            android:summaryOff="@string/widget_preferences_country_switch_off_summary"
+            android:switchTextOff="@string/widget_preferences_country_switch_off"
+            android:switchTextOn="@string/widget_preferences_country_switch_on"
+            android:selectable="true"
+            android:enabled="true"
+            android:defaultValue="@string/widget_preferences_country_switch_off"
+            android:disableDependentsState="false"
+            android:persistent="true"/>
+    </PreferenceCategory>
+    <PreferenceCategory android:title="@string/widget_preferences_units">
+        <ListPreference android:key="@string/widget_preferences_temperature_key"
+            android:title="@string/weather_preferences_temperature"
+            android:summary="@string/weather_preferences_temperature_celsius_human_value"
+            android:entries="@array/weather_preferences_temperature_human_value"
+            android:entryValues="@array/weather_preferences_temperature"
+            android:selectable="true"
+            android:persistent="true"
+            android:defaultValue="@string/weather_preferences_temperature_celsius" />
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/app/src/main/res/xml/appwidget_provider.xml b/app/src/main/res/xml/appwidget_provider.xml
new file mode 100644 (file)
index 0000000..155242e
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+    android:minWidth="180dp"
+    android:minHeight="40dp"
+    android:minResizeWidth="180dp"
+    android:minResizeHeight="40dp"
+    android:resizeMode="none"
+    android:previewImage="@drawable/ic_launcher"
+    android:initialLayout="@layout/appwidget_error"
+    android:configure="de.example.exampletdd.widget.WidgetConfigure" 
+    android:widgetCategory="home_screen|keyguard"
+    android:updatePeriodMillis="3600000">
+</appwidget-provider>
diff --git a/app/src/main/res/xml/weather_preferences.xml b/app/src/main/res/xml/weather_preferences.xml
new file mode 100644 (file)
index 0000000..baaa006
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+    <ListPreference android:key="@string/weather_preferences_day_forecast_key"
+        android:title="@string/weather_preferences_day_forecast"
+        android:entries="@array/weather_preferences_day_forecast_human_value"
+        android:entryValues="@array/weather_preferences_day_forecast"
+        android:selectable="true"
+        android:persistent="true"
+        android:defaultValue="14"
+        android:summary="14 day forecast" />
+    <ListPreference android:key="@string/weather_preferences_refresh_interval_key"
+        android:title="@string/weather_preferences_refresh_interval"
+        android:entries="@array/weather_preferences_refresh_interval_human_value"
+        android:entryValues="@array/weather_preferences_refresh_interval"
+        android:selectable="true"
+        android:persistent="true"
+        android:defaultValue="300000"
+        android:summary="five minutes" />
+    <PreferenceCategory android:title="@string/weather_preferences_units">
+        <ListPreference android:key="@string/weather_preferences_temperature_key"
+            android:title="@string/weather_preferences_temperature"
+            android:summary="@string/weather_preferences_temperature_celsius_human_value"
+            android:entries="@array/weather_preferences_temperature_human_value"
+            android:entryValues="@array/weather_preferences_temperature"
+            android:selectable="true"
+            android:persistent="true"
+            android:defaultValue="@string/weather_preferences_temperature_celsius" />
+        <ListPreference android:key="@string/weather_preferences_wind_key"
+            android:entryValues="@array/weather_preferences_wind"
+            android:entries="@array/weather_preferences_wind_human_value"
+            android:summary="@string/weather_preferences_wind_human_value_meters"
+            android:selectable="true"
+            android:persistent="true"
+            android:defaultValue="@string/weather_preferences_wind_meters"
+            android:title="@string/weather_preferences_wind"/>
+        <ListPreference android:key="@string/weather_preferences_pressure_key"
+            android:entryValues="@array/weather_preferences_pressure"
+            android:entries="@array/weather_preferences_pressure_human_value"
+            android:summary="@string/weather_preferences_pressure_human_value_pascal"
+            android:selectable="true"
+            android:persistent="true"
+            android:defaultValue="@string/weather_preferences_pressure_pascal"
+            android:title="@string/weather_preferences_pressure"/>
+    </PreferenceCategory>
+    <PreferenceCategory android:title="@string/weather_preferences_notifications">
+        <SwitchPreference android:key="@string/weather_preferences_notifications_switch_key"
+            android:summaryOn="@string/weather_preferences_notifications_switch_on_summary"
+            android:summaryOff="@string/weather_preferences_notifications_switch_off_summary"
+            android:switchTextOff="@string/weather_preferences_notifications_switch_off"
+            android:switchTextOn="@string/weather_preferences_notifications_switch_on"
+            android:selectable="true"
+            android:enabled="true"
+            android:defaultValue="@string/weather_preferences_notifications_switch_off"
+            android:disableDependentsState="false"
+            android:persistent="true"/>
+        <ListPreference android:key="@string/weather_preferences_update_time_rate_key"
+               android:entries="@array/weather_preferences_update_time_rate_human_value"
+               android:entryValues="@array/weather_preferences_update_time_rate"
+               android:title="@string/weather_preferences_update_time_rate"
+               android:defaultValue="900"
+               android:persistent="true"
+               android:selectable="true"
+               android:summary="fifteen minutes"
+               android:dependency="@string/weather_preferences_notifications_switch_key"/>
+    </PreferenceCategory>
+</PreferenceScreen>
diff --git a/build.gradle b/build.gradle
new file mode 100644 (file)
index 0000000..d03f0ba
--- /dev/null
@@ -0,0 +1,15 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:0.12.2'
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
diff --git a/gen/.gitignore b/gen/.gitignore
deleted file mode 100644 (file)
index b6c80c1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/com
-/de
-/.gitignore
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644 (file)
index 0000000..8c0fb64
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644 (file)
index 0000000..1e61d1f
--- /dev/null
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755 (executable)
index 0000000..91a7e26
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644 (file)
index 0000000..aec9973
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem  Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windowz variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+if "%@eval[2+2]" == "4" goto 4NT_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+goto execute\r
+\r
+:4NT_args\r
+@rem Get arguments from the 4NT Shell from JP Software\r
+set CMD_LINE_ARGS=%$\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
diff --git a/ic_launcher-web.png b/ic_launcher-web.png
deleted file mode 100644 (file)
index a18cbb4..0000000
Binary files a/ic_launcher-web.png and /dev/null differ
diff --git a/import-summary.txt b/import-summary.txt
new file mode 100644 (file)
index 0000000..f060163
--- /dev/null
@@ -0,0 +1,83 @@
+ECLIPSE ANDROID PROJECT IMPORT SUMMARY
+======================================
+
+Manifest Merging:
+-----------------
+Your project uses libraries that provide manifests, and your Eclipse
+project did not explicitly turn on manifest merging. In Android Gradle
+projects, manifests are always merged (meaning that contents from your
+libraries' manifests will be merged into the app manifest. If you had
+manually copied contents from library manifests into your app manifest
+you may need to remove these for the app to build correctly.
+
+Ignored Files:
+--------------
+The following files were *not* copied into the new Gradle project; you
+should evaluate whether these are still needed in your project and if
+so manually move them:
+
+* ic_launcher-web.png
+* proguard-project.txt
+* tests/
+* tests/gen/
+* tests/gen/de/
+* tests/gen/de/example/
+* tests/gen/de/example/exampletdd/
+* tests/gen/de/example/exampletdd/test/
+* tests/gen/de/example/exampletdd/test/BuildConfig.java
+* tests/gen/de/example/exampletdd/test/R.java
+* tests/proguard-project.txt
+* tests/project.properties
+
+Replaced Jars with Dependencies:
+--------------------------------
+The importer recognized the following .jar files as third party
+libraries and replaced them with Gradle dependencies instead. This has
+the advantage that more explicit version information is known, and the
+libraries can be updated automatically. However, it is possible that
+the .jar file in your project was of an older version than the
+dependency we picked, which could render the project not compileable.
+You can disable the jar replacement in the import wizard and try again:
+
+android-support-v4.jar => com.android.support:support-v4:+
+
+Replaced Libraries with Dependencies:
+-------------------------------------
+The importer recognized the following library projects as third party
+libraries and replaced them with Gradle dependencies instead. This has
+the advantage that more explicit version information is known, and the
+libraries can be updated automatically. However, it is possible that
+the source files in your project were of an older version than the
+dependency we picked, which could render the project not compileable.
+You can disable the library replacement in the import wizard and try
+again:
+
+google-play-services_lib => [com.google.android.gms:play-services:+]
+
+Moved Files:
+------------
+Android Gradle projects use a different directory structure than ADT
+Eclipse projects. Here's how the projects were restructured:
+
+* AndroidManifest.xml => app/src/main/AndroidManifest.xml
+* libs/jackson-core-2.3.3.jar => app/libs/jackson-core-2.3.3.jar
+* lint.xml => app/lint.xml
+* res/ => app/src/main/res/
+* src/ => app/src/main/java/
+* tests/res/ => app/src/androidTest/res/
+* tests/src/ => app/src/androidTest/java/
+
+Next Steps:
+-----------
+You can now build the project. The Gradle project needs network
+connectivity to download dependencies.
+
+Bugs:
+-----
+If for some reason your project does not build, and you determine that
+it is due to a bug or limitation of the Eclipse to Gradle importer,
+please file a bug at http://b.android.com with category
+Component-Tools.
+
+(This import summary is for your information only, and can be deleted
+after import once you are satisfied with the results.)
diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar
deleted file mode 100644 (file)
index c31cede..0000000
Binary files a/libs/android-support-v4.jar and /dev/null differ
diff --git a/libs/jackson-core-2.3.3.jar b/libs/jackson-core-2.3.3.jar
deleted file mode 100644 (file)
index 8312650..0000000
Binary files a/libs/jackson-core-2.3.3.jar and /dev/null differ
diff --git a/lint.xml b/lint.xml
deleted file mode 100644 (file)
index ee0eead..0000000
--- a/lint.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<lint>
-</lint>
\ No newline at end of file
diff --git a/proguard-project.txt b/proguard-project.txt
deleted file mode 100644 (file)
index dd79e3a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
-
--keep class * extends java.util.ListResourceBundle {
-    protected Object[][] getContents();
-}
-
--keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
-    public static final *** NULL;
-}
-
--keepnames @com.google.android.gms.common.annotation.KeepName class *
--keepclassmembernames class * {
-    @com.google.android.gms.common.annotation.KeepName *;
-}
-
--keepnames class * implements android.os.Parcelable {
-    public static final ** CREATOR;
-}
diff --git a/project.properties b/project.properties
deleted file mode 100644 (file)
index c7ce4b6..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-18
-android.library.reference.1=../google-play-services_lib
-android.library=false
diff --git a/res/anim/weather_map_enter_progress.xml b/res/anim/weather_map_enter_progress.xml
deleted file mode 100644 (file)
index c747270..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set>
-    <translate xmlns:android="http://schemas.android.com/apk/res/android"
-               android:fromYDelta="100%"
-               android:toYDelta="0%"
-               android:interpolator="@android:anim/decelerate_interpolator"
-               android:duration="@android:integer/config_mediumAnimTime"/>
-</set>
diff --git a/res/anim/weather_map_exit_progress.xml b/res/anim/weather_map_exit_progress.xml
deleted file mode 100644 (file)
index f425b7e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set>
-    <translate xmlns:android="http://schemas.android.com/apk/res/android"
-               android:fromYDelta="0%"
-               android:toYDelta="-100%"
-               android:interpolator="@android:anim/accelerate_interpolator"
-               android:duration="@android:integer/config_mediumAnimTime"/>
-</set>
diff --git a/res/drawable-hdpi/ic_action_import_export.png b/res/drawable-hdpi/ic_action_import_export.png
deleted file mode 100644 (file)
index 18c0fe7..0000000
Binary files a/res/drawable-hdpi/ic_action_import_export.png and /dev/null differ
diff --git a/res/drawable-hdpi/ic_action_map.png b/res/drawable-hdpi/ic_action_map.png
deleted file mode 100644 (file)
index 370cf5c..0000000
Binary files a/res/drawable-hdpi/ic_action_map.png and /dev/null differ
diff --git a/res/drawable-hdpi/ic_action_place.png b/res/drawable-hdpi/ic_action_place.png
deleted file mode 100644 (file)
index dba994d..0000000
Binary files a/res/drawable-hdpi/ic_action_place.png and /dev/null differ
diff --git a/res/drawable-hdpi/ic_action_refresh.png b/res/drawable-hdpi/ic_action_refresh.png
deleted file mode 100644 (file)
index dae2790..0000000
Binary files a/res/drawable-hdpi/ic_action_refresh.png and /dev/null differ
diff --git a/res/drawable-hdpi/ic_action_search.png b/res/drawable-hdpi/ic_action_search.png
deleted file mode 100644 (file)
index 772e359..0000000
Binary files a/res/drawable-hdpi/ic_action_search.png and /dev/null differ
diff --git a/res/drawable-hdpi/ic_action_settings.png b/res/drawable-hdpi/ic_action_settings.png
deleted file mode 100644 (file)
index 54eecde..0000000
Binary files a/res/drawable-hdpi/ic_action_settings.png and /dev/null differ
diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644 (file)
index 288b665..0000000
Binary files a/res/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/res/drawable-hdpi/ic_menu_settings_holo_light.png b/res/drawable-hdpi/ic_menu_settings_holo_light.png
deleted file mode 100644 (file)
index 577e055..0000000
Binary files a/res/drawable-hdpi/ic_menu_settings_holo_light.png and /dev/null differ
diff --git a/res/drawable-hdpi/thermometer.png b/res/drawable-hdpi/thermometer.png
deleted file mode 100644 (file)
index 89f39a8..0000000
Binary files a/res/drawable-hdpi/thermometer.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_clear.png b/res/drawable-hdpi/weather_clear.png
deleted file mode 100644 (file)
index 974da61..0000000
Binary files a/res/drawable-hdpi/weather_clear.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_clear_night.png b/res/drawable-hdpi/weather_clear_night.png
deleted file mode 100644 (file)
index 2db4d82..0000000
Binary files a/res/drawable-hdpi/weather_clear_night.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_few_clouds.png b/res/drawable-hdpi/weather_few_clouds.png
deleted file mode 100644 (file)
index ab3e430..0000000
Binary files a/res/drawable-hdpi/weather_few_clouds.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_few_clouds_night.png b/res/drawable-hdpi/weather_few_clouds_night.png
deleted file mode 100644 (file)
index 67ee004..0000000
Binary files a/res/drawable-hdpi/weather_few_clouds_night.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_fog.png b/res/drawable-hdpi/weather_fog.png
deleted file mode 100644 (file)
index bc3c429..0000000
Binary files a/res/drawable-hdpi/weather_fog.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_overcast.png b/res/drawable-hdpi/weather_overcast.png
deleted file mode 100644 (file)
index 8075b13..0000000
Binary files a/res/drawable-hdpi/weather_overcast.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_severe_alert.png b/res/drawable-hdpi/weather_severe_alert.png
deleted file mode 100644 (file)
index 42334e8..0000000
Binary files a/res/drawable-hdpi/weather_severe_alert.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_showers.png b/res/drawable-hdpi/weather_showers.png
deleted file mode 100644 (file)
index d2a456a..0000000
Binary files a/res/drawable-hdpi/weather_showers.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_showers_scattered.png b/res/drawable-hdpi/weather_showers_scattered.png
deleted file mode 100644 (file)
index e58ade9..0000000
Binary files a/res/drawable-hdpi/weather_showers_scattered.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_snow.png b/res/drawable-hdpi/weather_snow.png
deleted file mode 100644 (file)
index 4812c8c..0000000
Binary files a/res/drawable-hdpi/weather_snow.png and /dev/null differ
diff --git a/res/drawable-hdpi/weather_storm.png b/res/drawable-hdpi/weather_storm.png
deleted file mode 100644 (file)
index b829abf..0000000
Binary files a/res/drawable-hdpi/weather_storm.png and /dev/null differ
diff --git a/res/drawable-mdpi/ic_action_import_export.png b/res/drawable-mdpi/ic_action_import_export.png
deleted file mode 100644 (file)
index 95914cc..0000000
Binary files a/res/drawable-mdpi/ic_action_import_export.png and /dev/null differ
diff --git a/res/drawable-mdpi/ic_action_map.png b/res/drawable-mdpi/ic_action_map.png
deleted file mode 100644 (file)
index 50a9100..0000000
Binary files a/res/drawable-mdpi/ic_action_map.png and /dev/null differ
diff --git a/res/drawable-mdpi/ic_action_place.png b/res/drawable-mdpi/ic_action_place.png
deleted file mode 100644 (file)
index ce055ca..0000000
Binary files a/res/drawable-mdpi/ic_action_place.png and /dev/null differ
diff --git a/res/drawable-mdpi/ic_action_refresh.png b/res/drawable-mdpi/ic_action_refresh.png
deleted file mode 100644 (file)
index 94ab6f4..0000000
Binary files a/res/drawable-mdpi/ic_action_refresh.png and /dev/null differ
diff --git a/res/drawable-mdpi/ic_action_search.png b/res/drawable-mdpi/ic_action_search.png
deleted file mode 100644 (file)
index 4edb1ff..0000000
Binary files a/res/drawable-mdpi/ic_action_search.png and /dev/null differ
diff --git a/res/drawable-mdpi/ic_action_settings.png b/res/drawable-mdpi/ic_action_settings.png
deleted file mode 100644 (file)
index 25c36db..0000000
Binary files a/res/drawable-mdpi/ic_action_settings.png and /dev/null differ
diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644 (file)
index 6ae570b..0000000
Binary files a/res/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/res/drawable-mdpi/thermometer.png b/res/drawable-mdpi/thermometer.png
deleted file mode 100644 (file)
index f645657..0000000
Binary files a/res/drawable-mdpi/thermometer.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_clear.png b/res/drawable-mdpi/weather_clear.png
deleted file mode 100644 (file)
index 0bdb0da..0000000
Binary files a/res/drawable-mdpi/weather_clear.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_clear_night.png b/res/drawable-mdpi/weather_clear_night.png
deleted file mode 100644 (file)
index 2617ec1..0000000
Binary files a/res/drawable-mdpi/weather_clear_night.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_few_clouds.png b/res/drawable-mdpi/weather_few_clouds.png
deleted file mode 100644 (file)
index 5a78bd0..0000000
Binary files a/res/drawable-mdpi/weather_few_clouds.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_few_clouds_night.png b/res/drawable-mdpi/weather_few_clouds_night.png
deleted file mode 100644 (file)
index 3dcd13f..0000000
Binary files a/res/drawable-mdpi/weather_few_clouds_night.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_fog.png b/res/drawable-mdpi/weather_fog.png
deleted file mode 100644 (file)
index 7d99916..0000000
Binary files a/res/drawable-mdpi/weather_fog.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_overcast.png b/res/drawable-mdpi/weather_overcast.png
deleted file mode 100644 (file)
index 79303a5..0000000
Binary files a/res/drawable-mdpi/weather_overcast.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_severe_alert.png b/res/drawable-mdpi/weather_severe_alert.png
deleted file mode 100644 (file)
index 308931b..0000000
Binary files a/res/drawable-mdpi/weather_severe_alert.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_showers.png b/res/drawable-mdpi/weather_showers.png
deleted file mode 100644 (file)
index 6dce4e1..0000000
Binary files a/res/drawable-mdpi/weather_showers.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_showers_scattered.png b/res/drawable-mdpi/weather_showers_scattered.png
deleted file mode 100644 (file)
index 0e0b43e..0000000
Binary files a/res/drawable-mdpi/weather_showers_scattered.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_snow.png b/res/drawable-mdpi/weather_snow.png
deleted file mode 100644 (file)
index 9364b58..0000000
Binary files a/res/drawable-mdpi/weather_snow.png and /dev/null differ
diff --git a/res/drawable-mdpi/weather_storm.png b/res/drawable-mdpi/weather_storm.png
deleted file mode 100644 (file)
index 5e37b51..0000000
Binary files a/res/drawable-mdpi/weather_storm.png and /dev/null differ
diff --git a/res/drawable-xhdpi/ic_action_import_export.png b/res/drawable-xhdpi/ic_action_import_export.png
deleted file mode 100644 (file)
index b247eda..0000000
Binary files a/res/drawable-xhdpi/ic_action_import_export.png and /dev/null differ
diff --git a/res/drawable-xhdpi/ic_action_map.png b/res/drawable-xhdpi/ic_action_map.png
deleted file mode 100644 (file)
index 537c5a4..0000000
Binary files a/res/drawable-xhdpi/ic_action_map.png and /dev/null differ
diff --git a/res/drawable-xhdpi/ic_action_place.png b/res/drawable-xhdpi/ic_action_place.png
deleted file mode 100644 (file)
index 5e93aeb..0000000
Binary files a/res/drawable-xhdpi/ic_action_place.png and /dev/null differ
diff --git a/res/drawable-xhdpi/ic_action_refresh.png b/res/drawable-xhdpi/ic_action_refresh.png
deleted file mode 100644 (file)
index ab4ab9d..0000000
Binary files a/res/drawable-xhdpi/ic_action_refresh.png and /dev/null differ
diff --git a/res/drawable-xhdpi/ic_action_search.png b/res/drawable-xhdpi/ic_action_search.png
deleted file mode 100644 (file)
index 19658e4..0000000
Binary files a/res/drawable-xhdpi/ic_action_search.png and /dev/null differ
diff --git a/res/drawable-xhdpi/ic_action_settings.png b/res/drawable-xhdpi/ic_action_settings.png
deleted file mode 100644 (file)
index 425a8bc..0000000
Binary files a/res/drawable-xhdpi/ic_action_settings.png and /dev/null differ
diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644 (file)
index d4fb7cd..0000000
Binary files a/res/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/res/drawable-xhdpi/thermometer.png b/res/drawable-xhdpi/thermometer.png
deleted file mode 100644 (file)
index bd86520..0000000
Binary files a/res/drawable-xhdpi/thermometer.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_clear.png b/res/drawable-xhdpi/weather_clear.png
deleted file mode 100644 (file)
index 42bad9c..0000000
Binary files a/res/drawable-xhdpi/weather_clear.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_clear_night.png b/res/drawable-xhdpi/weather_clear_night.png
deleted file mode 100644 (file)
index a9ab2dc..0000000
Binary files a/res/drawable-xhdpi/weather_clear_night.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_few_clouds.png b/res/drawable-xhdpi/weather_few_clouds.png
deleted file mode 100644 (file)
index 954a7fd..0000000
Binary files a/res/drawable-xhdpi/weather_few_clouds.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_few_clouds_night.png b/res/drawable-xhdpi/weather_few_clouds_night.png
deleted file mode 100644 (file)
index be93567..0000000
Binary files a/res/drawable-xhdpi/weather_few_clouds_night.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_fog.png b/res/drawable-xhdpi/weather_fog.png
deleted file mode 100644 (file)
index bcca0a8..0000000
Binary files a/res/drawable-xhdpi/weather_fog.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_overcast.png b/res/drawable-xhdpi/weather_overcast.png
deleted file mode 100644 (file)
index 5096963..0000000
Binary files a/res/drawable-xhdpi/weather_overcast.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_severe_alert.png b/res/drawable-xhdpi/weather_severe_alert.png
deleted file mode 100644 (file)
index c074f4e..0000000
Binary files a/res/drawable-xhdpi/weather_severe_alert.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_showers.png b/res/drawable-xhdpi/weather_showers.png
deleted file mode 100644 (file)
index 28264f2..0000000
Binary files a/res/drawable-xhdpi/weather_showers.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_showers_scattered.png b/res/drawable-xhdpi/weather_showers_scattered.png
deleted file mode 100644 (file)
index f76f4e9..0000000
Binary files a/res/drawable-xhdpi/weather_showers_scattered.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_snow.png b/res/drawable-xhdpi/weather_snow.png
deleted file mode 100644 (file)
index 5226484..0000000
Binary files a/res/drawable-xhdpi/weather_snow.png and /dev/null differ
diff --git a/res/drawable-xhdpi/weather_storm.png b/res/drawable-xhdpi/weather_storm.png
deleted file mode 100644 (file)
index 7539dee..0000000
Binary files a/res/drawable-xhdpi/weather_storm.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/ic_action_import_export.png b/res/drawable-xxhdpi/ic_action_import_export.png
deleted file mode 100644 (file)
index 2dccb24..0000000
Binary files a/res/drawable-xxhdpi/ic_action_import_export.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/ic_action_map.png b/res/drawable-xxhdpi/ic_action_map.png
deleted file mode 100644 (file)
index ed72ce9..0000000
Binary files a/res/drawable-xxhdpi/ic_action_map.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/ic_action_place.png b/res/drawable-xxhdpi/ic_action_place.png
deleted file mode 100644 (file)
index 25623c7..0000000
Binary files a/res/drawable-xxhdpi/ic_action_place.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/ic_action_refresh.png b/res/drawable-xxhdpi/ic_action_refresh.png
deleted file mode 100644 (file)
index 44ee117..0000000
Binary files a/res/drawable-xxhdpi/ic_action_refresh.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/ic_action_search.png b/res/drawable-xxhdpi/ic_action_search.png
deleted file mode 100644 (file)
index a108638..0000000
Binary files a/res/drawable-xxhdpi/ic_action_search.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/ic_action_settings.png b/res/drawable-xxhdpi/ic_action_settings.png
deleted file mode 100644 (file)
index fe5fec4..0000000
Binary files a/res/drawable-xxhdpi/ic_action_settings.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/ic_launcher.png b/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100644 (file)
index 85a6081..0000000
Binary files a/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/thermometer.png b/res/drawable-xxhdpi/thermometer.png
deleted file mode 100644 (file)
index 37b3747..0000000
Binary files a/res/drawable-xxhdpi/thermometer.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_clear.png b/res/drawable-xxhdpi/weather_clear.png
deleted file mode 100644 (file)
index 73a5bbd..0000000
Binary files a/res/drawable-xxhdpi/weather_clear.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_clear_night.png b/res/drawable-xxhdpi/weather_clear_night.png
deleted file mode 100644 (file)
index 2c60054..0000000
Binary files a/res/drawable-xxhdpi/weather_clear_night.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_few_clouds.png b/res/drawable-xxhdpi/weather_few_clouds.png
deleted file mode 100644 (file)
index 2d38702..0000000
Binary files a/res/drawable-xxhdpi/weather_few_clouds.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_few_clouds_night.png b/res/drawable-xxhdpi/weather_few_clouds_night.png
deleted file mode 100644 (file)
index 333afa7..0000000
Binary files a/res/drawable-xxhdpi/weather_few_clouds_night.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_fog.png b/res/drawable-xxhdpi/weather_fog.png
deleted file mode 100644 (file)
index 1bebc54..0000000
Binary files a/res/drawable-xxhdpi/weather_fog.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_overcast.png b/res/drawable-xxhdpi/weather_overcast.png
deleted file mode 100644 (file)
index e3101eb..0000000
Binary files a/res/drawable-xxhdpi/weather_overcast.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_severe_alert.png b/res/drawable-xxhdpi/weather_severe_alert.png
deleted file mode 100644 (file)
index b0ac4b7..0000000
Binary files a/res/drawable-xxhdpi/weather_severe_alert.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_showers.png b/res/drawable-xxhdpi/weather_showers.png
deleted file mode 100644 (file)
index 6a1860c..0000000
Binary files a/res/drawable-xxhdpi/weather_showers.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_showers_scattered.png b/res/drawable-xxhdpi/weather_showers_scattered.png
deleted file mode 100644 (file)
index 97d0f77..0000000
Binary files a/res/drawable-xxhdpi/weather_showers_scattered.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_snow.png b/res/drawable-xxhdpi/weather_snow.png
deleted file mode 100644 (file)
index ac714cc..0000000
Binary files a/res/drawable-xxhdpi/weather_snow.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/weather_storm.png b/res/drawable-xxhdpi/weather_storm.png
deleted file mode 100644 (file)
index c339221..0000000
Binary files a/res/drawable-xxhdpi/weather_storm.png and /dev/null differ
diff --git a/res/layout-large/weather_main.xml b/res/layout-large/weather_main.xml
deleted file mode 100644 (file)
index 95e773e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context="de.example.exampletdd.WeatherInformationActivity"
-    tools:ignore="MergeRootFrame" >
-
-    <fragment
-        android:id="@+id/weather_overview_fragment"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        class="de.example.exampletdd.fragment.overview.OverviewFragment" />
-    
-    <fragment
-        android:id="@+id/weather_specific_fragment"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        class="de.example.exampletdd.fragment.specific.SpecificFragment" />
-
-</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/appwidget.xml b/res/layout/appwidget.xml
deleted file mode 100644 (file)
index 08f33cc..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/weather_appwidget"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_gravity="fill"
-    android:orientation="horizontal"
-    android:baselineAligned="false"
-    android:background="@color/widget_background_holo_dark"
-    android:padding="@dimen/widget_margin" >
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:padding="4dp"
-        android:orientation="vertical" >
-    
-       <ImageView
-               android:id="@+id/weather_appwidget_image"
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="start"
-               android:contentDescription="@string/icon_weather_description"
-               android:orientation="vertical"
-               android:src="@drawable/weather_showers" />
-    
-    </LinearLayout>
-    
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:padding="4dp"
-        android:orientation="vertical" >
-        
-        <TextView
-            android:id="@+id/weather_appwidget_temperature_max"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="12ºC"
-            android:textAlignment="center"
-            android:textAllCaps="true"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textStyle="bold" />
-    
-       <TextView
-               android:id="@+id/weather_appwidget_temperature_min"
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="center"
-               android:text="5ºC"
-               android:textAlignment="center"
-               android:textAllCaps="true"
-               android:textAppearance="?android:attr/textAppearanceMedium"
-               android:textStyle="normal" />
-    </LinearLayout>
-    
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:orientation="vertical"
-        android:padding="4dp" >
-        
-        <TextView
-            android:id="@+id/weather_appwidget_city"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="Morata de Tajuña"
-            android:textAlignment="center"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textStyle="bold" />
-    
-        <TextView
-            android:id="@+id/weather_appwidget_country"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="Spain"
-            android:textAlignment="center"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textStyle="normal" />
-    </LinearLayout>
-            
-
-    
-
-
-</LinearLayout>
diff --git a/res/layout/appwidget_configure.xml b/res/layout/appwidget_configure.xml
deleted file mode 100644 (file)
index f5df9a0..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_gravity="fill_vertical|fill_horizontal" >
-
-    <LinearLayout android:id="@+id/weather_appwidget_configure_preferences"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_gravity="center"
-        android:orientation="horizontal" >
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@+id/weather_appwidget_configure_preferences"
-        android:layout_centerHorizontal="true"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:baselineAligned="false"
-        android:orientation="horizontal" >
-
-        <Button
-            android:id="@+id/weather_appwidget_configure_refresh_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:textAlignment="center"
-            android:text="@string/widget_preferences_button_refresh" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_centerHorizontal="true"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:baselineAligned="false"
-        android:orientation="horizontal" >
-        
-        <Button
-            android:id="@+id/weather_appwidget_configure_save_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:textAlignment="center"
-            android:text="@android:string/ok" />
-    </LinearLayout>
-
-</RelativeLayout>
-
diff --git a/res/layout/appwidget_error.xml b/res/layout/appwidget_error.xml
deleted file mode 100644 (file)
index 4b6c90f..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/weather_appwidget_error"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_gravity="fill"
-    android:orientation="horizontal"
-    android:baselineAligned="false"
-    android:background="@color/widget_background_holo_dark"
-    android:padding="@dimen/widget_margin" >
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:padding="4dp"
-        android:orientation="vertical" >
-    
-       <ImageView
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="start"
-               android:contentDescription="@string/icon_weather_description"
-               android:orientation="vertical"
-               android:src="@drawable/ic_launcher" />
-    
-    </LinearLayout>
-    
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:orientation="vertical"
-        android:padding="4dp" >
-        
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="@string/text_field_remote_error"
-            android:textAlignment="center"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textStyle="bold" />
-    </LinearLayout>
-            
-
-    
-
-
-</LinearLayout>
diff --git a/res/layout/fragment_pager.xml b/res/layout/fragment_pager.xml
deleted file mode 100644 (file)
index 07cf7a6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical" android:padding="4dip"
-        android:gravity="center_horizontal"
-        android:layout_width="match_parent" android:layout_height="match_parent">
-
-    <android.support.v4.view.ViewPager
-            android:id="@+id/pager"
-            android:layout_width="match_parent"
-            android:layout_height="0px"
-            android:layout_weight="1">
-    </android.support.v4.view.ViewPager>
-
-</LinearLayout>
diff --git a/res/layout/notification.xml b/res/layout/notification.xml
deleted file mode 100644 (file)
index fd6bf80..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_gravity="fill"
-    android:baselineAligned="false"
-    android:orientation="horizontal" >
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:orientation="vertical" >
-    
-       <ImageView
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="start"
-               android:contentDescription="@string/icon_weather_description"
-               android:orientation="vertical"
-               android:src="@drawable/ic_launcher" />
-    </LinearLayout>
-    
-
-       
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:layout_weight="2"
-        android:gravity="center"
-        android:orientation="vertical" >
-        
-        <TextView
-            android:id="@+id/weather_notification_city"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="Morata de Tajuña"
-            android:textAlignment="center"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textStyle="bold" />
-    
-        <TextView
-            android:id="@+id/weather_notification_country"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="Spain"
-            android:textAlignment="center"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textStyle="normal" />
-    </LinearLayout>
-            
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:layout_weight="1"
-        android:gravity="center"
-        android:orientation="vertical" >
-        
-        <TextView
-            android:id="@+id/weather_notification_temperature_max"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="12ºC"
-            android:textAlignment="center"
-            android:textAllCaps="true"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textStyle="bold" />
-    
-       <TextView
-               android:id="@+id/weather_notification_temperature_min"
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="center"
-               android:text="5ºC"
-               android:textAlignment="center"
-               android:textAllCaps="true"
-               android:textAppearance="?android:attr/textAppearanceMedium"
-               android:textStyle="normal" />
-    </LinearLayout>
-    
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:gravity="center"
-        android:orientation="vertical" >
-    
-       <ImageView
-               android:id="@+id/weather_notification_image"
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="end"
-               android:contentDescription="@string/icon_weather_description"
-               android:orientation="vertical"
-               android:src="@drawable/ic_launcher" />
-    
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/res/layout/weather_current_fragment.xml b/res/layout/weather_current_fragment.xml
deleted file mode 100644 (file)
index e6618b6..0000000
+++ /dev/null
@@ -1,562 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/weather_current_fragment"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent" >
-
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center">
-        
-    <!-- TODO: align start/end feels like-snow humidity-rain wind-clouds -->
-    <LinearLayout android:id="@+id/weather_current_data_container"
-        android:layout_width="match_parent"
-       android:layout_height="wrap_content"
-       android:gravity="center"
-       android:layout_gravity="fill_vertical|center_horizontal"
-       android:orientation="vertical" >
-       
-        <!-- TODO: http://developer.android.com/guide/topics/manifest/supports-screens-element.html -->
-       <!-- TODO: supporting multiple layouts/languages http://developer.android.com/guide/practices/screens_support.html -->
-       <!-- TODO: Should I use RelativeLayout for long texts (I18N) and RTL/LTR UI?
-                With long texts, many times, text will not fit... The same for WP8 :/ -->
-       <LinearLayout
-               android:layout_width="match_parent"
-               android:layout_height="match_parent"
-               android:gravity="center"
-               android:layout_gravity="top|center"
-               android:padding="50dp"
-               android:orientation="horizontal" >
-
-               <ImageView
-                               android:id="@+id/weather_current_picture"
-                       android:layout_width="0dp"
-                       android:layout_weight="1"
-                       android:layout_height="wrap_content"
-                       android:contentDescription="@string/icon_weather_description"
-                       android:scaleType="fitCenter"
-                       android:gravity="center"
-                       android:layout_gravity="center"
-                       android:src="@drawable/weather_showers" />
-
-               <LinearLayout
-                       android:layout_width="0dp"
-                       android:layout_weight="1"
-                       android:layout_height="wrap_content"
-                       android:gravity="center"
-                       android:layout_gravity="center"
-                       android:orientation="vertical" >
-
-                       <TextView
-                           android:id="@+id/weather_current_temp_max"
-                           android:layout_width="wrap_content"
-                           android:layout_height="wrap_content"
-                           android:paddingEnd="10dp"
-                           android:paddingStart="20dp"
-                           android:singleLine="true"
-                           android:text="55ºC"
-                           android:textAlignment="textStart"
-                           android:textAppearance="?android:attr/textAppearanceLarge"
-                           android:textStyle="bold" />
-
-                       <TextView
-                       android:id="@+id/weather_current_temp_min"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:textAlignment="textStart"
-                       android:paddingEnd="10dp"
-                       android:paddingStart="20dp"
-                       android:singleLine="true"
-                       android:text="25ºC"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="normal" />
-               </LinearLayout>
-               </LinearLayout>
-       
-       <LinearLayout
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:gravity="center"
-               android:padding="25dp"
-               android:layout_gravity="top|center"
-               android:orientation="horizontal" >
-
-               <TextView
-                       android:id="@+id/weather_current_description"
-                       android:layout_width="match_parent"
-                       android:layout_height="wrap_content"
-                       android:gravity="center"
-                       android:text="Light rain"
-                       android:textAppearance="?android:attr/textAppearanceLarge"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:textStyle="bold" />    
-               </LinearLayout>
-
-       <LinearLayout
-           android:baselineAligned="false"
-               android:layout_width="match_parent"
-                       android:layout_height="wrap_content"
-               android:layout_gravity="top|fill_horizontal"
-               android:orientation="horizontal" >
-                               
-           <LinearLayout
-                       android:layout_width="0dp"
-                       android:layout_weight="1"
-                               android:layout_height="wrap_content"
-                       android:gravity="center"
-                       android:layout_gravity="center"
-                       android:orientation="horizontal" >
-                               <!-- Feels like -->
-                               <TextView
-                               android:id="@+id/weather_current_feelslike"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:layout_gravity="start"
-                               android:layout_margin="5dp"
-                               android:gravity="start"
-                               android:text="@string/text_field_feels_like"
-                               android:textAlignment="textStart"
-                               android:textAppearance="?android:attr/textAppearanceMedium"
-                               android:textColor="@color/weather_time_of_day_color_title"
-                               android:textStyle="bold" />
-        
-                               <!-- Feels like Value-->
-                               <TextView
-                               android:id="@+id/weather_current_feelslike_value"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="83"
-                               android:layout_gravity="start"
-                               android:gravity="start"
-                               android:textAlignment="textStart"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="normal" />
-        
-                               <!-- Feels like Units-->
-                               <TextView
-                               android:id="@+id/weather_current_feelslike_units"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="ºC"
-                               android:layout_gravity="start"
-                               android:gravity="start"
-                               android:textAlignment="textStart"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:layout_marginEnd="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="bold" />
-                       </LinearLayout>
-
-               <LinearLayout
-                       android:layout_width="0dp"
-                       android:layout_height="wrap_content"
-                       android:gravity="center"
-                               android:layout_gravity="center"
-                       android:layout_weight="1"
-                       android:orientation="horizontal" >
-                       <!-- Snow -->
-                               <TextView
-                               android:id="@+id/weather_current_snow"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                                       android:text="@string/text_field_snow"
-                                       android:gravity="end"
-                               android:layout_gravity="end"
-                               android:textAlignment="textEnd"
-                               android:textColor="@color/weather_time_of_day_color_title"
-                                       android:layout_margin="5dp"
-                               android:textAppearance="?android:attr/textAppearanceMedium"
-                               android:textStyle="bold" />
-          
-                               <!-- Snow Value-->
-                               <TextView
-                               android:id="@+id/weather_current_snow_value"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="1.22"
-                               android:layout_gravity="end"
-                               android:gravity="end"
-                               android:textAlignment="textEnd"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="normal" />
-        
-                               <!-- Snow Units -->
-                               <TextView
-                               android:id="@+id/weather_current_snow_units"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text=" mm 3h"
-                               android:layout_gravity="end"
-                               android:gravity="end"
-                               android:textAlignment="textEnd"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                                       android:layout_marginEnd="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="bold" />
-                       </LinearLayout>
-        </LinearLayout>
-        
-        <LinearLayout
-            android:baselineAligned="false"
-               android:layout_width="match_parent"
-                       android:layout_height="wrap_content"
-               android:layout_gravity="top|fill_horizontal"
-               android:orientation="horizontal" >
-               
-               <LinearLayout
-                               android:layout_width="0dp"
-                               android:layout_weight="1"
-                                       android:layout_height="wrap_content"
-                               android:gravity="center"
-                               android:layout_gravity="center"
-                               android:orientation="horizontal" >
-                               <!-- Humidity -->
-                               <TextView
-                               android:id="@+id/weather_current_humidity"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:layout_gravity="start"
-                               android:layout_margin="5dp"
-                               android:gravity="start"
-                               android:text="@string/text_field_humidity"
-                               android:textAlignment="textStart"
-                               android:textAppearance="?android:attr/textAppearanceMedium"
-                               android:textColor="@color/weather_time_of_day_color_title"
-                               android:textStyle="bold" />
-        
-                               <!-- Humidity Value-->
-                               <TextView
-                               android:id="@+id/weather_current_humidity_value"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="83"
-                               android:layout_gravity="start"
-                               android:gravity="start"
-                               android:textAlignment="textStart"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="normal" />
-        
-                               <!-- Humidity Units-->
-                               <TextView
-                               android:id="@+id/weather_current_humidity_units"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="%"
-                               android:layout_gravity="start"
-                               android:gravity="start"
-                               android:textAlignment="textStart"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:layout_marginEnd="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="bold" />
-                       </LinearLayout>
-
-               <LinearLayout
-                       android:layout_width="0dp"
-                       android:layout_height="wrap_content"
-                       android:gravity="center"
-                               android:layout_gravity="center"
-                       android:layout_weight="1"
-                       android:orientation="horizontal" >
-                       <!-- Rain -->
-                               <TextView
-                               android:id="@+id/weather_current_rain"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                                       android:text="@string/text_field_rain"
-                               android:layout_gravity="end"
-                               android:gravity="end"
-                               android:textAlignment="textEnd"
-                               android:textColor="@color/weather_time_of_day_color_title"
-                                       android:layout_margin="5dp"
-                               android:textAppearance="?android:attr/textAppearanceMedium"
-                               android:textStyle="bold" />
-          
-                               <!-- Rain Value-->
-                               <TextView
-                               android:id="@+id/weather_current_rain_value"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="1.24"
-                               android:layout_gravity="end"
-                               android:gravity="end"
-                               android:textAlignment="textEnd"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="normal" />
-        
-                               <!-- Rain Units -->
-                               <TextView
-                               android:id="@+id/weather_current_rain_units"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text=" mm 3h"
-                               android:layout_gravity="end"
-                               android:gravity="end"
-                               android:textAlignment="textEnd"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                                       android:layout_marginEnd="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="bold" />
-                       </LinearLayout>
-        </LinearLayout>   
-            
-        <LinearLayout
-            android:baselineAligned="false"
-               android:layout_width="match_parent"
-                       android:layout_height="wrap_content"
-               android:layout_gravity="top|fill_horizontal"
-               android:orientation="horizontal" >
-                       
-                <LinearLayout
-                               android:layout_width="0dp"
-                               android:layout_weight="1"
-                                       android:layout_height="wrap_content"
-                               android:gravity="center"
-                               android:layout_gravity="center"
-                               android:orientation="horizontal" >
-                               <!-- Wind -->
-                               <TextView
-                               android:id="@+id/weather_current_wind"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="@string/text_field_wind"
-                               android:layout_gravity="start"
-                               android:gravity="start"
-                               android:textAlignment="textStart"
-                               android:textColor="@color/weather_time_of_day_color_title"
-                               android:layout_margin="5dp"
-                               android:textAppearance="?android:attr/textAppearanceMedium"
-                               android:textStyle="bold" />
-        
-                               <!-- Wind Value-->
-                               <TextView
-                               android:id="@+id/weather_current_wind_value"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                                       android:text="6.36"
-                               android:layout_gravity="start"
-                               android:gravity="start"
-                               android:textAlignment="textStart"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="normal" />
-        
-                               <!-- Wind Units -->
-                               <TextView
-                               android:id="@+id/weather_current_wind_units"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text=" m/s"
-                               android:layout_gravity="start"
-                               android:gravity="start"
-                               android:textAlignment="textStart"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:layout_marginEnd="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="bold" />
-                       </LinearLayout>
-                       
-                <LinearLayout
-                       android:layout_width="0dp"
-                       android:layout_height="wrap_content"
-                       android:gravity="center"
-                               android:layout_gravity="center"
-                       android:layout_weight="1"
-                       android:orientation="horizontal" >
-                       <!-- Clouds -->
-                               <TextView
-                               android:id="@+id/weather_current_clouds"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="@string/text_field_clouds"
-                               android:layout_gravity="end"
-                               android:gravity="end"
-                               android:textAlignment="textEnd"
-                               android:textColor="@color/weather_time_of_day_color_title"
-                               android:layout_margin="5dp"
-                               android:textAppearance="?android:attr/textAppearanceMedium"
-                               android:textStyle="bold" />
-        
-                               <!-- Clouds Value-->
-                               <TextView
-                               android:id="@+id/weather_current_clouds_value"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="6.36"
-                               android:layout_gravity="end"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:gravity="end"
-                               android:textAlignment="textEnd"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="normal" />
-        
-                               <!-- Clouds Units -->
-                               <TextView
-                               android:id="@+id/weather_current_clouds_units"
-                               android:layout_width="wrap_content"
-                               android:layout_height="wrap_content"
-                               android:text="%"
-                               android:layout_gravity="end"
-                               android:gravity="end"
-                               android:textAlignment="textEnd"
-                               android:layout_marginTop="5dp"
-                               android:layout_marginBottom="5dp"
-                               android:layout_marginEnd="5dp"
-                               android:textAppearance="?android:attr/textAppearanceSmall"
-                               android:textStyle="bold" />
-                       </LinearLayout>
-               </LinearLayout>
-        <LinearLayout
-                       android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="top|center"
-               android:orientation="horizontal" >
-        
-                       <!-- Pressure -->
-                       <TextView
-                       android:id="@+id/weather_current_pressure"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="@string/text_field_pressure"
-                       android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:layout_margin="5dp"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="bold" />
-        
-                       <!-- Pressure Value-->
-                       <TextView
-                       android:id="@+id/weather_current_pressure_value"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="1036.05"
-                       android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="normal" />
-        
-                       <!-- Pressure Units-->
-                       <TextView
-                       android:id="@+id/weather_current_pressure_units"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text=" hpa"
-                               android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:layout_marginEnd="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="bold" />
-        </LinearLayout>
-        <LinearLayout
-                       android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="top|center"
-               android:orientation="horizontal" >
-        
-                       <!-- Sun rise -->
-                       <TextView
-                       android:id="@+id/weather_current_sunrise"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="@string/text_field_sun_rise"
-                       android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:layout_margin="5dp"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="bold" />
-        
-                       <!-- Sun rise Value-->
-                       <TextView
-                       android:id="@+id/weather_current_sunrise_value"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="2014.04.20 10:29:33"
-                       android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="normal" />
-        </LinearLayout>
-        <LinearLayout
-                       android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="top|center"
-               android:orientation="horizontal" >
-        
-                       <!-- Sun rise -->
-                       <TextView
-                       android:id="@+id/weather_current_sunset"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="@string/text_field_sun_set"
-                       android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:layout_margin="5dp"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="bold" />
-        
-                       <!-- Sun rise Value-->
-                       <TextView
-                       android:id="@+id/weather_current_sunset_value"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="2014.04.20 10:29:33"
-                       android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="normal" />
-        </LinearLayout>
-       </LinearLayout>
-       
-    <ProgressBar
-        android:id="@+id/weather_current_progressbar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:visibility="gone"
-        style="?android:attr/progressBarStyleLarge" />
-
-    <TextView
-        android:id="@+id/weather_current_error_message"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:text="@string/text_field_remote_error"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:visibility="gone" />
-
-       </FrameLayout>
-</ScrollView>
diff --git a/res/layout/weather_main_entry_list.xml b/res/layout/weather_main_entry_list.xml
deleted file mode 100644 (file)
index 017f8d0..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:baselineAligned="false"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_gravity="center_horizontal"
-    android:orientation="horizontal"
-    android:padding="5dp" >
-
-    <LinearLayout
-    android:layout_width="0dp"
-    android:layout_weight="1"
-    android:layout_height="match_parent"
-    android:gravity="center"
-    android:layout_gravity="center"
-    android:orientation="vertical" >
-
-    <TextView
-        android:id="@+id/weather_main_entry_date_name"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:text="SUN"
-        android:textAlignment="center"
-        android:textAllCaps="true"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textStyle="bold" />
-
-    <TextView
-        android:id="@+id/weather_main_entry_date_number"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:text="APR 23"
-        android:textAlignment="center"
-        android:textAllCaps="true"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textStyle="normal" />
-    
-    </LinearLayout>
-    
-
-    <LinearLayout
-    android:layout_width="0dp"
-    android:layout_weight="1"
-    android:layout_height="match_parent"
-    android:gravity="center"
-    android:layout_gravity="center"
-    android:orientation="vertical" >
-    
-        <TextView
-            android:id="@+id/weather_main_entry_temperature_max"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:text="12ºC"
-            android:textAlignment="center"
-            android:textAllCaps="true"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="@color/weather_time_of_day_color_title"
-            android:textStyle="bold" />
-    
-    <TextView
-        android:id="@+id/weather_main_entry_temperature_min"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:text="5ºC"
-        android:textAlignment="center"
-        android:textAllCaps="true"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textColor="@color/weather_time_of_day_color_title"
-        android:textStyle="normal" />
-    
-    </LinearLayout>
-    
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:layout_weight="1"
-        android:gravity="center"
-        android:orientation="vertical" >
-    
-    <ImageView
-        android:id="@+id/weather_main_entry_image"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:contentDescription="@string/icon_weather_description"
-        android:orientation="vertical"
-        android:src="@drawable/ic_launcher" />
-    
-    </LinearLayout>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/weather_map.xml b/res/layout/weather_map.xml
deleted file mode 100644 (file)
index 2e442c1..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>    
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/weather_map"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_gravity="center"
-    tools:context="de.example.exampletdd.MapActivity" >
-
-    <LinearLayout
-        android:id="@+id/weather_map_citycountry_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentStart="true" >
-       <LinearLayout
-               android:id="@+id/weather_map_city_container"
-               android:layout_width="0dp"
-               android:layout_weight="1"
-               android:layout_gravity="center"
-               android:gravity="center"
-               android:layout_height="wrap_content">     
-               <TextView
-                       android:id="@+id/weather_map_city"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="City"
-                       android:layout_gravity="center"
-                       android:textAlignment="center"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textIsSelectable="false"
-                       android:textStyle="bold|normal" />  
-       </LinearLayout>
-       
-       <ProgressBar
-           android:id="@+id/weather_map_progress"
-           android:layout_width="0dp"
-           android:layout_height="wrap_content"
-           android:layout_gravity="center"
-           android:layout_weight="1"
-           android:indeterminateBehavior="repeat"
-           android:indeterminateDuration="3500"
-           android:indeterminateOnly="true"
-           android:visibility="gone" />
-    
-       <LinearLayout
-               android:id="@+id/weather_map_country_container"
-               android:layout_width="0dp"
-               android:layout_weight="1"
-               android:layout_gravity="center"
-               android:gravity="center"
-               android:layout_height="wrap_content" >
-               <TextView
-                       android:id="@+id/weather_map_country"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="Country"
-                       android:layout_gravity="center"
-                       android:textAlignment="center"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textIsSelectable="false"
-                       android:textStyle="bold|normal" />
-               </LinearLayout>
-       </LinearLayout>
-
-    <fragment
-        android:id="@+id/weather_map_fragment_map"
-        android:name="com.google.android.gms.maps.MapFragment"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_below="@+id/weather_map_citycountry_container"
-        android:layout_above="@+id/weather_map_buttons_container" />
-
-    <LinearLayout
-        android:id="@+id/weather_map_buttons_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentStart="true"
-        android:orientation="horizontal"
-        android:baselineAligned="false" >
-    </LinearLayout>
-
-</RelativeLayout>
diff --git a/res/layout/weather_map_buttons.xml b/res/layout/weather_map_buttons.xml
deleted file mode 100644 (file)
index 4f81887..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:baselineAligned="false" >
-    
-       <LinearLayout
-               android:id="@+id/weather_map_button_savelocation_container"
-               android:layout_width="0dp"
-               android:layout_weight="1"
-               android:layout_gravity="center"
-               android:gravity="center"
-               android:layout_height="wrap_content">     
-               <Button
-                       android:id="@+id/weather_map_button_savelocation"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:layout_gravity="center"
-                       android:onClick="onClickSaveLocation"
-                       android:textAlignment="center"
-                       android:text="@string/weather_map_button_savelocation" />
-       </LinearLayout>
-       
-       <LinearLayout
-               android:id="@+id/weather_map_button_getlocation_container"
-               android:layout_width="0dp"
-               android:layout_weight="1"
-               android:layout_gravity="center"
-               android:gravity="center"
-               android:layout_height="wrap_content" >
-               <Button
-                       android:id="@+id/weather_map_button_getlocation"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:layout_gravity="center"
-                       android:onClick="onClickGetLocation"
-                       android:textAlignment="center"
-                       android:enabled="false"
-                       android:text="@string/weather_map_button_getlocation" />
-               </LinearLayout> 
-</LinearLayout>
diff --git a/res/layout/weather_map_progress.xml b/res/layout/weather_map_progress.xml
deleted file mode 100644 (file)
index b8eb00e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal" >
-    
-       <ProgressBar
-           android:id="@+id/weather_map_progressbar"
-           android:layout_width="0dp"
-           android:layout_height="wrap_content"
-           android:layout_gravity="center"
-           android:layout_weight="1"
-           android:indeterminateBehavior="repeat"
-           android:indeterminateDuration="3500"
-           android:indeterminateOnly="true"
-           android:visibility="visible" />
-    
-</LinearLayout>
diff --git a/res/layout/weather_specific.xml b/res/layout/weather_specific.xml
deleted file mode 100644 (file)
index 6147006..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/weather_specific"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:gravity="center"
-    android:orientation="vertical"
-    tools:context="de.example.exampletdd.SpecificActivity"
-    tools:ignore="MergeRootFrame" >
-
-
-     <fragment
-        android:id="@+id/specific_fragment"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        class="de.example.exampletdd.fragment.specific.SpecificFragment" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/weather_specific_fragment.xml b/res/layout/weather_specific_fragment.xml
deleted file mode 100644 (file)
index fd80c01..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/weather_specific_fragment"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent" >
-
-    <!-- TODO: align start/end humidity-rain wind-clouds -->
-    <LinearLayout
-        android:layout_width="match_parent"
-       android:layout_height="wrap_content"
-       android:gravity="center"
-       android:layout_gravity="fill_vertical|center_horizontal"
-       android:orientation="vertical" >
-       
-        <!-- TODO: http://developer.android.com/guide/topics/manifest/supports-screens-element.html -->
-       <!-- TODO: supporting multiple layouts/languages http://developer.android.com/guide/practices/screens_support.html -->
-       <!-- TODO: Should I use RelativeLayout for long texts (I18N) and RTL/LTR UI?
-                With long texts, many times, text will not fit... The same for WP8 :/ -->
-       <LinearLayout
-               android:layout_width="match_parent"
-               android:layout_height="match_parent"
-               android:gravity="center"
-               android:layout_gravity="top|center"
-               android:padding="50dp"
-               android:orientation="horizontal" >
-
-               <ImageView
-                               android:id="@+id/weather_specific_picture"
-                       android:layout_width="0dp"
-                       android:layout_weight="1"
-                       android:layout_height="wrap_content"
-                       android:contentDescription="@string/icon_weather_description"
-                       android:scaleType="fitCenter"
-                       android:gravity="center"
-                       android:layout_gravity="center"
-                       android:src="@drawable/weather_showers" />
-
-               <LinearLayout
-                       android:layout_width="0dp"
-                       android:layout_weight="1"
-                       android:layout_height="wrap_content"
-                       android:gravity="center"
-                       android:layout_gravity="center"
-                       android:orientation="vertical" >
-
-                       <TextView
-                           android:id="@+id/weather_specific_temp_max"
-                           android:layout_width="wrap_content"
-                           android:layout_height="wrap_content"
-                           android:paddingEnd="10dp"
-                           android:paddingStart="20dp"
-                           android:singleLine="true"
-                           android:text="55ºC"
-                           android:textAlignment="textStart"
-                           android:textAppearance="?android:attr/textAppearanceLarge"
-                           android:textStyle="bold" />
-
-                       <TextView
-                       android:id="@+id/weather_specific_temp_min"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:textAlignment="textStart"
-                       android:paddingEnd="10dp"
-                       android:paddingStart="20dp"
-                       android:singleLine="true"
-                       android:text="25ºC"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="normal" />
-               </LinearLayout>
-               </LinearLayout>
-       
-       <LinearLayout
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:gravity="center"
-               android:padding="25dp"
-               android:layout_gravity="top|center"
-               android:orientation="horizontal" >
-
-               <TextView
-                       android:id="@+id/weather_specific_description"
-                       android:layout_width="match_parent"
-                       android:layout_height="wrap_content"
-                       android:gravity="center"
-                       android:text="Light rain"
-                       android:textAppearance="?android:attr/textAppearanceLarge"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:textStyle="bold" />    
-               </LinearLayout>
-
-        <LinearLayout
-            android:baselineAligned="false"
-               android:layout_width="match_parent"
-                       android:layout_height="wrap_content"
-               android:layout_gravity="top|center"
-               android:orientation="horizontal" >
-                               
-            <LinearLayout
-                       android:layout_width="0dp"
-                       android:layout_weight="1"
-                               android:layout_height="wrap_content"
-                       android:gravity="center"
-                       android:layout_gravity="center"
-                       android:orientation="horizontal" >
-                       <!-- Humidity -->
-                       <TextView
-                       android:id="@+id/weather_specific_humidity"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:layout_gravity="start"
-                       android:layout_margin="5dp"
-                       android:gravity="start"
-                       android:text="@string/text_field_humidity"
-                       android:textAlignment="textStart"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:textStyle="bold" />
-        
-                       <!-- Humidity Value-->
-                       <TextView
-                       android:id="@+id/weather_specific_humidity_value"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="83"
-                       android:layout_gravity="start"
-                       android:gravity="start"
-                       android:textAlignment="textStart"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="normal" />
-        
-                       <!-- Humidity Units-->
-                       <TextView
-                       android:id="@+id/weather_specific_humidity_units"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="%"
-                       android:layout_gravity="start"
-                       android:gravity="start"
-                       android:textAlignment="textStart"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:layout_marginEnd="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="bold" />
-                       </LinearLayout>
-
-           <LinearLayout
-               android:layout_width="0dp"
-               android:layout_height="wrap_content"
-               android:gravity="center"
-                       android:layout_gravity="center"
-               android:layout_weight="1"
-               android:orientation="horizontal" >
-                <!-- Rain -->
-                       <TextView
-                       android:id="@+id/weather_specific_rain"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                               android:text="@string/text_field_rain"
-                       android:layout_gravity="end"
-                       android:gravity="end"
-                       android:textAlignment="textEnd"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                               android:layout_margin="5dp"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="bold" />
-          
-                       <!-- Rain Value-->
-                       <TextView
-                       android:id="@+id/weather_specific_rain_value"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="1.24"
-                       android:layout_gravity="end"
-                       android:gravity="end"
-                       android:textAlignment="textEnd"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="normal" />
-        
-                       <!-- Rain Units -->
-                       <TextView
-                       android:id="@+id/weather_specific_rain_units"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text=" mm 3h"
-                       android:layout_gravity="end"
-                       android:gravity="end"
-                       android:textAlignment="textEnd"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                               android:layout_marginEnd="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="bold" />
-               </LinearLayout>
-        </LinearLayout>
-    
-            
-        <LinearLayout
-            android:baselineAligned="false"
-               android:layout_width="match_parent"
-                       android:layout_height="wrap_content"
-               android:layout_gravity="top|center"
-               android:orientation="horizontal" >
-                               
-            <LinearLayout
-                       android:layout_width="0dp"
-                       android:layout_weight="1"
-                               android:layout_height="wrap_content"
-                       android:gravity="center"
-                       android:layout_gravity="center"
-                       android:orientation="horizontal" >
-                       
-                       <!-- Wind -->
-                       <TextView
-                       android:id="@+id/weather_specific_wind"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="@string/text_field_wind"
-                       android:layout_gravity="start"
-                       android:gravity="start"
-                       android:textAlignment="textStart"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:layout_margin="5dp"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="bold" />
-        
-                       <!-- Wind Value-->
-                       <TextView
-                       android:id="@+id/weather_specific_wind_value"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                               android:text="6.36"
-                       android:layout_gravity="start"
-                       android:gravity="start"
-                       android:textAlignment="textStart"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="normal" />
-        
-                       <!-- Wind Units -->
-                       <TextView
-                       android:id="@+id/weather_specific_wind_units"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text=" m/s"
-                       android:layout_gravity="start"
-                       android:gravity="start"
-                       android:textAlignment="textStart"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:layout_marginEnd="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="bold" />
-                       </LinearLayout>
-
-           <LinearLayout
-               android:layout_width="0dp"
-               android:layout_height="wrap_content"
-               android:gravity="center"
-                       android:layout_gravity="center"
-               android:layout_weight="1"
-               android:orientation="horizontal" >                      
-                <!-- Clouds -->
-                       <TextView
-                       android:id="@+id/weather_specific_clouds"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="@string/text_field_clouds"
-                       android:layout_gravity="end"
-                       android:gravity="end"
-                       android:textAlignment="textEnd"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:layout_margin="5dp"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="bold" />
-        
-                       <!-- Clouds Value-->
-                       <TextView
-                       android:id="@+id/weather_specific_clouds_value"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="6.36"
-                       android:layout_gravity="end"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:gravity="end"
-                       android:textAlignment="textEnd"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="normal" />
-        
-                       <!-- Clouds Units -->
-                       <TextView
-                       android:id="@+id/weather_specific_clouds_units"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="%"
-                       android:layout_gravity="end"
-                       android:gravity="end"
-                       android:textAlignment="textEnd"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:layout_marginEnd="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="bold" />
-                       </LinearLayout>
-               </LinearLayout>
-        <LinearLayout
-                       android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:layout_gravity="top|center"
-               android:orientation="horizontal" >
-        
-                       <!-- Pressure -->
-                       <TextView
-                       android:id="@+id/weather_specific_pressure"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="@string/text_field_pressure"
-                       android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:textColor="@color/weather_time_of_day_color_title"
-                       android:layout_margin="5dp"
-                       android:textAppearance="?android:attr/textAppearanceMedium"
-                       android:textStyle="bold" />
-        
-                       <!-- Pressure Value-->
-                       <TextView
-                       android:id="@+id/weather_specific_pressure_value"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text="1036.05"
-                       android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="normal" />
-        
-                       <!-- Pressure Units-->
-                       <TextView
-                       android:id="@+id/weather_specific_pressure_units"
-                       android:layout_width="wrap_content"
-                       android:layout_height="wrap_content"
-                       android:text=" hpa"
-                               android:layout_gravity="center"
-                       android:gravity="center"
-                       android:textAlignment="center"
-                       android:layout_marginTop="5dp"
-                       android:layout_marginBottom="5dp"
-                       android:layout_marginEnd="5dp"
-                       android:textAppearance="?android:attr/textAppearanceSmall"
-                       android:textStyle="bold" />
-        </LinearLayout>
-        
-        <HorizontalScrollView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="bottom|start"
-            android:layout_margin="10dp"
-            android:fadingEdge="none"
-            android:scrollbars="horizontal|none" >
-                       
-               <LinearLayout
-                   android:layout_width="wrap_content"
-                   android:layout_height="wrap_content"
-                   android:layout_gravity="center"
-                   android:fadingEdge="none"
-                   android:orientation="horizontal"
-                   android:scrollbarAlwaysDrawVerticalTrack="false"
-                   android:scrollbars="none" >
-
-                               <LinearLayout
-                                       android:layout_width="wrap_content"
-                                       android:layout_height="wrap_content"
-                                       android:paddingStart="20dp"
-                                       android:paddingEnd="20dp"
-                                       android:orientation="vertical" >
-                       
-                                       <!-- Time of day -->
-                                       <TextView
-                                       android:id="@+id/weather_specific_morn"
-                                               android:layout_width="wrap_content"
-                                               android:layout_height="wrap_content"
-                                       android:text="MORNING"
-                                       android:textColor="@color/weather_time_of_day_color_title"
-                                       android:textAlignment="center"
-                                       android:layout_gravity="top|center"
-                                       android:textAppearance="?android:attr/textAppearanceMedium" />
-                               
-                                       <!-- Temperature -->
-                                       <TextView
-                                               android:id="@+id/weather_specific_morn_temperature"
-                                               android:layout_width="wrap_content"
-                                               android:layout_height="wrap_content"
-                                       android:text="55ºC"
-                                       android:textAlignment="center"
-                                       android:layout_gravity="bottom|center"
-                                       android:textAppearance="?android:attr/textAppearanceMedium"
-                                       android:textStyle="bold" />
-                               </LinearLayout>
-                               <LinearLayout
-                                       android:layout_width="wrap_content"
-                                       android:layout_height="wrap_content"
-                                       android:orientation="vertical" >
-                               
-                                       <!-- Time of day -->
-                                       <TextView
-                                       android:id="@+id/weather_specific_day"
-                                               android:layout_width="wrap_content"
-                                               android:layout_height="wrap_content"
-                                       android:text="DAY"
-                                       android:textColor="@color/weather_time_of_day_color_title"
-                                       android:textAlignment="center"
-                                       android:layout_gravity="top|center"
-                                       android:textAppearance="?android:attr/textAppearanceMedium" />
-                               
-                                       <!-- Temperature -->
-                                       <TextView
-                                               android:id="@+id/weather_specific_day_temperature"
-                                               android:layout_width="wrap_content"
-                                               android:layout_height="wrap_content"
-                                       android:text="55ºC"
-                                       android:textAlignment="center"
-                                       android:layout_gravity="bottom|center"
-                                       android:textAppearance="?android:attr/textAppearanceMedium"
-                                       android:textStyle="bold" />
-                               </LinearLayout>
-                               <LinearLayout
-                                       android:layout_width="wrap_content"
-                                       android:layout_height="wrap_content"
-                                       android:paddingStart="20dp"
-                                       android:paddingEnd="20dp"
-                                       android:orientation="vertical" >
-                       
-                                       <!-- Time of day -->
-                                       <TextView
-                                       android:id="@+id/weather_specific_eve"
-                                               android:layout_width="wrap_content"
-                                               android:layout_height="wrap_content"
-                                       android:text="EVENING"
-                                       android:textColor="@color/weather_time_of_day_color_title"
-                                       android:textAlignment="center"
-                                       android:layout_gravity="top|center"
-                                       android:textAppearance="?android:attr/textAppearanceMedium" />
-                               
-                                       <!-- Temperature -->
-                                       <TextView
-                                               android:id="@+id/weather_specific_eve_temperature"
-                                               android:layout_width="wrap_content"
-                                               android:layout_height="wrap_content"
-                                       android:text="55ºC"
-                                       android:textAlignment="center"
-                                       android:layout_gravity="bottom|center"
-                                       android:textAppearance="?android:attr/textAppearanceMedium"
-                                       android:textStyle="bold" />
-                               </LinearLayout>
-                               <LinearLayout
-                                       android:layout_width="wrap_content"
-                                       android:layout_height="wrap_content"
-                                       android:paddingStart="20dp"
-                                       android:paddingEnd="20dp"
-                                       android:orientation="vertical" >
-                       
-                                       <!-- Time of day -->
-                                       <TextView
-                                       android:id="@+id/weather_specific_night"
-                                               android:layout_width="wrap_content"
-                                               android:layout_height="wrap_content"
-                                       android:text="NIGHT"
-                                       android:textColor="@color/weather_time_of_day_color_title"
-                                       android:textAlignment="center"
-                                       android:layout_gravity="top|center"
-                                       android:textAppearance="?android:attr/textAppearanceMedium" />
-                               
-                                       <!-- Temperature -->
-                                       <TextView
-                                               android:id="@+id/weather_specific_night_temperature"
-                                               android:layout_width="wrap_content"
-                                               android:layout_height="wrap_content"
-                                       android:text="55ºC"
-                                       android:textAlignment="center"
-                                       android:layout_gravity="bottom|center"
-                                       android:textAppearance="?android:attr/textAppearanceMedium"
-                                       android:textStyle="bold" />
-                               </LinearLayout>
-                       </LinearLayout>
-               </HorizontalScrollView>
-       </LinearLayout>
-</ScrollView>
diff --git a/res/menu/main.xml b/res/menu/main.xml
deleted file mode 100644 (file)
index 5d21935..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context="de.example.exampletdd.MainActivity" >
-
-    <item
-        android:id="@+id/action_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never"
-        android:title="@string/weather_preferences_action_settings"/>
-
-</menu>
diff --git a/res/menu/weather_main_menu.xml b/res/menu/weather_main_menu.xml
deleted file mode 100644 (file)
index f3f36c8..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
-    
-    
-    <item
-        android:id="@+id/weather_menu_settings"
-        android:menuCategory="system"
-        android:title="@string/weather_preferences_action_settings"
-        android:titleCondensed="@string/weather_preferences_action_settings"
-        android:checked="false"
-        android:visible="true"
-        android:checkable="false"
-        android:enabled="true"
-        android:icon="@drawable/ic_action_settings"
-        android:showAsAction="ifRoom">
-    </item>
-    <item
-        android:id="@+id/weather_menu_map"
-        android:icon="@drawable/ic_action_map"
-        android:showAsAction="ifRoom"
-        android:visible="true"
-        android:checkable="false"
-        android:enabled="true"
-        android:checked="false"
-        android:title="@string/weather_map_action_map"
-        android:titleCondensed="@string/weather_map_action_map">
-    </item>
-    
-
-</menu>
diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml
deleted file mode 100644 (file)
index 4460dcf..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<resources>
-
-    <!--
-        Base application theme for API 11+. This theme completely replaces
-        AppBaseTheme from res/values/styles.xml on API 11+ devices.
-    -->
-    <style name="AppBaseTheme" parent="android:Theme.Holo">
-        <!-- API 11 theme customizations can go here. -->
-    </style>
-
-</resources>
diff --git a/res/values-v14/dimens.xml b/res/values-v14/dimens.xml
deleted file mode 100644 (file)
index 94bb2e6..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<resources>
-
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-    <dimen name="widget_margin">0dp</dimen>
-</resources>
diff --git a/res/values-v14/styles.xml b/res/values-v14/styles.xml
deleted file mode 100644 (file)
index 3e61a52..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<resources>
-
-    <!--
-        Base application theme for API 14+. This theme completely replaces
-        AppBaseTheme from BOTH res/values/styles.xml and
-        res/values-v11/styles.xml on API 14+ devices.
-    -->
-    <style name="AppBaseTheme" parent="android:Theme.Holo">
-        <!-- API 14 theme customizations can go here. -->
-    </style>
-
-</resources>
diff --git a/res/values-w820dp/dimens.xml b/res/values-w820dp/dimens.xml
deleted file mode 100644 (file)
index f3e7020..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<resources>
-
-    <!--
-         Example customization of dimensions originally defined in res/values/dimens.xml
-         (such as screen margins) for screens with more than 820dp of available width. This
-         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
-    -->
-    <dimen name="activity_horizontal_margin">64dp</dimen>
-
-</resources>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
deleted file mode 100644 (file)
index 2de335e..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string-array name="weather_preferences_day_forecast">
-        <item>5</item>
-        <item>10</item>
-        <item>14</item>
-    </string-array>
-    <string-array name="weather_preferences_day_forecast_human_value">
-        <item>5 day forecast</item>
-        <item>10 day forecast</item>
-        <item>14 day forecast</item>
-    </string-array>
-    <string-array name="weather_preferences_update_time_rate">
-        <item>900</item>
-        <item>1800</item>
-        <item>3600</item>       
-        <item>43200</item>
-        <item>86400</item>    
-    </string-array>
-    <string-array name="weather_preferences_update_time_rate_human_value">
-        <item>fifteen minutes</item>
-        <item>half hour</item>
-        <item>one hour</item>   
-        <item>half day</item>
-        <item>one day</item>     
-    </string-array>
-    <string-array name="weather_preferences_refresh_interval">
-        <item>300000</item>
-        <item>900000</item>
-        <item>1800000</item>
-        <item>3600000</item>
-        <item>7200000</item>
-        <item>43200000</item>
-        <item>86400000</item>
-    </string-array>
-    <string-array name="weather_preferences_refresh_interval_human_value">
-        <item>five minutes</item>
-        <item>fifteen minutes</item>
-        <item>half hour</item>
-        <item>one hour</item>
-        <item>two hours</item>
-        <item>half day</item>
-        <item>one day</item>
-    </string-array>
-    <string-array name="weather_preferences_temperature">
-        <item>@string/weather_preferences_temperature_celsius</item>
-        <item>@string/weather_preferences_temperature_fahrenheit</item>
-        <item>@string/weather_preferences_temperature_kelvin</item>
-    </string-array>
-    <string-array name="weather_preferences_temperature_human_value">
-        <item>@string/weather_preferences_temperature_celsius_human_value</item>
-        <item>@string/weather_preferences_temperature_fahrenheit_human_value</item>
-        <item>@string/weather_preferences_temperature_kelvin_human_value</item>
-    </string-array>
-    <string-array name="weather_preferences_wind">
-        <item>@string/weather_preferences_wind_meters</item>
-        <item>@string/weather_preferences_wind_miles</item>
-    </string-array>
-    <string-array name="weather_preferences_wind_human_value">
-        <item>@string/weather_preferences_wind_human_value_meters</item>
-        <item>@string/weather_preferences_wind_human_value_miles</item>
-    </string-array>
-    <string-array name="weather_preferences_pressure">
-        <item>@string/weather_preferences_pressure_pascal</item>
-        <item>@string/weather_preferences_pressure_standard_atm</item>
-    </string-array>
-    <string-array name="weather_preferences_pressure_human_value">
-        <item>@string/weather_preferences_pressure_human_value_pascal</item>
-        <item>@string/weather_preferences_pressure_human_value_standard_atm</item>
-    </string-array>
-</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
deleted file mode 100644 (file)
index 063ada2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<resources>
-
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-    <dimen name="widget_margin">8dp</dimen>
-</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
deleted file mode 100644 (file)
index dea5420..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <string name="app_name">Weather Information</string>
-    <string name="icon_weather_description">Icon weather</string> 
-
-
-    <!-- Activities Current, Overview and Specific -->
-    <string name="text_field_sun_rise">SUN RISE</string>
-    <string name="text_field_sun_set">SUN SET</string>
-    <string name="text_field_feels_like">FEELS LIKE</string>
-    <string name="text_field_clouds">CLOUDS</string>
-    <string name="text_field_rain">RAIN</string>
-    <string name="text_field_wind">WIND</string>
-    <string name="text_field_snow">SNOW</string>
-    <string name="text_field_pressure">PRESSURE</string>
-    <string name="text_field_humidity">HUMIDITY</string>
-    <string name="text_units_mm3h">mm 3h</string>
-    <string name="text_units_percent">%</string>
-    <string name="text_field_remote_error">No data available</string>
-
-
-    <!-- Preferences Acitivity -->
-    <string name="weather_preferences_action_settings">Settings</string>
-    <string name="weather_preferences_units">Units</string>
-    <string name="weather_preferences_temperature_key">weather_preferences_temperature</string>
-    <string name="weather_preferences_temperature">Temperature</string>
-    <string name="weather_preferences_temperature_celsius">ºC</string>
-    <string name="weather_preferences_temperature_fahrenheit">ºF</string>
-    <string name="weather_preferences_temperature_kelvin">K</string>
-    <string name="weather_preferences_temperature_celsius_human_value">celsius</string>
-    <string name="weather_preferences_temperature_fahrenheit_human_value">fahrenheit</string>
-    <string name="weather_preferences_temperature_kelvin_human_value">kelvin</string>
-    <string name="weather_preferences_notifications">Notifications</string>
-    <string name="weather_preferences_notifications_switch_off_summary">Disabled</string>
-    <string name="weather_preferences_notifications_switch_on_summary">Enabled</string>
-    <string name="weather_preferences_notifications_switch_off">OFF</string>
-    <string name="weather_preferences_notifications_switch_on">ON</string>
-    <string name="weather_preferences_notifications_switch_key">weather_preferences_notifications_switch</string>
-    <string name="weather_preferences_update_time_rate_key">weather_preferences_update_time_rate</string>
-    <string name="weather_preferences_update_time_rate">Update time rate</string>
-    <string name="weather_preferences_day_forecast_key">weather_preferences_day_forecast</string>
-    <string name="weather_preferences_day_forecast">Forecast days number</string>
-    <string name="weather_preferences_refresh_interval_key">weather_preferences_refresh_interval</string>
-    <string name="weather_preferences_refresh_interval">Refresh interval</string>
-    <string name="weather_preferences_wind_key">weather_preferences_wind</string>
-    <string name="weather_preferences_wind">Wind</string>
-    <string name="weather_preferences_wind_meters">m/s</string>
-    <string name="weather_preferences_wind_miles">mph</string>
-    <string name="weather_preferences_wind_human_value_meters">meter per second</string>
-    <string name="weather_preferences_wind_human_value_miles">miles per hour</string>
-    <string name="weather_preferences_pressure_key">weather_preferences_pressure</string>
-    <string name="weather_preferences_pressure">Pressure</string>
-    <string name="weather_preferences_pressure_pascal">hpa</string>
-    <string name="weather_preferences_pressure_standard_atm">atm</string>
-    <string name="weather_preferences_pressure_human_value_pascal">pascal</string>
-    <string name="weather_preferences_pressure_human_value_standard_atm">standard atmosphere</string>
-
-
-    <!-- Widget Preferences Activity -->
-    <string name="widget_preferences_action_settings">Settings</string>
-    <string name="widget_preferences_button_refresh">Refresh</string>
-    <string name="widget_preferences_country">Country</string>
-    <string name="widget_preferences_units">Units</string>
-    <string name="widget_preferences_temperature_key">widget_preferences_temperature</string>
-    <string name="widget_preferences_country_switch_key">widget_preferences_countries_switch</string>
-    <string name="widget_preferences_country_switch_off_summary">Hide</string>
-    <string name="widget_preferences_country_switch_on_summary">Show</string>
-    <string name="widget_preferences_country_switch_off">OFF</string>
-    <string name="widget_preferences_country_switch_on">ON</string>
-
-
-    <!-- Map Activity -->
-    <string name="weather_map_action_map">Select Location</string>
-    <string name="city_not_found">city not found</string>
-    <string name="country_not_found">country not found</string>
-    <string name="progress_dialog_generic_message">Please wait&#8230;</string>
-    <string name="weather_map_button_savelocation">Save Location</string>
-       <string name="weather_map_button_getlocation">Get Location</string>
-       
-       
-       <!-- DO NOT TRANSLATE -->
-       <string name="uri_api_weather_today">http://api.openweathermap.org/data/{0}/weather?lat={1}&amp;lon={2}&amp;cnt=1</string>
-    <string name="uri_api_weather_forecast">http://api.openweathermap.org/data/{0}/forecast/daily?lat={1}&amp;lon={2}&amp;cnt={3}&amp;mode=json</string>
-    <string name="api_version">2.5</string>
-</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
deleted file mode 100644 (file)
index 034465a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<resources>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="android:Theme.Holo">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="android:Theme.Holo">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-    
-
-    <color name="weather_time_of_day_color_title">#48aed4</color>
-    <color name="widget_background_holo_dark">#ff000000</color>
-
-</resources>
diff --git a/res/xml/appwidget_preferences.xml b/res/xml/appwidget_preferences.xml
deleted file mode 100644 (file)
index db489da..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
-    <PreferenceCategory android:title="@string/widget_preferences_country">
-        <SwitchPreference android:key="@string/widget_preferences_country_switch_key"
-            android:summaryOn="@string/widget_preferences_country_switch_on_summary"
-            android:summaryOff="@string/widget_preferences_country_switch_off_summary"
-            android:switchTextOff="@string/widget_preferences_country_switch_off"
-            android:switchTextOn="@string/widget_preferences_country_switch_on"
-            android:selectable="true"
-            android:enabled="true"
-            android:defaultValue="@string/widget_preferences_country_switch_off"
-            android:disableDependentsState="false"
-            android:persistent="true"/>
-    </PreferenceCategory>
-    <PreferenceCategory android:title="@string/widget_preferences_units">
-        <ListPreference android:key="@string/widget_preferences_temperature_key"
-            android:title="@string/weather_preferences_temperature"
-            android:summary="@string/weather_preferences_temperature_celsius_human_value"
-            android:entries="@array/weather_preferences_temperature_human_value"
-            android:entryValues="@array/weather_preferences_temperature"
-            android:selectable="true"
-            android:persistent="true"
-            android:defaultValue="@string/weather_preferences_temperature_celsius" />
-    </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/res/xml/appwidget_provider.xml b/res/xml/appwidget_provider.xml
deleted file mode 100644 (file)
index 155242e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
-    android:minWidth="180dp"
-    android:minHeight="40dp"
-    android:minResizeWidth="180dp"
-    android:minResizeHeight="40dp"
-    android:resizeMode="none"
-    android:previewImage="@drawable/ic_launcher"
-    android:initialLayout="@layout/appwidget_error"
-    android:configure="de.example.exampletdd.widget.WidgetConfigure" 
-    android:widgetCategory="home_screen|keyguard"
-    android:updatePeriodMillis="3600000">
-</appwidget-provider>
diff --git a/res/xml/weather_preferences.xml b/res/xml/weather_preferences.xml
deleted file mode 100644 (file)
index baaa006..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
-    <ListPreference android:key="@string/weather_preferences_day_forecast_key"
-        android:title="@string/weather_preferences_day_forecast"
-        android:entries="@array/weather_preferences_day_forecast_human_value"
-        android:entryValues="@array/weather_preferences_day_forecast"
-        android:selectable="true"
-        android:persistent="true"
-        android:defaultValue="14"
-        android:summary="14 day forecast" />
-    <ListPreference android:key="@string/weather_preferences_refresh_interval_key"
-        android:title="@string/weather_preferences_refresh_interval"
-        android:entries="@array/weather_preferences_refresh_interval_human_value"
-        android:entryValues="@array/weather_preferences_refresh_interval"
-        android:selectable="true"
-        android:persistent="true"
-        android:defaultValue="300000"
-        android:summary="five minutes" />
-    <PreferenceCategory android:title="@string/weather_preferences_units">
-        <ListPreference android:key="@string/weather_preferences_temperature_key"
-            android:title="@string/weather_preferences_temperature"
-            android:summary="@string/weather_preferences_temperature_celsius_human_value"
-            android:entries="@array/weather_preferences_temperature_human_value"
-            android:entryValues="@array/weather_preferences_temperature"
-            android:selectable="true"
-            android:persistent="true"
-            android:defaultValue="@string/weather_preferences_temperature_celsius" />
-        <ListPreference android:key="@string/weather_preferences_wind_key"
-            android:entryValues="@array/weather_preferences_wind"
-            android:entries="@array/weather_preferences_wind_human_value"
-            android:summary="@string/weather_preferences_wind_human_value_meters"
-            android:selectable="true"
-            android:persistent="true"
-            android:defaultValue="@string/weather_preferences_wind_meters"
-            android:title="@string/weather_preferences_wind"/>
-        <ListPreference android:key="@string/weather_preferences_pressure_key"
-            android:entryValues="@array/weather_preferences_pressure"
-            android:entries="@array/weather_preferences_pressure_human_value"
-            android:summary="@string/weather_preferences_pressure_human_value_pascal"
-            android:selectable="true"
-            android:persistent="true"
-            android:defaultValue="@string/weather_preferences_pressure_pascal"
-            android:title="@string/weather_preferences_pressure"/>
-    </PreferenceCategory>
-    <PreferenceCategory android:title="@string/weather_preferences_notifications">
-        <SwitchPreference android:key="@string/weather_preferences_notifications_switch_key"
-            android:summaryOn="@string/weather_preferences_notifications_switch_on_summary"
-            android:summaryOff="@string/weather_preferences_notifications_switch_off_summary"
-            android:switchTextOff="@string/weather_preferences_notifications_switch_off"
-            android:switchTextOn="@string/weather_preferences_notifications_switch_on"
-            android:selectable="true"
-            android:enabled="true"
-            android:defaultValue="@string/weather_preferences_notifications_switch_off"
-            android:disableDependentsState="false"
-            android:persistent="true"/>
-        <ListPreference android:key="@string/weather_preferences_update_time_rate_key"
-               android:entries="@array/weather_preferences_update_time_rate_human_value"
-               android:entryValues="@array/weather_preferences_update_time_rate"
-               android:title="@string/weather_preferences_update_time_rate"
-               android:defaultValue="900"
-               android:persistent="true"
-               android:selectable="true"
-               android:summary="fifteen minutes"
-               android:dependency="@string/weather_preferences_notifications_switch_key"/>
-    </PreferenceCategory>
-</PreferenceScreen>
diff --git a/settings.gradle b/settings.gradle
new file mode 100644 (file)
index 0000000..e7b4def
--- /dev/null
@@ -0,0 +1 @@
+include ':app'
diff --git a/src/de/example/exampletdd/MapActivity.java b/src/de/example/exampletdd/MapActivity.java
deleted file mode 100644 (file)
index 01a3c41..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-package de.example.exampletdd;
-
-import android.app.ActionBar;
-import android.content.Context;
-import android.location.Criteria;
-import android.location.Geocoder;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.view.View;
-import android.widget.Button;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.google.android.gms.maps.CameraUpdateFactory;
-import com.google.android.gms.maps.GoogleMap;
-import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
-import com.google.android.gms.maps.MapFragment;
-import com.google.android.gms.maps.model.LatLng;
-import com.google.android.gms.maps.model.Marker;
-import com.google.android.gms.maps.model.MarkerOptions;
-
-import de.example.exampletdd.fragment.map.MapButtonsFragment;
-import de.example.exampletdd.fragment.map.MapProgressFragment;
-import de.example.exampletdd.model.DatabaseQueries;
-import de.example.exampletdd.model.WeatherLocation;
-
-public class MapActivity extends FragmentActivity implements
-                                                                       LocationListener,
-                                                                       MapProgressFragment.TaskCallbacks {
-    private static final String PROGRESS_FRAGMENT_TAG = "PROGRESS_FRAGMENT";
-    private static final String BUTTONS_FRAGMENT_TAG = "BUTTONS_FRAGMENT";
-    private WeatherLocation mRestoreUI;
-       
-    // Google Play Services Map
-    private GoogleMap mMap;
-    // TODO: read and store from different threads? Hopefully always from UI thread.
-    private Marker mMarker;
-    
-    private LocationManager mLocationManager;
-
-    @Override
-    protected void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        this.setContentView(R.layout.weather_map);
-        
-        // Acquire a reference to the system Location Manager
-        this.mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
-        
-        // Google Play Services Map
-        final MapFragment mapFragment = (MapFragment) this.getFragmentManager()
-                .findFragmentById(R.id.weather_map_fragment_map);
-        this.mMap = mapFragment.getMap();
-        this.mMap.setMyLocationEnabled(false);
-        this.mMap.getUiSettings().setMyLocationButtonEnabled(false);
-        this.mMap.getUiSettings().setZoomControlsEnabled(true);
-        this.mMap.getUiSettings().setCompassEnabled(true);
-        this.mMap.setOnMapLongClickListener(new MapActivityOnMapLongClickListener(this));
-    }
-    
-    @Override
-    protected void onRestoreInstanceState(final Bundle savedInstanceState) {
-       // Instead of restoring the state during onCreate() you may choose to
-       // implement onRestoreInstanceState(), which the system calls after the
-       // onStart() method. The system calls onRestoreInstanceState() only if
-       // there is a saved state to restore, so you do not need to check whether
-       // the Bundle is null:
-        super.onRestoreInstanceState(savedInstanceState);
-        
-        // Restore UI state
-        this.mRestoreUI = (WeatherLocation) savedInstanceState.getSerializable("WeatherLocation");
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        final ActionBar actionBar = this.getActionBar();
-        // TODO: string resource
-        actionBar.setTitle("Mark your location");
-        
-        WeatherLocation weatherLocation;
-        if (this.mRestoreUI != null) {
-               // Restore UI state
-               weatherLocation = this.mRestoreUI;
-               // just once
-               this.mRestoreUI = null;
-        } else if (this.mMarker != null ) {
-               final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
-            final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
-            final String cityString = city.getText().toString();
-            final String countryString = country.getText().toString();
-            
-            final LatLng point = this.mMarker.getPosition();
-            double latitude = point.latitude;
-            double longitude = point.longitude;
-
-            weatherLocation = new WeatherLocation()
-                       .setCity(cityString)
-                       .setCountry(countryString)
-                       .setLatitude(latitude)
-                       .setLongitude(longitude);
-       } else {
-               final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
-               weatherLocation = query.queryDataBase();
-        }
-        
-        if (weatherLocation != null) {
-               this.updateUI(weatherLocation);
-        }
-    }
-    
-    /**
-     * I am not using fragment transactions in the right way. But I do not know other way for doing what I am doing.
-     * 
-     * {@link http://stackoverflow.com/questions/16265733/failure-delivering-result-onactivityforresult}
-     */
-    @Override
-    public void onPostResume() {
-       super.onPostResume();
-       
-       final FragmentManager fm = getSupportFragmentManager();
-       final Fragment progressFragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
-       if (progressFragment == null) {
-                this.addButtonsFragment();
-       } else {
-               this.removeProgressFragment();
-               final Bundle bundle = progressFragment.getArguments();
-               double latitude = bundle.getDouble("latitude");
-               double longitude = bundle.getDouble("longitude");
-               this.addProgressFragment(latitude, longitude);
-       }
-    }
-    
-    @Override
-    public void onSaveInstanceState(final Bundle savedInstanceState) {
-       // Save UI state
-       // Save Google Maps Marker
-       if (this.mMarker != null) {
-               final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
-            final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
-            final String cityString = city.getText().toString();
-            final String countryString = country.getText().toString();
-            
-            final LatLng point = this.mMarker.getPosition();
-            double latitude = point.latitude;
-            double longitude = point.longitude;
-
-            final WeatherLocation location = new WeatherLocation()
-                       .setCity(cityString)
-                       .setCountry(countryString)
-                       .setLatitude(latitude)
-                       .setLongitude(longitude);
-            savedInstanceState.putSerializable("WeatherLocation", location);
-        }
-               
-       super.onSaveInstanceState(savedInstanceState);
-    }
-    
-       @Override
-       public void onPause() {
-               super.onPause();
-               
-               this.mLocationManager.removeUpdates(this);
-       }
-       
-    public void onClickSaveLocation(final View v) {
-       if (this.mMarker != null) {
-               final LatLng position = this.mMarker.getPosition();
-               
-               final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
-            final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
-            final String cityString = city.getText().toString();
-            final String countryString = country.getText().toString();
-            
-               final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
-               final WeatherLocation weatherLocation = query.queryDataBase();
-            if (weatherLocation != null) {
-               weatherLocation
-               .setCity(cityString)
-               .setCountry(countryString)
-               .setLatitude(position.latitude)
-               .setLongitude(position.longitude)
-               .setLastCurrentUIUpdate(null)
-               .setLastForecastUIUpdate(null);
-               query.updateDataBase(weatherLocation);
-            } else {
-               final WeatherLocation location = new WeatherLocation()
-                       .setCity(cityString)
-                       .setCountry(countryString)
-                       .setIsSelected(true)
-                       .setLatitude(position.latitude)
-                       .setLongitude(position.longitude);
-               query.insertIntoDataBase(location);
-            }
-       }
-    }
-    
-    public void onClickGetLocation(final View v) {
-       // TODO: Somehow I should show a progress dialog.
-        // If Google Play Services is available
-        if (this.mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
-               // TODO: Hopefully there will be results even if location did not change...   
-            final Criteria criteria = new Criteria();
-            criteria.setAccuracy(Criteria.ACCURACY_FINE);
-            criteria.setAltitudeRequired(false);
-            criteria.setBearingAccuracy(Criteria.NO_REQUIREMENT);
-            criteria.setBearingRequired(false);
-            criteria.setCostAllowed(false);
-            criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
-            criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
-            criteria.setSpeedAccuracy(Criteria.NO_REQUIREMENT);
-            criteria.setSpeedRequired(false);
-            criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH);
-            
-            this.mLocationManager.requestSingleUpdate(criteria, this, null);
-        } else {
-               // TODO: string resource
-               Toast.makeText(this, "You do not have enabled location.", Toast.LENGTH_LONG).show();
-        }
-        // Trying to use the synchronous calls. Problems: mGoogleApiClient read/store from different threads.
-        // new GetLocationTask(this).execute();
-    }
-    
-    private void updateUI(final WeatherLocation weatherLocation) {
-
-        final TextView city = (TextView) this.findViewById(R.id.weather_map_city);
-        final TextView country = (TextView) this.findViewById(R.id.weather_map_country);
-        city.setText(weatherLocation.getCity());
-        country.setText(weatherLocation.getCountry());
-
-        final LatLng point = new LatLng(weatherLocation.getLatitude(), weatherLocation.getLongitude());
-        if (this.mMarker != null) {
-               // Just one marker on map
-               this.mMarker.remove();
-        }
-        this.mMarker = this.mMap.addMarker(new MarkerOptions().position(point).draggable(true));
-        this.mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(point, 5));
-        this.mMap.animateCamera(CameraUpdateFactory.zoomIn());
-        this.mMap.animateCamera(CameraUpdateFactory.zoomTo(8), 2000, null);
-    }
-    
-    private class MapActivityOnMapLongClickListener implements OnMapLongClickListener {
-       // Store the context passed to the AsyncTask when the system instantiates it.
-        private final Context localContext;
-        
-       private MapActivityOnMapLongClickListener(final Context context) {
-               this.localContext = context;
-       }
-       
-               @Override
-               public void onMapLongClick(final LatLng point) {
-                       final MapActivity activity = (MapActivity) this.localContext;
-                       activity.getAddressAndUpdateUI(point.latitude, point.longitude);
-               }
-       
-    }
-
-    /**
-     * Getting the address of the current location, using reverse geocoding only works if
-     * a geocoding service is available.
-     *
-     */
-    private void getAddressAndUpdateUI(final double latitude, final double longitude) {
-        // In Gingerbread and later, use Geocoder.isPresent() to see if a geocoder is available.
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && Geocoder.isPresent()) {
-               this.removeButtonsFragment();
-               this.removeProgressFragment();
-               this.addProgressFragment(latitude, longitude);
-        } else {
-               this.removeProgressFragment();
-               this.addButtonsFragment();
-               // No geocoder is present. Issue an error message.
-               // TODO: string resource
-            Toast.makeText(this, "Cannot get address. No geocoder available.", Toast.LENGTH_LONG).show();
-            
-            // Default values
-            final String city = this.getString(R.string.city_not_found);
-            final String country = this.getString(R.string.country_not_found); 
-            final WeatherLocation weatherLocation = new WeatherLocation()
-                       .setLatitude(latitude)
-                       .setLongitude(longitude)
-                       .setCity(city)
-                       .setCountry(country);
-            
-            updateUI(weatherLocation);
-        }
-    }
-
-       /*****************************************************************************************************
-        *
-        *                                                      MapProgressFragment.TaskCallbacks
-        *
-        *****************************************************************************************************/
-       @Override
-       public void onPostExecute(WeatherLocation weatherLocation) {
-
-        this.updateUI(weatherLocation);
-        this.removeProgressFragment();
-
-        this.addButtonsFragment();
-       }
-
-       /*****************************************************************************************************
-        *
-        *                                                      MapProgressFragment
-        * I am not using fragment transactions in the right way. But I do not know other way for doing what I am doing.
-     * Android sucks.
-     *
-     * "Avoid performing transactions inside asynchronous callback methods." :(
-     * see: http://stackoverflow.com/questions/16265733/failure-delivering-result-onactivityforresult
-     * see: http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html
-     * How do you do what I am doing in a different way without using fragments?
-        *****************************************************************************************************/
-       
-       private void addProgressFragment(final double latitude, final double longitude) {
-       final Fragment progressFragment = new MapProgressFragment();
-       progressFragment.setRetainInstance(true);
-       final Bundle args = new Bundle();
-       args.putDouble("latitude", latitude);
-       args.putDouble("longitude", longitude);
-       progressFragment.setArguments(args);
-       
-       final FragmentManager fm = this.getSupportFragmentManager();
-       final FragmentTransaction fragmentTransaction = fm.beginTransaction();
-       fragmentTransaction.setCustomAnimations(R.anim.weather_map_enter_progress, R.anim.weather_map_exit_progress);
-       fragmentTransaction.add(R.id.weather_map_buttons_container, progressFragment, PROGRESS_FRAGMENT_TAG).commit();
-       fm.executePendingTransactions();
-       }
-       
-       private void removeProgressFragment() {
-       final FragmentManager fm = this.getSupportFragmentManager();
-       final Fragment progressFragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
-       if (progressFragment != null) {
-               final FragmentTransaction fragmentTransaction = fm.beginTransaction();
-               fragmentTransaction.remove(progressFragment).commit();
-               fm.executePendingTransactions();
-       }
-       }
-       
-       private void addButtonsFragment() {
-               final FragmentManager fm = this.getSupportFragmentManager();
-       Fragment buttonsFragment = fm.findFragmentByTag(BUTTONS_FRAGMENT_TAG);
-       if (buttonsFragment == null) {
-               buttonsFragment = new MapButtonsFragment();
-               buttonsFragment.setRetainInstance(true);
-               final FragmentTransaction fragmentTransaction = fm.beginTransaction();
-               fragmentTransaction.setCustomAnimations(R.anim.weather_map_enter_progress, R.anim.weather_map_exit_progress);
-               fragmentTransaction.add(R.id.weather_map_buttons_container, buttonsFragment, BUTTONS_FRAGMENT_TAG).commit();
-               fm.executePendingTransactions();
-       }
-       
-       if (this.mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
-               final Button getLocationButton = (Button) this.findViewById(R.id.weather_map_button_getlocation);
-               getLocationButton.setEnabled(true);
-       }
-       }
-       
-       private void removeButtonsFragment() {
-       final FragmentManager fm = this.getSupportFragmentManager();
-       final Fragment buttonsFragment = fm.findFragmentByTag(BUTTONS_FRAGMENT_TAG);
-       if (buttonsFragment != null) {
-               final FragmentTransaction fragmentTransaction = fm.beginTransaction();
-               fragmentTransaction.remove(buttonsFragment).commit();
-               fm.executePendingTransactions();
-       }
-       }
-
-   /*****************************************************************************************************
-    *
-    *                                                  android.location.LocationListener
-    *
-    *****************************************************************************************************/
-       
-       @Override
-       public void onLocationChanged(final Location location) {
-               // It was called from onClickGetLocation (UI thread) This method will run in the same thread (the UI thread)
-               // so, I do no think there should be any problem.
-
-               // Display the current location in the UI
-               // TODO: May location not be null?
-               this.getAddressAndUpdateUI(location.getLatitude(), location.getLongitude());
-       }
-       
-       @Override
-       public void onStatusChanged(String provider, int status, Bundle extras) {
-               // TODO Auto-generated method stub
-               
-       }
-
-       @Override
-       public void onProviderEnabled(String provider) {
-               // TODO Auto-generated method stub
-               
-       }
-
-       @Override
-       public void onProviderDisabled(String provider) {
-               // TODO Auto-generated method stub
-               
-       }
-}
diff --git a/src/de/example/exampletdd/NotificationIntentService.java b/src/de/example/exampletdd/NotificationIntentService.java
deleted file mode 100644 (file)
index 596b43f..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-package de.example.exampletdd;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.Calendar;
-import java.util.Locale;
-
-import org.apache.http.client.ClientProtocolException;
-
-import android.app.IntentService;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.http.AndroidHttpClient;
-import android.preference.PreferenceManager;
-import android.support.v4.app.NotificationCompat;
-import android.support.v4.app.NotificationManagerCompat;
-import android.support.v4.app.TaskStackBuilder;
-import android.util.Log;
-import android.widget.RemoteViews;
-
-import com.fasterxml.jackson.core.JsonParseException;
-
-import de.example.exampletdd.httpclient.CustomHTTPClient;
-import de.example.exampletdd.model.DatabaseQueries;
-import de.example.exampletdd.model.WeatherLocation;
-import de.example.exampletdd.model.currentweather.Current;
-import de.example.exampletdd.parser.JPOSWeatherParser;
-import de.example.exampletdd.service.IconsList;
-import de.example.exampletdd.service.ServiceParser;
-
-public class NotificationIntentService extends IntentService {
-    private static final String TAG = "NotificationIntentService";
-
-
-    public NotificationIntentService() {
-        super("NIS-Thread");
-    }
-
-    @Override
-    protected void onHandleIntent(final Intent intent) {
-        final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
-        final WeatherLocation weatherLocation = query.queryDataBase();
-        
-        if (weatherLocation != null) {
-            final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser());
-            final CustomHTTPClient HTTPClient = new CustomHTTPClient(
-                    AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent"));
-
-            Current current = null;
-            try {
-               current = this.doInBackgroundThrowable(weatherLocation, HTTPClient, weatherService);
-                
-            } catch (final JsonParseException e) {
-                Log.e(TAG, "doInBackground exception: ", e);
-            } catch (final ClientProtocolException e) {
-                Log.e(TAG, "doInBackground exception: ", e);
-            } catch (final MalformedURLException e) {
-                Log.e(TAG, "doInBackground exception: ", e);
-            } catch (final URISyntaxException e) {
-                Log.e(TAG, "doInBackground exception: ", e);
-            } catch (final IOException e) {
-                // logger infrastructure swallows UnknownHostException :/
-                Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
-            } finally {
-                HTTPClient.close();
-            }
-            
-            if (current != null) {
-               this.showNotification(current, weatherLocation);
-            }
-        }
-    }
-
-    private Current doInBackgroundThrowable(final WeatherLocation weatherLocation,
-            final CustomHTTPClient HTTPClient, final ServiceParser weatherService)
-                    throws ClientProtocolException, MalformedURLException, URISyntaxException,
-                    JsonParseException, IOException {
-
-        final String APIVersion = this.getResources().getString(R.string.api_version);
-
-        final String urlAPI = this.getResources().getString(R.string.uri_api_weather_today);
-        final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
-                weatherLocation.getLatitude(), weatherLocation.getLongitude());
-        final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
-        final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
-        final Current current = weatherService.retrieveCurrentFromJPOS(jsonData);
-        // TODO: what is this for? I guess I could skip it :/
-        final Calendar now = Calendar.getInstance();
-        current.setDate(now.getTime());
-        
-        return current;
-    }
-    
-    private interface UnitsConversor {
-       
-       public double doConversion(final double value);
-    }
-    
-    private void showNotification(final Current current, final WeatherLocation weatherLocation) {
-        final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this.getApplicationContext());
-
-               // TODO: repeating the same code in Overview, Specific and Current!!!
-               // 1. Update units of measurement.
-        // 1.1 Temperature
-        String tempSymbol;
-        UnitsConversor tempUnitsConversor;
-        String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key);
-        String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
-        if (unitsPreferenceValue.equals(values[0])) {
-               tempSymbol = values[0];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value - 273.15;
-                               }
-                       
-               };
-        } else if (unitsPreferenceValue.equals(values[1])) {
-               tempSymbol = values[1];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return (value * 1.8) - 459.67;
-                               }
-                       
-               };
-        } else {
-               tempSymbol = values[2];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value;
-                               }
-                       
-               };
-        }
-
-
-        // 2. Formatters
-        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
-        tempFormatter.applyPattern("#####.#####");
-
-
-        // 3. Prepare data for RemoteViews.
-        String tempMax = "";
-        if (current.getMain().getTemp_max() != null) {
-            double conversion = (Double) current.getMain().getTemp_max();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempMax = tempFormatter.format(conversion) + tempSymbol;
-        }
-        String tempMin = "";
-        if (current.getMain().getTemp_min() != null) {
-            double conversion = (Double) current.getMain().getTemp_min();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempMin = tempFormatter.format(conversion) + tempSymbol;
-        }
-        Bitmap picture;
-        if ((current.getWeather().size() > 0)
-                && (current.getWeather().get(0).getIcon() != null)
-                && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) {
-            final String icon = current.getWeather().get(0).getIcon();
-            picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
-                    .getResourceDrawable());
-        } else {
-            picture = BitmapFactory.decodeResource(this.getResources(),
-                    R.drawable.weather_severe_alert);
-        }
-        final String city = weatherLocation.getCity();
-        final String country = weatherLocation.getCountry();
-        
-        // 4. Insert data in RemoteViews.
-        final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.notification);
-        remoteView.setImageViewBitmap(R.id.weather_notification_image, picture);
-        remoteView.setTextViewText(R.id.weather_notification_temperature_max, tempMax);
-        remoteView.setTextViewText(R.id.weather_notification_temperature_min, tempMin);
-        remoteView.setTextViewText(R.id.weather_notification_city, city);
-        remoteView.setTextViewText(R.id.weather_notification_country, country);
-
-        // 5. Activity launcher.
-        final Intent resultIntent =  new Intent(this.getApplicationContext(), WeatherTabsActivity.class);
-        // The PendingIntent to launch our activity if the user selects this notification
-//        final PendingIntent contentIntent = PendingIntent.getActivity(
-//                     this.getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-        // The stack builder object will contain an artificial back stack for the started Activity.
-        // This ensures that navigating backward from the Activity leads out of
-        // your application to the Home screen.
-        final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext());
-        // Adds the back stack for the Intent (but not the Intent itself)
-        stackBuilder.addParentStack(WeatherTabsActivity.class);
-        // Adds the Intent that starts the Activity to the top of the stack
-        stackBuilder.addNextIntent(resultIntent);
-        final PendingIntent resultPendingIntent =
-                       stackBuilder.getPendingIntent(
-                    0,
-                    PendingIntent.FLAG_UPDATE_CURRENT
-                );
-        
-       final NotificationManagerCompat notificationManager =
-                       NotificationManagerCompat.from(this.getApplicationContext());
-       
-
-       // 6. Create notification.
-        final NotificationCompat.Builder notificationBuilder =
-                       new NotificationCompat.Builder(this.getApplicationContext())
-                       .setContent(remoteView)
-                .setSmallIcon(R.drawable.ic_launcher)
-                .setAutoCancel(true)
-                .setLocalOnly(true)
-                .setWhen(System.currentTimeMillis())
-                .setContentIntent(resultPendingIntent)
-                .setPriority(NotificationCompat.PRIORITY_DEFAULT);
-        
-        final Notification notification = notificationBuilder.build();
-        notification.flags |= Notification.FLAG_AUTO_CANCEL;
-
-        // Send the notification.
-        // Sets an ID for the notification, so it can be updated (just in case)
-        int notifyID = 1;
-        notificationManager.notify(notifyID, notification);
-    }
-}
diff --git a/src/de/example/exampletdd/SpecificActivity.java b/src/de/example/exampletdd/SpecificActivity.java
deleted file mode 100644 (file)
index 3cb5da4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package de.example.exampletdd;
-
-import android.app.ActionBar;
-import android.os.Bundle;
-import android.support.v4.app.FragmentActivity;
-import de.example.exampletdd.model.DatabaseQueries;
-import de.example.exampletdd.model.WeatherLocation;
-
-public class SpecificActivity extends FragmentActivity {
-
-    @Override
-    protected void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        this.setContentView(R.layout.weather_specific);
-
-        final ActionBar actionBar = this.getActionBar();
-
-        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
-        actionBar.setDisplayHomeAsUpEnabled(true);
-
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        // 1. Update title.
-        final DatabaseQueries query = new DatabaseQueries(this);
-        final WeatherLocation weatherLocation = query.queryDataBase();
-        if (weatherLocation != null) {
-               final ActionBar actionBar = this.getActionBar();
-            // TODO: I18N and comma :/
-            actionBar.setTitle(weatherLocation.getCity() + "," + weatherLocation.getCountry());        
-        }
-    }
-}
diff --git a/src/de/example/exampletdd/WeatherInformationBootReceiver.java b/src/de/example/exampletdd/WeatherInformationBootReceiver.java
deleted file mode 100644 (file)
index 05b751d..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-package de.example.exampletdd;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.SystemClock;
-import android.preference.PreferenceManager;
-
-public class WeatherInformationBootReceiver extends BroadcastReceiver {
-
-    @Override
-    public void onReceive(final Context context, final Intent intent) {
-
-        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
-               
-               // Update Time Rate
-            final SharedPreferences sharedPreferences = PreferenceManager
-                    .getDefaultSharedPreferences(context);
-            final String keyPreference = context
-                    .getString(R.string.weather_preferences_update_time_rate_key);
-            final String updateTimeRate = sharedPreferences.getString(keyPreference, "");            
-            long chosenInterval = 0;
-            if (updateTimeRate.equals("900")) {
-               chosenInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
-            } else if (updateTimeRate.equals("1800")) {
-               chosenInterval = AlarmManager.INTERVAL_HALF_HOUR;
-            } else if (updateTimeRate.equals("3600")) {
-               chosenInterval = AlarmManager.INTERVAL_HOUR;
-            } else if (updateTimeRate.equals("43200")) {
-               chosenInterval = AlarmManager.INTERVAL_HALF_DAY;
-            } else if (updateTimeRate.equals("86400")) {
-               chosenInterval = AlarmManager.INTERVAL_DAY;
-            }
-
-            if (chosenInterval != 0) {
-                final AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-                // TODO: better use some string instead of .class? In case I change the service class
-                // this could be a problem (I guess)
-                final Intent serviceIntent = new Intent(context, NotificationIntentService.class);
-                final PendingIntent alarmIntent = PendingIntent.getService(
-                               context,
-                               0,
-                               serviceIntent,
-                               PendingIntent.FLAG_UPDATE_CURRENT);
-                alarmMgr.setInexactRepeating(
-                               AlarmManager.ELAPSED_REALTIME,
-                               SystemClock.elapsedRealtime() + chosenInterval,
-                               chosenInterval,
-                               alarmIntent);
-            }
-        }
-    }
-
-}
diff --git a/src/de/example/exampletdd/WeatherInformationPreferencesActivity.java b/src/de/example/exampletdd/WeatherInformationPreferencesActivity.java
deleted file mode 100644 (file)
index 1e9b0d4..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.example.exampletdd;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.os.Bundle;
-import de.example.exampletdd.fragment.preferences.WeatherInformationPreferencesFragment;
-
-public class WeatherInformationPreferencesActivity extends Activity {
-
-    @Override
-    protected void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        this.getFragmentManager()
-        .beginTransaction()
-        .replace(android.R.id.content,
-                new WeatherInformationPreferencesFragment()).commit();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        final ActionBar actionBar = this.getActionBar();
-        actionBar.setTitle(this.getString(R.string.weather_preferences_action_settings));
-    }
-}
diff --git a/src/de/example/exampletdd/WeatherTabsActivity.java b/src/de/example/exampletdd/WeatherTabsActivity.java
deleted file mode 100644 (file)
index 168ab2e..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-package de.example.exampletdd;
-
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.FragmentTransaction;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.view.Menu;
-import android.view.MenuItem;
-import de.example.exampletdd.fragment.current.CurrentFragment;
-import de.example.exampletdd.fragment.overview.OverviewFragment;
-import de.example.exampletdd.model.DatabaseQueries;
-import de.example.exampletdd.model.WeatherLocation;
-
-public class WeatherTabsActivity extends FragmentActivity {
-    private static final int NUM_ITEMS = 2;
-    private ViewPager mPager;
-    
-    @Override
-    protected void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        this.setContentView(R.layout.fragment_pager);
-
-        this.mPager = (ViewPager)this.findViewById(R.id.pager);
-        this.mPager.setAdapter(new TabsAdapter(this.getSupportFragmentManager()));
-
-
-        this.mPager.setOnPageChangeListener(
-                new ViewPager.SimpleOnPageChangeListener() {
-                    @Override
-                    public void onPageSelected(final int position) {
-                        WeatherTabsActivity.this.getActionBar().setSelectedNavigationItem(position);
-                    }
-                });
-
-
-        final ActionBar actionBar = this.getActionBar();
-
-        PreferenceManager.setDefaultValues(this, R.xml.weather_preferences, false);
-
-        // Specify that tabs should be displayed in the action bar.
-        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
-        actionBar.setDisplayHomeAsUpEnabled(true);
-
-        // Create a tab listener that is called when the user changes tabs.
-        final ActionBar.TabListener tabListener = new ActionBar.TabListener() {
-
-            @Override
-            public void onTabSelected(final Tab tab, final FragmentTransaction ft) {
-                WeatherTabsActivity.this.mPager.setCurrentItem(tab.getPosition());
-
-            }
-
-            @Override
-            public void onTabUnselected(final Tab tab, final FragmentTransaction ft) {
-
-            }
-
-            @Override
-            public void onTabReselected(final Tab tab, final FragmentTransaction ft) {
-
-            }
-
-        };
-
-        actionBar.addTab(actionBar.newTab().setText("CURRENTLY").setTabListener(tabListener));
-        actionBar.addTab(actionBar.newTab().setText("FORECAST").setTabListener(tabListener));
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(final Menu menu) {
-
-        this.getMenuInflater().inflate(R.menu.weather_main_menu, menu);
-
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(final MenuItem item) {
-        // Handle action bar item clicks here. The action bar will
-        // automatically handle clicks on the Home/Up button, so long
-        // as you specify a parent activity in AndroidManifest.xml.
-        super.onOptionsItemSelected(item);
-
-        Intent intent;
-        final int itemId = item.getItemId();
-        if (itemId == R.id.weather_menu_settings) {
-            intent = new Intent("de.example.exampletdd.WEATHERINFO")
-            .setComponent(new ComponentName("de.example.exampletdd",
-                    "de.example.exampletdd.WeatherInformationPreferencesActivity"));
-            this.startActivity(intent);
-            return true;
-        } else if (itemId == R.id.weather_menu_map) {
-            intent = new Intent("de.example.exampletdd.WEATHERINFO").
-                       setComponent(new ComponentName("de.example.exampletdd",
-                                       "de.example.exampletdd.MapActivity"));
-            this.startActivity(intent);
-            return true;
-        } else {
-        }
-
-        // TODO: calling again super method?
-        return super.onOptionsItemSelected(item);
-    }
-
-    @Override
-    protected void onRestoreInstanceState(final Bundle savedInstanceState) {
-        super.onRestoreInstanceState(savedInstanceState);
-    }
-
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        final ActionBar actionBar = this.getActionBar();
-        
-        // 1. Update title.
-        final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
-        final WeatherLocation weatherLocation = query.queryDataBase();
-        if (weatherLocation != null) {
-            // TODO: I18N and comma :/
-            actionBar.setTitle(weatherLocation.getCity() + "," + weatherLocation.getCountry());        
-        } else {
-               // TODO: static resource
-               actionBar.setTitle("no chosen location");
-        }
-
-        // 2. Update forecast tab text.
-        final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this);
-        final String keyPreference = this.getString(R.string.weather_preferences_day_forecast_key);
-        final String value = sharedPreferences.getString(keyPreference, "");
-        String humanValue = "";
-        if (value.equals("5")) {
-            humanValue = "5 DAY FORECAST";
-        } else if (value.equals("10")) {
-            humanValue = "10 DAY FORECAST";
-        } else if (value.equals("14")) {
-            humanValue = "14 DAY FORECAST";
-        }
-        actionBar.getTabAt(1).setText(humanValue);
-    }
-
-    @Override
-    public void onSaveInstanceState(final Bundle savedInstanceState) {
-        super.onSaveInstanceState(savedInstanceState);
-    }
-
-    private class TabsAdapter extends FragmentPagerAdapter {
-        public TabsAdapter(final FragmentManager fm) {
-            super(fm);
-        }
-
-        @Override
-        public int getCount() {
-            return NUM_ITEMS;
-        }
-
-        @Override
-        public Fragment getItem(final int position) {
-            if (position == 0) {
-               // TODO: new instance every time I click on tab?
-                return new CurrentFragment();
-            } else {
-               // TODO: new instance every time I click on tab?
-                final Fragment fragment = new OverviewFragment();
-                return fragment;
-            }
-
-        }
-    }
-}
diff --git a/src/de/example/exampletdd/WidgetIntentService.java b/src/de/example/exampletdd/WidgetIntentService.java
deleted file mode 100644 (file)
index ed38545..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-package de.example.exampletdd;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.Calendar;
-import java.util.Locale;
-
-import org.apache.http.client.ClientProtocolException;
-
-import android.app.IntentService;
-import android.app.PendingIntent;
-import android.appwidget.AppWidgetManager;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.net.http.AndroidHttpClient;
-import android.preference.PreferenceManager;
-import android.support.v4.app.TaskStackBuilder;
-import android.util.Log;
-import android.widget.RemoteViews;
-
-import com.fasterxml.jackson.core.JsonParseException;
-
-import de.example.exampletdd.httpclient.CustomHTTPClient;
-import de.example.exampletdd.model.DatabaseQueries;
-import de.example.exampletdd.model.WeatherLocation;
-import de.example.exampletdd.model.currentweather.Current;
-import de.example.exampletdd.parser.JPOSWeatherParser;
-import de.example.exampletdd.service.IconsList;
-import de.example.exampletdd.service.PermanentStorage;
-import de.example.exampletdd.service.ServiceParser;
-import de.example.exampletdd.widget.WidgetConfigure;
-
-public class WidgetIntentService extends IntentService {
-       private static final String TAG = "WidgetIntentService";
-
-
-       public WidgetIntentService() {
-               super("WIS-Thread");
-       }
-
-       @Override
-       protected void onHandleIntent(final Intent intent) {
-               Log.i(TAG, "onHandleIntent");
-               final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
-               final boolean isUpdateByApp = intent.getBooleanExtra("updateByApp", false);
-
-               if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
-                       // Nothing to do. Something went wrong. Show error.
-                       return;
-               }
-
-
-               final DatabaseQueries query = new DatabaseQueries(this.getApplicationContext());
-               final WeatherLocation weatherLocation = query.queryDataBase();
-               
-               if (weatherLocation == null) {
-                       // Nothing to do. Show error.
-                       final RemoteViews view = this.makeErrorView(appWidgetId);
-                       this.updateWidget(view, appWidgetId);
-                       return;
-               }
-               
-               if (isUpdateByApp) {            
-                       this.updateByApp(weatherLocation, appWidgetId);
-               } else {
-                       this.updateByTimeout(weatherLocation, appWidgetId);
-               }
-
-       }
-
-       private void updateByApp(final WeatherLocation weatherLocation, final int appWidgetId) {
-               final PermanentStorage store = new PermanentStorage(this.getApplicationContext());
-        final Current current = store.getCurrent();
-               
-               this.updateWidget(current, weatherLocation, appWidgetId);
-       }
-       
-       private void updateByTimeout(final WeatherLocation weatherLocation, final int appWidgetId) {
-
-               final Current current = this.getRemoteCurrent(weatherLocation);
-
-               this.updateWidget(current, weatherLocation, appWidgetId);
-       }
-       
-       private void updateWidget(final Current current, final WeatherLocation weatherLocation, final int appWidgetId) {
-
-               if (current != null) {
-                       final RemoteViews view = this.makeView(current, weatherLocation, appWidgetId);
-                       this.updateWidget(view, appWidgetId);
-               } else {
-                       // Show error.
-                       final RemoteViews view = this.makeErrorView(appWidgetId);
-                       this.updateWidget(view, appWidgetId);
-               }
-       }
-
-
-       
-       private Current getRemoteCurrent(final WeatherLocation weatherLocation) {
-
-               final ServiceParser weatherService = new ServiceParser(new JPOSWeatherParser());
-               final CustomHTTPClient HTTPClient = new CustomHTTPClient(
-                               AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent"));
-
-               try {
-                       return this.getRemoteCurrentThrowable(weatherLocation, HTTPClient, weatherService);
-
-               } catch (final JsonParseException e) {
-                       Log.e(TAG, "doInBackground exception: ", e);
-               } catch (final ClientProtocolException e) {
-                       Log.e(TAG, "doInBackground exception: ", e);
-               } catch (final MalformedURLException e) {
-                       Log.e(TAG, "doInBackground exception: ", e);
-               } catch (final URISyntaxException e) {
-                       Log.e(TAG, "doInBackground exception: ", e);
-               } catch (final IOException e) {
-                       // logger infrastructure swallows UnknownHostException :/
-                       Log.e(TAG, "doInBackground exception: " + e.getMessage(), e);
-               } finally {
-                       HTTPClient.close();
-               }
-
-               return null;
-       }
-
-       private Current getRemoteCurrentThrowable(final WeatherLocation weatherLocation,
-                       final CustomHTTPClient HTTPClient, final ServiceParser weatherService)
-                                       throws ClientProtocolException, MalformedURLException, URISyntaxException,
-                                       JsonParseException, IOException {
-
-               final String APIVersion = this.getResources().getString(R.string.api_version);
-
-               final String urlAPI = this.getResources().getString(R.string.uri_api_weather_today);
-               final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion,
-                               weatherLocation.getLatitude(), weatherLocation.getLongitude());
-               final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
-               final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
-               final Current current = weatherService.retrieveCurrentFromJPOS(jsonData);
-               // TODO: what is this for? I guess I could skip it :/
-               final Calendar now = Calendar.getInstance();
-               current.setDate(now.getTime());
-
-               return current;
-       }
-
-    private interface UnitsConversor {
-       
-       public double doConversion(final double value);
-    }
-    
-       private RemoteViews makeView(final Current current, final WeatherLocation weatherLocation, final int appWidgetId) {
-               final SharedPreferences sharedPreferences = PreferenceManager
-                               .getDefaultSharedPreferences(this.getApplicationContext());
-
-               // TODO: repeating the same code in Overview, Specific and Current!!!
-               // 1. Update units of measurement.
-        // 1.1 Temperature
-        String tempSymbol;
-        UnitsConversor tempUnitsConversor;
-        String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key);
-        String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
-        if (unitsPreferenceValue.equals(values[0])) {
-               tempSymbol = values[0];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value - 273.15;
-                               }
-                       
-               };
-        } else if (unitsPreferenceValue.equals(values[1])) {
-               tempSymbol = values[1];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return (value * 1.8) - 459.67;
-                               }
-                       
-               };
-        } else {
-               tempSymbol = values[2];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value;
-                               }
-                       
-               };
-        }
-
-
-               // 2. Formatters
-               final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
-               tempFormatter.applyPattern("#####.#####");
-
-
-               // 3. Prepare data for RemoteViews.
-               String tempMax = "";
-               if (current.getMain().getTemp_max() != null) {
-                       double conversion = (Double) current.getMain().getTemp_max();
-                       conversion = tempUnitsConversor.doConversion(conversion);
-                       tempMax = tempFormatter.format(conversion) + tempSymbol;
-               }
-               String tempMin = "";
-               if (current.getMain().getTemp_min() != null) {
-                       double conversion = (Double) current.getMain().getTemp_min();
-                       conversion = tempUnitsConversor.doConversion(conversion);
-                       tempMin = tempFormatter.format(conversion) + tempSymbol;
-               }
-               Bitmap picture;
-               if ((current.getWeather().size() > 0)
-                               && (current.getWeather().get(0).getIcon() != null)
-                               && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) {
-                       final String icon = current.getWeather().get(0).getIcon();
-                       picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
-                                       .getResourceDrawable());
-               } else {
-                       picture = BitmapFactory.decodeResource(this.getResources(),
-                                       R.drawable.weather_severe_alert);
-               }
-               final String city = weatherLocation.getCity();
-               final String country = weatherLocation.getCountry();
-
-               // 4. Insert data in RemoteViews.
-               final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.appwidget);
-               remoteView.setImageViewBitmap(R.id.weather_appwidget_image, picture);
-               remoteView.setTextViewText(R.id.weather_appwidget_temperature_max, tempMax);
-               remoteView.setTextViewText(R.id.weather_appwidget_temperature_min, tempMin);
-               remoteView.setTextViewText(R.id.weather_appwidget_city, city);
-               remoteView.setTextViewText(R.id.weather_appwidget_country, country);
-
-               // 5. Activity launcher.
-               final Intent resultIntent =  new Intent(this.getApplicationContext(), WidgetConfigure.class);
-               resultIntent.putExtra("actionFromUser", true);
-               resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-               // From: http://stackoverflow.com/questions/4011178/multiple-instances-of-widget-only-updating-last-widget
-               final Uri data = Uri.withAppendedPath(Uri.parse("PAIN" + "://widget/id/") ,String.valueOf(appWidgetId));
-               resultIntent.setData(data);
-
-               final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext());
-               // Adds the back stack for the Intent (but not the Intent itself)
-               stackBuilder.addParentStack(WidgetConfigure.class);
-               // Adds the Intent that starts the Activity to the top of the stack
-               stackBuilder.addNextIntent(resultIntent);
-               final PendingIntent resultPendingIntent =
-                               stackBuilder.getPendingIntent(
-                                               0,
-                                               PendingIntent.FLAG_UPDATE_CURRENT
-                                               );
-               remoteView.setOnClickPendingIntent(R.id.weather_appwidget, resultPendingIntent);
-               
-               return remoteView;
-       }
-       
-       private RemoteViews makeErrorView(final int appWidgetId) {
-               final RemoteViews remoteView = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.appwidget_error);
-
-               // 5. Activity launcher.
-               final Intent resultIntent =  new Intent(this.getApplicationContext(), WidgetConfigure.class);
-               resultIntent.putExtra("actionFromUser", true);
-               resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-               // From: http://stackoverflow.com/questions/4011178/multiple-instances-of-widget-only-updating-last-widget
-               final Uri data = Uri.withAppendedPath(Uri.parse("PAIN" + "://widget/id/") ,String.valueOf(appWidgetId));
-               resultIntent.setData(data);
-
-               final TaskStackBuilder stackBuilder = TaskStackBuilder.create(this.getApplicationContext());
-               // Adds the back stack for the Intent (but not the Intent itself)
-               stackBuilder.addParentStack(WidgetConfigure.class);
-               // Adds the Intent that starts the Activity to the top of the stack
-               stackBuilder.addNextIntent(resultIntent);
-               final PendingIntent resultPendingIntent =
-                               stackBuilder.getPendingIntent(
-                                               0,
-                                               PendingIntent.FLAG_UPDATE_CURRENT
-                                               );
-               remoteView.setOnClickPendingIntent(R.id.weather_appwidget_error, resultPendingIntent);
-
-               return remoteView;
-       }
-
-       private void updateWidget(final RemoteViews remoteView, final int appWidgetId) {
-               
-               final AppWidgetManager manager = AppWidgetManager.getInstance(this.getApplicationContext());
-               manager.updateAppWidget(appWidgetId, remoteView);
-       }
-       
-//     private void updateWidgets(final RemoteViews remoteView) {
-//             
-//             final ComponentName widgets = new ComponentName(this.getApplicationContext(), WidgetProvider.class);
-//             final AppWidgetManager manager = AppWidgetManager.getInstance(this.getApplicationContext());
-//             manager.updateAppWidget(widgets, remoteView);
-//     }
-}
diff --git a/src/de/example/exampletdd/dummy/DummyContent.java b/src/de/example/exampletdd/dummy/DummyContent.java
deleted file mode 100644 (file)
index 6c09241..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package de.example.exampletdd.dummy;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Helper class for providing sample content for user interfaces created by
- * Android template wizards.
- * <p>
- * TODO: Replace all uses of this class before publishing your app.
- */
-public class DummyContent {
-
-    /**
-     * An array of sample (dummy) items.
-     */
-    public static List<DummyItem> ITEMS = new ArrayList<DummyItem>();
-
-    /**
-     * A map of sample (dummy) items, by ID.
-     */
-    public static Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
-
-    static {
-        // Add 3 sample items.
-        addItem(new DummyItem("1", "Item 1"));
-        addItem(new DummyItem("2", "Item 2"));
-        addItem(new DummyItem("3", "Item 3"));
-    }
-
-    private static void addItem(DummyItem item) {
-        ITEMS.add(item);
-        ITEM_MAP.put(item.id, item);
-    }
-
-    /**
-     * A dummy item representing a piece of content.
-     */
-    public static class DummyItem {
-        public String id;
-        public String content;
-
-        public DummyItem(String id, String content) {
-            this.id = id;
-            this.content = content;
-        }
-
-        @Override
-        public String toString() {
-            return content;
-        }
-    }
-}
diff --git a/src/de/example/exampletdd/fragment/ErrorDialogFragment.java b/src/de/example/exampletdd/fragment/ErrorDialogFragment.java
deleted file mode 100644 (file)
index 5d00707..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-package de.example.exampletdd.fragment;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-
-public class ErrorDialogFragment extends DialogFragment {
-
-    public static ErrorDialogFragment newInstance(final int title) {
-        final ErrorDialogFragment frag = new ErrorDialogFragment();
-        final Bundle args = new Bundle();
-
-        args.putInt("title", title);
-        frag.setArguments(args);
-
-        return frag;
-    }
-
-    @Override
-    public Dialog onCreateDialog(final Bundle savedInstanceState) {
-        final int title = this.getArguments().getInt("title");
-
-        return new AlertDialog.Builder(this.getActivity())
-        .setIcon(android.R.drawable.ic_dialog_alert)
-        .setTitle(title)
-        .setPositiveButton(android.R.string.ok,
-                new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog,
-                    final int whichButton) {
-
-            }
-        }).create();
-    }
-    
-    @Override
-    public void onDestroyView() {
-       if (getDialog() != null && getRetainInstance()) {
-               getDialog().setDismissMessage(null);
-       }
-       super.onDestroyView();
-    }
-}
\ No newline at end of file
diff --git a/src/de/example/exampletdd/fragment/ProgressDialogFragment.java b/src/de/example/exampletdd/fragment/ProgressDialogFragment.java
deleted file mode 100644 (file)
index 7ff9960..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-package de.example.exampletdd.fragment;
-
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.view.KeyEvent;
-
-public class ProgressDialogFragment extends DialogFragment {
-
-    public static ProgressDialogFragment newInstance(final int title) {
-        return newInstance(title, null);
-    }
-
-    public static ProgressDialogFragment newInstance(final int title,
-            final String message) {
-        final ProgressDialogFragment frag = new ProgressDialogFragment();
-        final Bundle args = new Bundle();
-
-        args.putInt("title", title);
-        args.putString("message", message);
-        frag.setArguments(args);
-        return frag;
-    }
-
-    @Override
-    public Dialog onCreateDialog(final Bundle savedInstanceState) {
-        final int title = this.getArguments().getInt("title");
-        final String message = this.getArguments().getString("message");
-
-        final ProgressDialog dialog = new ProgressDialog(this.getActivity());
-        dialog.setIcon(android.R.drawable.ic_dialog_info);
-        if (title != 0) {
-            dialog.setTitle(title);
-        }
-        if (message != null) {
-            dialog.setMessage(message);
-        }
-        dialog.setCancelable(false);
-        this.setCancelable(false);
-        dialog.setIndeterminate(true);
-        dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
-
-            @Override
-            public final boolean onKey(final DialogInterface dialog,
-                    final int keyCode, final KeyEvent event) {
-                return false;
-            }
-        });
-
-        return dialog;
-    }
-}
diff --git a/src/de/example/exampletdd/fragment/current/CurrentFragment.java b/src/de/example/exampletdd/fragment/current/CurrentFragment.java
deleted file mode 100644 (file)
index 13f9a77..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-package de.example.exampletdd.fragment.current;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-
-import org.apache.http.client.ClientProtocolException;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.http.AndroidHttpClient;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.support.v4.app.Fragment;
-import android.support.v4.content.LocalBroadcastManager;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.fasterxml.jackson.core.JsonParseException;
-
-import de.example.exampletdd.R;
-import de.example.exampletdd.WidgetIntentService;
-import de.example.exampletdd.httpclient.CustomHTTPClient;
-import de.example.exampletdd.model.DatabaseQueries;
-import de.example.exampletdd.model.WeatherLocation;
-import de.example.exampletdd.model.currentweather.Current;
-import de.example.exampletdd.parser.JPOSWeatherParser;
-import de.example.exampletdd.service.IconsList;
-import de.example.exampletdd.service.PermanentStorage;
-import de.example.exampletdd.service.ServiceParser;
-
-public class CurrentFragment extends Fragment {
-    private static final String TAG = "CurrentFragment";
-    private BroadcastReceiver mReceiver;
-
-    @Override
-    public void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                             Bundle savedInstanceState) {
-    
-       // Inflate the layout for this fragment
-        return inflater.inflate(R.layout.weather_current_fragment, container, false);
-    }
-    
-    @Override
-    public void onActivityCreated(final Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        if (savedInstanceState != null) {
-               // Restore UI state
-            final Current current = (Current) savedInstanceState.getSerializable("Current");
-
-            // TODO: Could it be better to store in global forecast data even if it is null value?
-            //       So, perhaps do not check for null value and always store in global variable.
-            if (current != null) {
-               final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-               store.saveCurrent(current);
-            }
-        }     
-        
-        this.setHasOptionsMenu(false);
-
-        this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE);
-        this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.VISIBLE);
-       this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE);   
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-
-        this.mReceiver = new BroadcastReceiver() {
-
-                       @Override
-                       public void onReceive(final Context context, final Intent intent) {
-                               final String action = intent.getAction();
-                               if (action.equals("de.example.exampletdd.UPDATECURRENT")) {
-                                       final Current currentRemote = (Current) intent.getSerializableExtra("current");
-
-                                       if (currentRemote != null) {
-
-                                               // 1. Check conditions. They must be the same as the ones that triggered the AsyncTask.
-                                               final DatabaseQueries query = new DatabaseQueries(context.getApplicationContext());
-                                   final WeatherLocation weatherLocation = query.queryDataBase();
-                                   final PermanentStorage store = new PermanentStorage(context.getApplicationContext());
-                                   final Current current = store.getCurrent();
-
-                                   if (current == null || !CurrentFragment.this.isDataFresh(weatherLocation.getLastCurrentUIUpdate())) {
-                                       // 2. Update UI.
-                                       CurrentFragment.this.updateUI(currentRemote);
-
-                                       // 3. Update Data.
-                                                       store.saveCurrent(currentRemote);
-                                           weatherLocation.setLastCurrentUIUpdate(new Date());
-                                           query.updateDataBase(weatherLocation);
-                                   }
-
-                                       } else {
-                                               // Empty UI and show error message
-                                               CurrentFragment.this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE);
-                                               CurrentFragment.this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.GONE);
-                                               CurrentFragment.this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.VISIBLE);
-                                       }
-                               }
-                       }
-        };
-
-        // Register receiver
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction("de.example.exampletdd.UPDATECURRENT");
-        LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext())
-                                                       .registerReceiver(this.mReceiver, filter);
-
-        // Empty UI
-        this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.GONE);
-        
-        final DatabaseQueries query = new DatabaseQueries(this.getActivity().getApplicationContext());
-        final WeatherLocation weatherLocation = query.queryDataBase();
-        if (weatherLocation == null) {
-            // Nothing to do.
-               // Show error message
-               final ProgressBar progress = (ProgressBar) getActivity().findViewById(R.id.weather_current_progressbar);
-               progress.setVisibility(View.GONE);
-                       final TextView errorMessage = (TextView) getActivity().findViewById(R.id.weather_current_error_message);
-               errorMessage.setVisibility(View.VISIBLE);
-            return;
-        }
-
-        final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-        final Current current = store.getCurrent();
-
-        if (current != null && this.isDataFresh(weatherLocation.getLastCurrentUIUpdate())) {
-            this.updateUI(current);
-        } else {
-            // Load remote data (aynchronous)
-            // Gets the data from the web.
-               this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.VISIBLE);
-               this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE);
-            final CurrentTask task = new CurrentTask(
-                       this.getActivity().getApplicationContext(),
-                    new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")),
-                    new ServiceParser(new JPOSWeatherParser()));
-
-            task.execute(weatherLocation.getLatitude(), weatherLocation.getLongitude());
-            // TODO: make sure UI thread keeps running in parallel after that. I guess.
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(final Bundle savedInstanceState) {
-
-        // Save UI state
-       final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-        final Current current = store.getCurrent();
-
-        // TODO: Could it be better to save current data even if it is null value?
-        //       So, perhaps do not check for null value.
-        if (current != null) {
-            savedInstanceState.putSerializable("Current", current);
-        }
-
-        super.onSaveInstanceState(savedInstanceState);
-    }
-
-    @Override
-    public void onPause() {
-        LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext()).unregisterReceiver(this.mReceiver);
-
-        super.onPause();
-    }
-
-    private interface UnitsConversor {
-       
-       public double doConversion(final double value);
-    }
-
-    private void updateUI(final Current current) {
-       
-        final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this.getActivity().getApplicationContext());
-
-        // TODO: repeating the same code in Overview, Specific and Current!!!
-        // 1. Update units of measurement.
-        // 1.1 Temperature
-        String tempSymbol;
-        UnitsConversor tempUnitsConversor;
-        String keyPreference = this.getResources().getString(R.string.weather_preferences_temperature_key);
-        String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
-        if (unitsPreferenceValue.equals(values[0])) {
-               tempSymbol = values[0];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value - 273.15;
-                               }
-                       
-               };
-        } else if (unitsPreferenceValue.equals(values[1])) {
-               tempSymbol = values[1];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return (value * 1.8) - 459.67;
-                               }
-                       
-               };
-        } else {
-               tempSymbol = values[2];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value;
-                               }
-                       
-               };
-        }
-
-        // 1.2 Wind
-        String windSymbol;
-        UnitsConversor windUnitsConversor;
-        keyPreference = this.getResources().getString(R.string.weather_preferences_wind_key);
-        unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        values = this.getResources().getStringArray(R.array.weather_preferences_wind);
-        if (unitsPreferenceValue.equals(values[0])) {
-               windSymbol = values[0];
-               windUnitsConversor = new UnitsConversor(){
-
-                       @Override
-                       public double doConversion(double value) {
-                               return value;
-                       }       
-               };
-        } else {
-               windSymbol = values[1];
-               windUnitsConversor = new UnitsConversor(){
-
-                       @Override
-                       public double doConversion(double value) {
-                               return value * 2.237;
-                       }       
-               };
-        }
-
-        // 1.3 Pressure
-        String pressureSymbol;
-        UnitsConversor pressureUnitsConversor;
-        keyPreference = this.getResources().getString(R.string.weather_preferences_pressure_key);
-        unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        values = this.getResources().getStringArray(R.array.weather_preferences_pressure);
-        if (unitsPreferenceValue.equals(values[0])) {
-               pressureSymbol = values[0];
-               pressureUnitsConversor = new UnitsConversor(){
-
-                       @Override
-                       public double doConversion(double value) {
-                               return value;
-                       }       
-               };
-        } else {
-               pressureSymbol = values[1];
-               pressureUnitsConversor = new UnitsConversor(){
-
-                       @Override
-                       public double doConversion(double value) {
-                               return value / 113.25d;
-                       }       
-               };
-        }
-
-
-        // 2. Formatters
-        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
-        tempFormatter.applyPattern("#####.#####");
-        final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.US);
-
-        
-        // 3. Prepare data for UI.
-        String tempMax = "";
-        if (current.getMain().getTemp_max() != null) {
-            double conversion = (Double) current.getMain().getTemp_max();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempMax = tempFormatter.format(conversion) + tempSymbol;
-        }
-        String tempMin = "";
-        if (current.getMain().getTemp_min() != null) {
-            double conversion = (Double) current.getMain().getTemp_min();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempMin = tempFormatter.format(conversion) + tempSymbol;
-        }
-        Bitmap picture;
-        if ((current.getWeather().size() > 0)
-                && (current.getWeather().get(0).getIcon() != null)
-                && (IconsList.getIcon(current.getWeather().get(0).getIcon()) != null)) {
-            final String icon = current.getWeather().get(0).getIcon();
-            picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
-                    .getResourceDrawable());
-        } else {
-            picture = BitmapFactory.decodeResource(this.getResources(),
-                    R.drawable.weather_severe_alert);
-        }
-
-        // TODO: static resource
-        String description = "no description available";
-        if (current.getWeather().size() > 0) {
-            description = current.getWeather().get(0).getDescription();
-        }
-
-        // TODO: units!!!!
-        String humidityValue = "";
-        if ((current.getMain() != null)
-                && (current.getMain().getHumidity() != null)) {
-            final double conversion = (Double) current.getMain().getHumidity();
-            humidityValue = tempFormatter.format(conversion);
-        }
-        String pressureValue = "";
-        if ((current.getMain() != null)
-                && (current.getMain().getPressure() != null)) {
-            double conversion = (Double) current.getMain().getPressure();
-            conversion = pressureUnitsConversor.doConversion(conversion);
-            pressureValue = tempFormatter.format(conversion);
-        }
-        String windValue = "";
-        if ((current.getWind() != null)
-                && (current.getWind().getSpeed() != null)) {
-            double conversion = (Double) current.getWind().getSpeed();
-            conversion = windUnitsConversor.doConversion(conversion);
-            windValue = tempFormatter.format(conversion);
-        }
-        String rainValue = "";
-        if ((current.getRain() != null)
-                && (current.getRain().get3h() != null)) {
-            final double conversion = (Double) current.getRain().get3h();
-            rainValue = tempFormatter.format(conversion);
-        }
-        String cloudsValue = "";
-        if ((current.getClouds() != null)
-                && (current.getClouds().getAll() != null)) {
-            final double conversion = (Double) current.getClouds().getAll();
-            cloudsValue = tempFormatter.format(conversion);
-        }
-        String snowValue = "";
-        if ((current.getSnow() != null)
-                && (current.getSnow().get3h() != null)) {
-            final double conversion = (Double) current.getSnow().get3h();
-            snowValue = tempFormatter.format(conversion);
-        }
-        String feelsLike = "";
-        if (current.getMain().getTemp() != null) {
-            double conversion = (Double) current.getMain().getTemp();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            feelsLike = tempFormatter.format(conversion);
-        }
-        String sunRiseTime = "";
-        if (current.getSys().getSunrise() != null) {
-            final long unixTime = (Long) current.getSys().getSunrise();
-            final Date unixDate = new Date(unixTime * 1000L);
-            sunRiseTime = dateFormat.format(unixDate);
-        }
-        String sunSetTime = "";
-        if (current.getSys().getSunset() != null) {
-            final long unixTime = (Long) current.getSys().getSunset();
-            final Date unixDate = new Date(unixTime * 1000L);
-            sunSetTime = dateFormat.format(unixDate);
-        }
-
-
-        // 4. Update UI.
-        final TextView tempMaxView = (TextView) getActivity().findViewById(R.id.weather_current_temp_max);
-        tempMaxView.setText(tempMax);
-        final TextView tempMinView = (TextView) getActivity().findViewById(R.id.weather_current_temp_min);
-        tempMinView.setText(tempMin);
-        final ImageView pictureView = (ImageView) getActivity().findViewById(R.id.weather_current_picture);
-        pictureView.setImageBitmap(picture);    
-        
-        final TextView descriptionView = (TextView) getActivity().findViewById(R.id.weather_current_description);
-        descriptionView.setText(description);
-        
-        ((TextView) getActivity().findViewById(R.id.weather_current_humidity_value)).setText(humidityValue);
-        ((TextView) getActivity().findViewById(R.id.weather_current_humidity_units)).setText(
-                       this.getActivity().getApplicationContext().getString(R.string.text_units_percent));
-        
-        ((TextView) getActivity().findViewById(R.id.weather_current_pressure_value)).setText(pressureValue);
-        ((TextView) getActivity().findViewById(R.id.weather_current_pressure_units)).setText(pressureSymbol);
-        
-        ((TextView) getActivity().findViewById(R.id.weather_current_wind_value)).setText(windValue);
-        ((TextView) getActivity().findViewById(R.id.weather_current_wind_units)).setText(windSymbol);
-        
-        ((TextView) getActivity().findViewById(R.id.weather_current_rain_value)).setText(rainValue);
-        ((TextView) getActivity().findViewById(R.id.weather_current_rain_units)).setText(
-                       this.getActivity().getApplicationContext().getString(R.string.text_units_mm3h));
-        
-        ((TextView) getActivity().findViewById(R.id.weather_current_clouds_value)).setText(cloudsValue);
-        ((TextView) getActivity().findViewById(R.id.weather_current_clouds_units)).setText(
-                       this.getActivity().getApplicationContext().getString(R.string.text_units_percent));
-        
-        ((TextView) getActivity().findViewById(R.id.weather_current_snow_value)).setText(snowValue);
-        ((TextView) getActivity().findViewById(R.id.weather_current_snow_units)).setText(
-                       this.getActivity().getApplicationContext().getString(R.string.text_units_mm3h));
-        
-        ((TextView) getActivity().findViewById(R.id.weather_current_feelslike_value)).setText(feelsLike);
-        ((TextView) getActivity().findViewById(R.id.weather_current_feelslike_units)).setText(tempSymbol);
-        
-        ((TextView) getActivity().findViewById(R.id.weather_current_sunrise_value)).setText(sunRiseTime);
-
-        ((TextView) getActivity().findViewById(R.id.weather_current_sunset_value)).setText(sunSetTime);
-        
-        this.getActivity().findViewById(R.id.weather_current_data_container).setVisibility(View.VISIBLE);
-        this.getActivity().findViewById(R.id.weather_current_progressbar).setVisibility(View.GONE);
-        this.getActivity().findViewById(R.id.weather_current_error_message).setVisibility(View.GONE);       
-    }
-    
-    private boolean isDataFresh(final Date lastUpdate) {
-       if (lastUpdate == null) {
-               return false;
-       }
-       
-       final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(
-                       this.getActivity().getApplicationContext());
-        final String keyPreference = this.getString(R.string.weather_preferences_refresh_interval_key);
-        final String refresh = sharedPreferences.getString(
-                       keyPreference,
-                       this.getResources().getStringArray(R.array.weather_preferences_refresh_interval)[0]);
-        final Date currentTime = new Date();
-       if (((currentTime.getTime() - lastUpdate.getTime())) < Long.valueOf(refresh)) {
-               return true;
-       }
-       
-       return false;
-    }
-    
-    // TODO: How could I show just one progress dialog when I have two fragments in tabs
-    //       activity doing the same in background?
-    //       I mean, if OverviewTask shows one progress dialog and CurrentTask does the same I will have
-    //       have two progress dialogs... How may I solve this problem? I HATE ANDROID.
-    private class CurrentTask extends AsyncTask<Object, Void, Current> {
-       // Store the context passed to the AsyncTask when the system instantiates it.
-        private final Context localContext;
-        final CustomHTTPClient HTTPClient;
-        final ServiceParser weatherService;
-
-        public CurrentTask(final Context context, final CustomHTTPClient HTTPClient,
-                       final ServiceParser weatherService) {
-               this.localContext = context;
-            this.HTTPClient = HTTPClient;
-            this.weatherService = weatherService;
-        }
-
-        @Override
-        protected Current doInBackground(final Object... params) {
-               final double latitude = (Double) params[0];
-            final double longitude = (Double) params[1];
-  
-            Current current = null;
-            try {
-               current = this.doInBackgroundThrowable(latitude, longitude);
-            } catch (final JsonParseException e) {
-                Log.e(TAG, "CurrentTask doInBackground exception: ", e);
-            } catch (final ClientProtocolException e) {
-                Log.e(TAG, "CurrentTask doInBackground exception: ", e);
-            } catch (final MalformedURLException e) {
-                Log.e(TAG, "CurrentTask doInBackground exception: ", e);
-            } catch (final URISyntaxException e) {
-                Log.e(TAG, "CurrentTask doInBackground exception: ", e);
-            } catch (final IOException e) {
-                // logger infrastructure swallows UnknownHostException :/
-                Log.e(TAG, "CurrentTask doInBackground exception: " + e.getMessage(), e);
-            } finally {
-               HTTPClient.close();
-            }
-
-            return current;
-        }
-
-        private Current doInBackgroundThrowable(final double latitude, final double longitude)
-                        throws URISyntaxException, ClientProtocolException, JsonParseException, IOException {
-
-               final String APIVersion = localContext.getResources().getString(R.string.api_version);
-            final String urlAPI = localContext.getResources().getString(R.string.uri_api_weather_today);
-            final String url = weatherService.createURIAPICurrent(urlAPI, APIVersion, latitude, longitude);
-            final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
-            final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
-            final Current current = weatherService.retrieveCurrentFromJPOS(jsonData);
-            // TODO: what is this for? I guess I could skip it :/
-            final Calendar now = Calendar.getInstance();
-            current.setDate(now.getTime());
-
-            return current;
-        }
-
-        @Override
-        protected void onPostExecute(final Current current) {
-               // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method?
-               // I hope so, otherwise I must catch(Throwable) in doInBackground method :(
-
-            // Call updateUI on the UI thread.
-            final Intent currentData = new Intent("de.example.exampletdd.UPDATECURRENT");
-            currentData.putExtra("current", current);
-            LocalBroadcastManager.getInstance(this.localContext).sendBroadcastSync(currentData);
-        }
-    }
-}
diff --git a/src/de/example/exampletdd/fragment/map/MapButtonsFragment.java b/src/de/example/exampletdd/fragment/map/MapButtonsFragment.java
deleted file mode 100644 (file)
index a063eb5..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.example.exampletdd.fragment.map;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import de.example.exampletdd.R;
-
-public class MapButtonsFragment extends Fragment {
-       
-    @Override
-    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
-                             final Bundle savedInstanceState) {
-    
-       // Inflate the layout for this fragment
-        return inflater.inflate(R.layout.weather_map_buttons, container, false);
-    }
-    
-    /**
-     * This method will only be called once when the retained
-     * Fragment is first created.
-     */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-       super.onCreate(savedInstanceState);
-       
-       // Retain this fragment across configuration changes.
-       this.setRetainInstance(true);
-    }
-}
diff --git a/src/de/example/exampletdd/fragment/map/MapProgressFragment.java b/src/de/example/exampletdd/fragment/map/MapProgressFragment.java
deleted file mode 100644 (file)
index aa4b6e4..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-package de.example.exampletdd.fragment.map;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Locale;
-
-import android.app.Activity;
-import android.content.Context;
-import android.location.Address;
-import android.location.Geocoder;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import de.example.exampletdd.R;
-import de.example.exampletdd.model.WeatherLocation;
-
-/**
- * {@link http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html}
- *
- */
-public class MapProgressFragment extends Fragment {
-
-       /**
-        * 
-        * Callback interface through which the fragment will report the
-        * task's progress and results back to the Activity.
-        */
-       public static interface TaskCallbacks {
-               void onPostExecute(final WeatherLocation weatherLocation);
-       }
-       
-       private TaskCallbacks mCallbacks;
-       
-    @Override
-    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
-                             final Bundle savedInstanceState) {
-    
-       // Inflate the layout for this fragment
-        return inflater.inflate(R.layout.weather_map_progress, container, false);
-    }
-    
-    /**
-     * This method will only be called once when the retained
-     * Fragment is first created.
-     */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-       super.onCreate(savedInstanceState);
-       
-       // Retain this fragment across configuration changes.
-       this.setRetainInstance(true);
-       
-       final Bundle bundle = this.getArguments();
-       double latitude = bundle.getDouble("latitude");
-       double longitude = bundle.getDouble("longitude");
-       
-       // Create and execute the background task.
-       new GetAddressTask(this.getActivity().getApplicationContext()).execute(latitude, longitude);
-    }
-    
-       /**
-        * Hold a reference to the parent Activity so we can report the
-        * task's current progress and results. The Android framework 
-        * will pass us a reference to the newly created Activity after 
-        * each configuration change.
-        */
-       @Override
-       public void onAttach(final Activity activity) {
-               super.onAttach(activity);
-               mCallbacks = (TaskCallbacks) activity;
-       }
-       
-       /**
-        * Set the callback to null so we don't accidentally leak the 
-        * Activity instance.
-        */
-//     @Override
-//     public void onDetach() {
-//             super.onDetach();
-//             mCallbacks = null;
-//     }
-       
-       /**
-        * I am not using onDetach because there are problems when my activity goes to background.
-        * 
-        * {@link http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html}
-        */
-       @Override
-       public void onPause() {
-               super.onPause();
-               mCallbacks = null;
-       }
-    
-    private class GetAddressTask extends AsyncTask<Object, Void, WeatherLocation> {
-        private static final String TAG = "GetAddressTask";
-        // Store the context passed to the AsyncTask when the system instantiates it.
-        private final Context localContext;
-
-        private GetAddressTask(final Context context) {
-               this.localContext = context;    
-        }
-        
-        @Override
-        protected WeatherLocation doInBackground(final Object... params) {
-            final double latitude = (Double) params[0];
-            final double longitude = (Double) params[1];
-
-            WeatherLocation weatherLocation = this.doDefaultLocation(latitude, longitude);
-            try {
-               weatherLocation = this.getLocation(latitude, longitude);
-            } catch (final Throwable e) { // Hopefully nothing goes wrong because of catching Throwable.
-                Log.e(TAG, "GetAddressTask doInBackground exception: ", e);
-            }
-
-            return weatherLocation;
-        }
-
-        @Override
-        protected void onPostExecute(final WeatherLocation weatherLocation) {
-               // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method?
-               // I hope so, otherwise I must catch(Throwable) in doInBackground method :(
-            // Call updateUI on the UI thread.
-               if (mCallbacks != null) {
-                       mCallbacks.onPostExecute(weatherLocation);
-               }
-        }
-        
-        private WeatherLocation getLocation(final double latitude, final double longitude) throws IOException {
-               // TODO: i18n Locale.getDefault()
-            final Geocoder geocoder = new Geocoder(this.localContext, Locale.US);
-            final List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
-
-            // Default values
-            WeatherLocation weatherLocation = this.doDefaultLocation(latitude, longitude);
-            
-            if (addresses != null && addresses.size() > 0) {
-               if (addresses.get(0).getLocality() != null) {
-                       weatherLocation.setCity(addresses.get(0).getLocality());
-               }
-               if(addresses.get(0).getCountryName() != null) {
-                       weatherLocation.setCountry(addresses.get(0).getCountryName());
-               }       
-            }
-
-            return weatherLocation;
-        }
-
-        private WeatherLocation doDefaultLocation(final double latitude, final double longitude) {
-               // Default values
-            String city = this.localContext.getString(R.string.city_not_found);
-            String country = this.localContext.getString(R.string.country_not_found);
-
-            return new WeatherLocation()
-                       .setLatitude(latitude)
-                       .setLongitude(longitude)
-                       .setCity(city)
-                       .setCountry(country);
-        }
-    }
-}
diff --git a/src/de/example/exampletdd/fragment/overview/OverviewAdapter.java b/src/de/example/exampletdd/fragment/overview/OverviewAdapter.java
deleted file mode 100644 (file)
index 13641b6..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-package de.example.exampletdd.fragment.overview;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-import de.example.exampletdd.R;
-
-public class OverviewAdapter extends ArrayAdapter<OverviewEntry> {
-    private final int resource;
-
-    public OverviewAdapter(final Context context, final int resource) {
-        super(context, 0);
-
-        this.resource = resource;
-    }
-
-    @Override
-    public View getView(final int position, final View convertView,
-            final ViewGroup parent) {
-
-        // We need to get the best view (re-used if possible) and then
-        // retrieve its corresponding ViewHolder, which optimizes lookup
-        // efficiency
-        final View view = this.getWorkingView(convertView);
-        final ViewHolder viewHolder = this.getViewHolder(view);
-        final OverviewEntry entry = this.getItem(position);
-
-
-        // Setting date
-        viewHolder.dateNameView.setText(entry.getDateName());
-        viewHolder.dateNumberView.setText(entry.getDateNumber());
-
-        // Setting temperature max/min
-        viewHolder.temperatureMaxView.setText(entry.getMaxTemp());
-        viewHolder.temperatureMinView.setText(entry.getMinTemp());
-
-        // Set image view
-        viewHolder.pictureView.setImageBitmap(entry.getPicture());
-
-
-        return view;
-    }
-
-    private View getWorkingView(final View convertView) {
-        // The workingView is basically just the convertView re-used if possible
-        // or inflated new if not possible
-        View workingView = null;
-
-        if(null == convertView) {
-            final Context context = this.getContext();
-            final LayoutInflater inflater = (LayoutInflater)context.getSystemService
-                    (Context.LAYOUT_INFLATER_SERVICE);
-
-            workingView = inflater.inflate(this.resource, null);
-        } else {
-            workingView = convertView;
-        }
-
-        return workingView;
-    }
-
-    private ViewHolder getViewHolder(final View workingView) {
-        // The viewHolder allows us to avoid re-looking up view references
-        // Since views are recycled, these references will never change
-        final Object tag = workingView.getTag();
-        ViewHolder viewHolder = null;
-
-
-        if((null == tag) || !(tag instanceof ViewHolder)) {
-            viewHolder = new ViewHolder();
-
-            viewHolder.dateNameView = (TextView) workingView
-                    .findViewById(R.id.weather_main_entry_date_name);
-            viewHolder.dateNumberView = (TextView) workingView
-                    .findViewById(R.id.weather_main_entry_date_number);
-            viewHolder.temperatureMaxView = (TextView) workingView
-                    .findViewById(R.id.weather_main_entry_temperature_max);
-            viewHolder.temperatureMinView = (TextView) workingView
-                    .findViewById(R.id.weather_main_entry_temperature_min);
-            viewHolder.pictureView = (ImageView) workingView
-                    .findViewById(R.id.weather_main_entry_image);
-
-            workingView.setTag(viewHolder);
-
-        } else {
-            viewHolder = (ViewHolder) tag;
-        }
-
-        return viewHolder;
-    }
-
-    /**
-     * ViewHolder allows us to avoid re-looking up view references
-     * Since views are recycled, these references will never change
-     */
-    private static class ViewHolder {
-        public TextView dateNameView;
-        public TextView dateNumberView;
-        public TextView temperatureMaxView;
-        public TextView temperatureMinView;
-        public ImageView pictureView;
-    }
-
-}
diff --git a/src/de/example/exampletdd/fragment/overview/OverviewEntry.java b/src/de/example/exampletdd/fragment/overview/OverviewEntry.java
deleted file mode 100644 (file)
index 16135f9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package de.example.exampletdd.fragment.overview;
-
-import android.graphics.Bitmap;
-
-public class OverviewEntry {
-    private final String dateName;
-    private final String dateNumber;
-    private final String maxTemp;
-    private final String minTemp;
-    private final Bitmap picture;
-
-    public OverviewEntry(final String dateName, final String dateNumber,
-            final String maxTemp, final String minTemp,
-            final Bitmap picture) {
-        this.dateName = dateName;
-        this.dateNumber = dateNumber;
-        this.maxTemp = maxTemp;
-        this.minTemp = minTemp;
-        this.picture = picture;
-    }
-
-    public String getDateName() {
-        return this.dateName;
-    }
-
-    public String getDateNumber() {
-        return this.dateNumber;
-    }
-
-    public String getMaxTemp() {
-        return this.maxTemp;
-    }
-
-    public String getMinTemp() {
-        return this.minTemp;
-    }
-
-    public Bitmap getPicture() {
-        return this.picture;
-    }
-}
diff --git a/src/de/example/exampletdd/fragment/overview/OverviewFragment.java b/src/de/example/exampletdd/fragment/overview/OverviewFragment.java
deleted file mode 100644 (file)
index 682e5bd..0000000
+++ /dev/null
@@ -1,410 +0,0 @@
-package de.example.exampletdd.fragment.overview;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.http.client.ClientProtocolException;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.http.AndroidHttpClient;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.support.v4.app.ListFragment;
-import android.support.v4.content.LocalBroadcastManager;
-import android.util.Log;
-import android.view.View;
-import android.widget.ListView;
-
-import com.fasterxml.jackson.core.JsonParseException;
-
-import de.example.exampletdd.R;
-import de.example.exampletdd.fragment.specific.SpecificFragment;
-import de.example.exampletdd.httpclient.CustomHTTPClient;
-import de.example.exampletdd.model.DatabaseQueries;
-import de.example.exampletdd.model.WeatherLocation;
-import de.example.exampletdd.model.forecastweather.Forecast;
-import de.example.exampletdd.parser.JPOSWeatherParser;
-import de.example.exampletdd.service.IconsList;
-import de.example.exampletdd.service.PermanentStorage;
-import de.example.exampletdd.service.ServiceParser;
-
-public class OverviewFragment extends ListFragment {
-    private static final String TAG = "OverviewFragment";
-    private BroadcastReceiver mReceiver;
-
-    @Override
-    public void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    public void onActivityCreated(final Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        final ListView listWeatherView = this.getListView();
-        listWeatherView.setChoiceMode(ListView.CHOICE_MODE_NONE);
-
-        if (savedInstanceState != null) {
-            // Restore UI state
-            final Forecast forecast = (Forecast) savedInstanceState.getSerializable("Forecast");
-
-            // TODO: Could it be better to store in global forecast data even if it is null value?
-            //       So, perhaps do not check for null value and always store in global variable.
-            if (forecast != null) {
-               final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-               store.saveForecast(forecast);
-            }
-        }
-
-        this.setHasOptionsMenu(false);
-
-        this.setEmptyText(this.getString(R.string.text_field_remote_error));
-        this.setListShownNoAnimation(false);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        this.mReceiver = new BroadcastReceiver() {
-
-                       @Override
-                       public void onReceive(final Context context, final Intent intent) {
-                               final String action = intent.getAction();
-                               if (action.equals("de.example.exampletdd.UPDATEFORECAST")) {
-                                       final Forecast forecastRemote = (Forecast) intent.getSerializableExtra("forecast");
-
-                                       if (forecastRemote != null) {
-
-                                               // 1. Check conditions. They must be the same as the ones that triggered the AsyncTask.
-                                               final DatabaseQueries query = new DatabaseQueries(context.getApplicationContext());
-                                   final WeatherLocation weatherLocation = query.queryDataBase();
-                                   final PermanentStorage store = new PermanentStorage(context.getApplicationContext());
-                                   final Forecast forecast = store.getForecast();
-
-                                       if (forecast == null || !OverviewFragment.this.isDataFresh(weatherLocation.getLastForecastUIUpdate())) {
-                                               // 2. Update UI.
-                                               OverviewFragment.this.updateUI(forecastRemote);
-
-                                               // 3. Update Data.
-                                               store.saveForecast(forecastRemote);
-                                           weatherLocation.setLastForecastUIUpdate(new Date());
-                                           query.updateDataBase(weatherLocation);
-
-                                           // 4. Show list.
-                                           OverviewFragment.this.setListShownNoAnimation(true);
-                                       }
-
-                                       } else {
-                                               // Empty list and show error message (see setEmptyText in onCreate)
-                                               OverviewFragment.this.setListAdapter(null);
-                                               OverviewFragment.this.setListShownNoAnimation(true);
-                                       }
-                               }
-                       }
-        };
-
-        // Register receiver
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction("de.example.exampletdd.UPDATEFORECAST");
-        LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext())
-                                                       .registerReceiver(this.mReceiver, filter);
-
-        final DatabaseQueries query = new DatabaseQueries(this.getActivity().getApplicationContext());
-        final WeatherLocation weatherLocation = query.queryDataBase();
-        if (weatherLocation == null) {
-            // Nothing to do.
-               // Empty list and show error message (see setEmptyText in onCreate)
-                       this.setListAdapter(null);
-                       this.setListShownNoAnimation(true);
-            return;
-        }
-
-        final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-        final Forecast forecast = store.getForecast();
-
-        // TODO: store forecast data in permanent storage and check here if there is data in permanent storage
-        if (forecast != null && this.isDataFresh(weatherLocation.getLastForecastUIUpdate())) {
-            this.updateUI(forecast);
-        } else {
-            // Load remote data (aynchronous)
-            // Gets the data from the web.
-            this.setListShownNoAnimation(false);
-            final OverviewTask task = new OverviewTask(
-                       this.getActivity().getApplicationContext(),
-                    new CustomHTTPClient(AndroidHttpClient.newInstance("Android 4.3 WeatherInformation Agent")),
-                    new ServiceParser(new JPOSWeatherParser()));
-
-            task.execute(weatherLocation.getLatitude(), weatherLocation.getLongitude());
-            // TODO: make sure thread UI keeps running in parallel after that. I guess.
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(final Bundle savedInstanceState) {
-
-        // Save UI state
-       final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-        final Forecast forecast = store.getForecast();
-
-        // TODO: Could it be better to save forecast data even if it is null value?
-        //       So, perhaps do not check for null value.
-        if (forecast != null) {
-            savedInstanceState.putSerializable("Forecast", forecast);
-        }
-
-        super.onSaveInstanceState(savedInstanceState);
-    }
-
-    @Override
-    public void onPause() {
-        LocalBroadcastManager.getInstance(this.getActivity().getApplicationContext()).unregisterReceiver(this.mReceiver);
-
-        super.onPause();
-    }
-
-    @Override
-    public void onListItemClick(final ListView l, final View v, final int position, final long id) {
-        final SpecificFragment fragment = (SpecificFragment) this
-                .getFragmentManager().findFragmentById(R.id.weather_specific_fragment);
-        if (fragment == null) {
-            // handset layout
-            final Intent intent = new Intent("de.example.exampletdd.WEATHERINFO")
-            .setComponent(new ComponentName("de.example.exampletdd",
-                    "de.example.exampletdd.SpecificActivity"));
-            intent.putExtra("CHOSEN_DAY", (int) id);
-            OverviewFragment.this.getActivity().startActivity(intent);
-        } else {
-            // tablet layout
-            fragment.updateUIByChosenDay((int) id);
-        }
-    }
-
-    private interface UnitsConversor {
-       
-       public double doConversion(final double value);
-    }
-    
-    private void updateUI(final Forecast forecastWeatherData) {
-
-        final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this.getActivity().getApplicationContext());
-
-        // TODO: repeating the same code in Overview, Specific and Current!!!
-        // 1. Update units of measurement.
-        String symbol;
-        UnitsConversor unitsConversor;
-        String keyPreference = this.getResources().getString(
-                R.string.weather_preferences_temperature_key);
-        final String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
-        if (unitsPreferenceValue.equals(values[0])) {
-               symbol = values[0];
-               unitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value - 273.15;
-                               }
-                       
-               };
-        } else if (unitsPreferenceValue.equals(values[1])) {
-               symbol = values[1];
-               unitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return (value * 1.8) - 459.67;
-                               }
-                       
-               };
-        } else {
-               symbol = values[2];
-               unitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value;
-                               }
-                       
-               };
-        }
-
-
-        // 2. Update number day forecast.
-        keyPreference = this.getResources().getString(R.string.weather_preferences_day_forecast_key);
-        final String dayForecast = sharedPreferences.getString(keyPreference, "5");
-        final int mDayForecast = Integer.valueOf(dayForecast);
-
-
-        // 3. Formatters
-        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
-        tempFormatter.applyPattern("#####.##");
-        final SimpleDateFormat dayNameFormatter = new SimpleDateFormat("EEE", Locale.US);
-        final SimpleDateFormat monthAndDayNumberormatter = new SimpleDateFormat("MMM d", Locale.US);
-
-
-        // 4. Prepare data for UI.
-        final List<OverviewEntry> entries = new ArrayList<OverviewEntry>();
-        final OverviewAdapter adapter = new OverviewAdapter(this.getActivity(),
-                R.layout.weather_main_entry_list);
-        final Calendar calendar = Calendar.getInstance();
-        int count = mDayForecast;
-        for (final de.example.exampletdd.model.forecastweather.List forecast : forecastWeatherData
-                .getList()) {
-
-            Bitmap picture;
-
-            if ((forecast.getWeather().size() > 0) &&
-                    (forecast.getWeather().get(0).getIcon() != null) &&
-                    (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) {
-                final String icon = forecast.getWeather().get(0).getIcon();
-                picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
-                        .getResourceDrawable());
-            } else {
-                picture = BitmapFactory.decodeResource(this.getResources(),
-                        R.drawable.weather_severe_alert);
-            }
-
-            final Long forecastUNIXDate = (Long) forecast.getDt();
-            calendar.setTimeInMillis(forecastUNIXDate * 1000L);
-            final Date dayTime = calendar.getTime();
-            final String dayTextName = dayNameFormatter.format(dayTime);
-            final String monthAndDayNumberText = monthAndDayNumberormatter.format(dayTime);
-
-            Double maxTemp = null;
-            if (forecast.getTemp().getMax() != null) {
-                maxTemp = (Double) forecast.getTemp().getMax();
-                maxTemp = unitsConversor.doConversion(maxTemp);
-            }
-
-            Double minTemp = null;
-            if (forecast.getTemp().getMin() != null) {
-                minTemp = (Double) forecast.getTemp().getMin();
-                minTemp = unitsConversor.doConversion(minTemp);
-            }
-
-            if ((maxTemp != null) && (minTemp != null)) {
-                entries.add(new OverviewEntry(dayTextName, monthAndDayNumberText,
-                        tempFormatter.format(maxTemp) + symbol, tempFormatter.format(minTemp) + symbol,
-                        picture));
-            }
-
-            count = count - 1;
-            if (count == 0) {
-                break;
-            }
-        }
-
-
-        // 5. Update UI.
-        adapter.addAll(entries);
-        this.setListAdapter(adapter);
-    }
-
-    private boolean isDataFresh(final Date lastUpdate) {
-       if (lastUpdate == null) {
-               return false;
-       }
-       
-       final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(
-                       this.getActivity().getApplicationContext());
-        final String keyPreference = this.getString(R.string.weather_preferences_refresh_interval_key);
-        final String refresh = sharedPreferences.getString(
-                       keyPreference,
-                       this.getResources().getStringArray(R.array.weather_preferences_refresh_interval)[0]);
-        final Date currentTime = new Date();
-       if (((currentTime.getTime() - lastUpdate.getTime())) < Long.valueOf(refresh)) {
-               return true;
-       }
-       
-       return false;
-    }
-
-    // TODO: How could I show just one progress dialog when I have two fragments in tabs
-    //       activity doing the same in background?
-    //       I mean, if OverviewTask shows one progress dialog and CurrentTask does the same I will have
-    //       have two progress dialogs... How may I solve this problem? I HATE ANDROID.
-    private class OverviewTask extends AsyncTask<Object, Void, Forecast> {
-       // Store the context passed to the AsyncTask when the system instantiates it.
-        private final Context localContext;
-        private final CustomHTTPClient HTTPClient;
-        private final ServiceParser weatherService;
-
-        public OverviewTask(final Context context, final CustomHTTPClient HTTPClient,
-                       final ServiceParser weatherService) {
-               this.localContext = context;
-            this.HTTPClient = HTTPClient;
-            this.weatherService = weatherService;
-        }
-        
-        @Override
-        protected Forecast doInBackground(final Object... params) {
-            final double latitude = (Double) params[0];
-            final double longitude = (Double) params[1];
-
-            Forecast forecast = null;
-
-            try {
-                forecast = this.doInBackgroundThrowable(latitude, longitude);
-            } catch (final JsonParseException e) {
-                Log.e(TAG, "OverviewTask doInBackground exception: ", e);
-            } catch (final ClientProtocolException e) {
-                Log.e(TAG, "OverviewTask doInBackground exception: ", e);
-            } catch (final MalformedURLException e) {
-                Log.e(TAG, "OverviewTask doInBackground exception: ", e);
-            } catch (final URISyntaxException e) {
-                Log.e(TAG, "OverviewTask doInBackground exception: ", e);
-            } catch (final IOException e) {
-                // logger infrastructure swallows UnknownHostException :/
-                Log.e(TAG, "OverviewTask doInBackground exception: " + e.getMessage(), e);
-            } finally {
-               HTTPClient.close();
-            }
-
-            return forecast;
-        }
-
-        private Forecast doInBackgroundThrowable(final double latitude, final double longitude)
-                        throws URISyntaxException, ClientProtocolException, JsonParseException, IOException {
-
-            final String APIVersion = localContext.getResources().getString(R.string.api_version);
-            final String urlAPI = localContext.getResources().getString(R.string.uri_api_weather_forecast);
-            // TODO: number as resource
-            final String url = weatherService.createURIAPIForecast(urlAPI, APIVersion, latitude, longitude, "14");
-            final String urlWithoutCache = url.concat("&time=" + System.currentTimeMillis());
-            final String jsonData = HTTPClient.retrieveDataAsString(new URL(urlWithoutCache));
-
-            return weatherService.retrieveForecastFromJPOS(jsonData);
-        }
-
-        @Override
-        protected void onPostExecute(final Forecast forecast) {
-               // TODO: Is AsyncTask calling this method even when RunTimeException in doInBackground method?
-               // I hope so, otherwise I must catch(Throwable) in doInBackground method :(
-               
-            // Call updateUI on the UI thread.
-               final Intent forecastData = new Intent("de.example.exampletdd.UPDATEFORECAST");
-               forecastData.putExtra("forecast", forecast);
-            LocalBroadcastManager.getInstance(this.localContext).sendBroadcastSync(forecastData);
-        }
-    }
-}
diff --git a/src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java b/src/de/example/exampletdd/fragment/preferences/WeatherInformationPreferencesFragment.java
deleted file mode 100644 (file)
index ba19c5e..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-package de.example.exampletdd.fragment.preferences;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.preference.Preference;
-import android.preference.PreferenceFragment;
-import android.preference.SwitchPreference;
-import de.example.exampletdd.R;
-import de.example.exampletdd.NotificationIntentService;
-
-public class WeatherInformationPreferencesFragment extends PreferenceFragment 
-                                                                                                       implements OnSharedPreferenceChangeListener {
-
-    @Override
-    public void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Load the preferences from an XML resource
-        this.addPreferencesFromResource(R.xml.weather_preferences);
-        
-        
-        // Temperature units
-        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
-        String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value);
-        String keyPreference = this.getActivity().getApplicationContext().getString(
-                R.string.weather_preferences_temperature_key);
-        Preference connectionPref = this.findPreference(keyPreference);
-        String value = this.getPreferenceManager().getSharedPreferences()
-                .getString(keyPreference, "");
-        String humanValue = "";
-        if (value.equals(values[0])) {
-            humanValue = humanValues[0];
-        } else if (value.equals(values[1])) {
-            humanValue = humanValues[1];
-        } else if (value.equals(values[2])) {
-            humanValue = humanValues[2];
-        }
-        connectionPref.setSummary(humanValue);
-        
-        // Wind
-        values = this.getResources().getStringArray(R.array.weather_preferences_wind);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_wind_human_value);
-        keyPreference = this.getString(R.string.weather_preferences_wind_key);
-        connectionPref = this.findPreference(keyPreference);
-        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
-        humanValue = "";
-        if (value.equals(values[0])) {
-            humanValue = humanValues[0];
-        } else if (value.equals(values[1])) {
-            humanValue = humanValues[1];
-        }
-        connectionPref.setSummary(humanValue);
-
-        // Pressure
-        values = this.getResources().getStringArray(R.array.weather_preferences_pressure);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_pressure_human_value);
-        keyPreference = this.getString(R.string.weather_preferences_pressure_key);
-        connectionPref = this.findPreference(keyPreference);
-        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
-        humanValue = "";
-        if (value.equals(values[0])) {
-            humanValue = humanValues[0];
-        } else if (value.equals(values[1])) {
-            humanValue = humanValues[1];
-        }
-        connectionPref.setSummary(humanValue);
-
-        // Forecast days number
-        values = this.getResources().getStringArray(R.array.weather_preferences_day_forecast);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_day_forecast_human_value);
-        keyPreference = this.getActivity().getApplicationContext().getString(
-                R.string.weather_preferences_day_forecast_key);
-        connectionPref = this.findPreference(keyPreference);
-        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
-        humanValue = "";
-        if (value.equals(values[0])) {
-            humanValue = humanValues[0];
-        } else if (value.equals(values[1])) {
-            humanValue = humanValues[1];
-        } else if (value.equals(values[2])) {
-            humanValue = humanValues[2];
-        }
-        connectionPref.setSummary(humanValue);
-
-        // Refresh interval
-        values = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval_human_value);
-        keyPreference = this.getActivity().getApplicationContext().getString(
-                R.string.weather_preferences_refresh_interval_key);
-        connectionPref = this.findPreference(keyPreference);
-        value = this.getPreferenceManager().getSharedPreferences().getString(keyPreference, "");
-        humanValue = "";
-        if (value.equals(values[0])) {
-            humanValue = humanValues[0];
-        } else if (value.equals(values[1])) {
-            humanValue = humanValues[1];
-        } else if (value.equals(values[2])) {
-            humanValue = humanValues[2];
-        } else if (value.equals(values[3])) {
-            humanValue = humanValues[3];
-        } else if (value.equals(values[4])) {
-            humanValue = humanValues[4];
-        } else if (value.equals(values[5])) {
-            humanValue = humanValues[5];
-        } else if (value.equals(values[6])) {
-            humanValue = humanValues[6];
-        }
-        connectionPref.setSummary(humanValue);
-
-        // Update Time Rate
-        values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate_human_value);
-        keyPreference = this.getActivity().getApplicationContext().getString(
-                R.string.weather_preferences_update_time_rate_key);
-        connectionPref = this.findPreference(keyPreference);
-        value = this.getPreferenceManager().getSharedPreferences()
-                .getString(keyPreference, "");
-        humanValue = "";
-        if (value.equals(values[0])) {
-            humanValue = humanValues[0];
-        } else if (value.equals(values[1])) {
-            humanValue = humanValues[1];
-        } else if (value.equals(values[2])) {
-            humanValue = humanValues[2];
-        } else if (value.equals(values[3])) {
-            humanValue = humanValues[3];
-        } else if (value.equals(values[4])) {
-            humanValue = humanValues[4];
-        }
-        connectionPref.setSummary(humanValue);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        this.getPreferenceManager().getSharedPreferences()
-        .registerOnSharedPreferenceChangeListener(this);
-
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        this.getPreferenceManager().getSharedPreferences()
-        .unregisterOnSharedPreferenceChangeListener(this);
-    }
-
-    @Override
-    public void onSharedPreferenceChanged(
-            final SharedPreferences sharedPreferences, final String key) {
-       
-       // Temperature units
-       String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
-       String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value);
-        String keyValue = this.getActivity().getApplicationContext().getString(
-                R.string.weather_preferences_temperature_key);
-        if (key.equals(keyValue)) {
-               final Preference connectionPref = this.findPreference(key);
-            final String value = sharedPreferences.getString(key, "");
-               String humanValue = "";
-               if (value.equals(values[0])) {
-                       humanValue = humanValues[0];
-               } else if (value.equals(values[1])) {
-                       humanValue = humanValues[1];
-               } else if (value.equals(values[2])) {
-                       humanValue = humanValues[2];
-               }
-
-               connectionPref.setSummary(humanValue);
-               return;
-        }
-
-        // Wind
-        values = this.getResources().getStringArray(R.array.weather_preferences_wind);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_wind_human_value);
-        keyValue = this.getString(R.string.weather_preferences_wind_key);
-        if (key.equals(keyValue)) {
-            final Preference connectionPref = this.findPreference(key);
-            final String value = sharedPreferences.getString(key, "");
-            String humanValue = "";
-            if (value.equals(values[0])) {
-               humanValue = humanValues[0];
-            } else if (value.equals(values[1])) {
-               humanValue = humanValues[1];
-            }
-        
-               connectionPref.setSummary(humanValue);
-               return;
-        }
-
-        // Pressure
-        values = this.getResources().getStringArray(R.array.weather_preferences_pressure);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_pressure_human_value);
-        keyValue = this.getString(R.string.weather_preferences_pressure_key);
-        if (key.equals(keyValue)) {
-            final Preference connectionPref = this.findPreference(key);
-            final String value = sharedPreferences.getString(key, "");
-            String humanValue = "";
-            if (value.equals(values[0])) {
-               humanValue = humanValues[0];
-            } else if (value.equals(values[1])) {
-               humanValue = humanValues[1];
-            }
-        
-               connectionPref.setSummary(humanValue);
-               return;
-        }
-
-        // Forecast days number
-        values = this.getResources().getStringArray(R.array.weather_preferences_day_forecast);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_day_forecast_human_value);
-        keyValue = this.getActivity().getString(
-                R.string.weather_preferences_day_forecast_key);
-        if (key.equals(keyValue)) {
-            final Preference connectionPref = this.findPreference(key);
-            final String value = sharedPreferences.getString(key, "");
-            String humanValue = "";
-            if (value.equals(values[0])) {
-                humanValue = humanValues[0];
-            } else if (value.equals(values[1])) {
-                humanValue = humanValues[1];
-            } else if (value.equals(values[2])) {
-                humanValue = humanValues[2];
-            }
-            connectionPref.setSummary(humanValue);
-            return;
-        }
-
-        // Refresh interval
-        values = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_refresh_interval_human_value);
-        keyValue = this.getActivity().getApplicationContext().getString(
-                R.string.weather_preferences_refresh_interval_key);
-        if (key.equals(keyValue)) {
-               final Preference connectionPref = this.findPreference(key);
-            final String value = sharedPreferences.getString(key, "");
-            String humanValue = "";
-            if (value.equals(values[0])) {
-                humanValue = humanValues[0];
-            } else if (value.equals(values[1])) {
-                humanValue = humanValues[1];
-            } else if (value.equals(values[2])) {
-                humanValue = humanValues[2];
-            } else if (value.equals(values[3])) {
-                humanValue = humanValues[3];
-            } else if (value.equals(values[4])) {
-                humanValue = humanValues[4];
-            } else if (value.equals(values[5])) {
-                humanValue = humanValues[5];
-            } else if (value.equals(values[6])) {
-                humanValue = humanValues[6];
-            }
-            connectionPref.setSummary(humanValue);
-            return;
-        }
-
-        // Notification switch
-        keyValue = this.getActivity().getApplicationContext().getString(
-                       R.string.weather_preferences_notifications_switch_key);
-        if (key.equals(keyValue)) {
-               final SwitchPreference preference = (SwitchPreference)this.findPreference(key);
-               if (preference.isChecked())
-               {
-                       keyValue = this.getActivity().getApplicationContext().getString(
-                               R.string.weather_preferences_update_time_rate_key);
-                       final String value = sharedPreferences.getString(keyValue, "");
-                       this.updateNotification(value);
-               } else {
-                       this.cancelNotification();
-               }
-        }
-        // Update Time Rate
-        values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate);
-        humanValues = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate_human_value);
-        keyValue = this.getActivity().getApplicationContext().getString(
-                       R.string.weather_preferences_update_time_rate_key);
-        if (key.equals(keyValue)) {
-            final Preference connectionPref = this.findPreference(key);
-            final String value = sharedPreferences.getString(key, "");
-            String humanValue = "";
-            if (value.equals(values[0])) {
-                humanValue = humanValues[0];
-            } else if (value.equals(values[1])) {
-                humanValue = humanValues[1];
-            } else if (value.equals(values[2])) {
-                humanValue = humanValues[2];
-            } else if (value.equals(values[3])) {
-                humanValue = humanValues[3];
-            } else if (value.equals(values[4])) {
-                humanValue = humanValues[4];
-            }
-
-            this.updateNotification(value);
-            connectionPref.setSummary(humanValue);
-            return;
-        }
-    }
-
-    private void updateNotification(final String updateTimeRate) {
-       final String[] values = this.getResources().getStringArray(R.array.weather_preferences_update_time_rate);
-        long chosenInterval = 0;
-        if (updateTimeRate.equals(values[0])) {
-               chosenInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
-        } else if (updateTimeRate.equals(values[1])) {
-               chosenInterval = AlarmManager.INTERVAL_HALF_HOUR;
-        } else if (updateTimeRate.equals(values[2])) {
-               chosenInterval = AlarmManager.INTERVAL_HOUR;
-        } else if (updateTimeRate.equals(values[3])) {
-               chosenInterval = AlarmManager.INTERVAL_HALF_DAY;
-        } else if (updateTimeRate.equals(values[4])) {
-               chosenInterval = AlarmManager.INTERVAL_DAY;
-        }
-
-        final AlarmManager alarmMgr =
-                       (AlarmManager) this.getActivity().getApplicationContext().getSystemService(Context.ALARM_SERVICE);
-        // TODO: better use some string instead of .class? In case I change the service class
-        // this could be a problem (I guess)
-        final Intent serviceIntent =
-                       new Intent(this.getActivity().getApplicationContext(), NotificationIntentService.class);
-        final PendingIntent alarmIntent =
-                       PendingIntent.getService(
-                                       this.getActivity().getApplicationContext(),
-                                       0,
-                                       serviceIntent,
-                                       PendingIntent.FLAG_UPDATE_CURRENT);
-        if (chosenInterval != 0) {   
-            alarmMgr.setInexactRepeating(
-                       AlarmManager.ELAPSED_REALTIME,
-                       SystemClock.elapsedRealtime(),
-                       chosenInterval,
-                       alarmIntent);
-        }
-    }
-
-    private void cancelNotification() {
-       final AlarmManager alarmMgr =
-                       (AlarmManager) this.getActivity().getApplicationContext().getSystemService(Context.ALARM_SERVICE);
-       final Intent serviceIntent =
-                       new Intent(this.getActivity().getApplicationContext(), NotificationIntentService.class);
-       final PendingIntent alarmIntent =
-                       PendingIntent.getService(
-                                       this.getActivity().getApplicationContext(),
-                                       0,
-                                       serviceIntent,
-                                       PendingIntent.FLAG_UPDATE_CURRENT);
-       alarmMgr.cancel(alarmIntent);
-    }
-}
diff --git a/src/de/example/exampletdd/fragment/specific/SpecificFragment.java b/src/de/example/exampletdd/fragment/specific/SpecificFragment.java
deleted file mode 100644 (file)
index e355c71..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-package de.example.exampletdd.fragment.specific;
-
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-import de.example.exampletdd.R;
-import de.example.exampletdd.model.forecastweather.Forecast;
-import de.example.exampletdd.service.IconsList;
-import de.example.exampletdd.service.PermanentStorage;
-
-
-public class SpecificFragment extends Fragment {
-    private int mChosenDay;
-
-    @Override
-    public void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        final Bundle extras = this.getActivity().getIntent().getExtras();
-
-        if (extras != null) {
-               // handset layout
-            this.mChosenDay = extras.getInt("CHOSEN_DAY", 0);
-        } else {
-               // tablet layout
-               // Always 0 when tablet layout (by default shows the first day)
-            this.mChosenDay = 0;
-        }
-    }
-    
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                             Bundle savedInstanceState) {
-    
-       // Inflate the layout for this fragment
-        return inflater.inflate(R.layout.weather_specific_fragment, container, false);
-    }
-    
-    @Override
-    public void onActivityCreated(final Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        if (savedInstanceState != null) {
-               // Restore UI state
-            final Forecast forecast = (Forecast) savedInstanceState.getSerializable("Forecast");
-
-            // TODO: Could it be better to store in global data forecast even if it is null value?
-            //       So, perhaps do not check for null value and always store in global variable.
-            if (forecast != null) {
-               final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-               store.saveForecast(forecast);
-            }
-
-            this.mChosenDay = savedInstanceState.getInt("mChosenDay");
-        }
-
-        this.setHasOptionsMenu(false);
-    }
-
-    @Override
-    public void onSaveInstanceState(final Bundle savedInstanceState) {
-
-        // Save UI state
-       final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-        final Forecast forecast = store.getForecast();
-
-        // TODO: Could it be better to save forecast data even if it is null value?
-        //       So, perhaps do not check for null value.
-        if (forecast != null) {
-            savedInstanceState.putSerializable("Forecast", forecast);
-        }
-
-        savedInstanceState.putInt("mChosenDay", this.mChosenDay);
-
-        super.onSaveInstanceState(savedInstanceState);
-    }
-
-    /**
-     * This method is used by tablet layout.
-     * 
-     * @param chosenDay
-     */
-    public void updateUIByChosenDay(final int chosenDay) {
-       final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-        final Forecast forecast = store.getForecast();
-
-        if (forecast != null) {
-            this.updateUI(forecast, chosenDay);
-        }
-    }
-
-    private interface UnitsConversor {
-       
-       public double doConversion(final double value);
-    }
-
-    private void updateUI(final Forecast forecastWeatherData, final int chosenDay) {
-
-        final SharedPreferences sharedPreferences = PreferenceManager
-                .getDefaultSharedPreferences(this.getActivity());
-
-        // TODO: repeating the same code in Overview, Specific and Current!!!
-        // 1. Update units of measurement.
-        // 1.1 Temperature
-        String tempSymbol;
-        UnitsConversor tempUnitsConversor;
-        String keyPreference = this.getResources().getString(
-                R.string.weather_preferences_temperature_key);
-        String unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
-        if (unitsPreferenceValue.equals(values[0])) {
-               tempSymbol = values[0];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value - 273.15;
-                               }
-                       
-               };
-        } else if (unitsPreferenceValue.equals(values[1])) {
-               tempSymbol = values[1];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return (value * 1.8) - 459.67;
-                               }
-                       
-               };
-        } else {
-               tempSymbol = values[2];
-               tempUnitsConversor = new UnitsConversor(){
-
-                               @Override
-                               public double doConversion(final double value) {
-                                       return value;
-                               }
-                       
-               };
-        }
-
-        // 1.2 Wind
-        String windSymbol;
-        UnitsConversor windUnitsConversor;
-        keyPreference = this.getResources().getString(R.string.weather_preferences_wind_key);
-        unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        values = this.getResources().getStringArray(R.array.weather_preferences_wind);
-        if (unitsPreferenceValue.equals(values[0])) {
-               windSymbol = values[0];
-               windUnitsConversor = new UnitsConversor(){
-
-                       @Override
-                       public double doConversion(double value) {
-                               return value;
-                       }       
-               };
-        } else {
-               windSymbol = values[1];
-               windUnitsConversor = new UnitsConversor(){
-
-                       @Override
-                       public double doConversion(double value) {
-                               return value * 2.237;
-                       }       
-               };
-        }
-
-        // 1.3 Pressure
-        String pressureSymbol;
-        UnitsConversor pressureUnitsConversor;
-        keyPreference = this.getResources().getString(R.string.weather_preferences_pressure_key);
-        unitsPreferenceValue = sharedPreferences.getString(keyPreference, "");
-        values = this.getResources().getStringArray(R.array.weather_preferences_pressure);
-        if (unitsPreferenceValue.equals(values[0])) {
-               pressureSymbol = values[0];
-               pressureUnitsConversor = new UnitsConversor(){
-
-                       @Override
-                       public double doConversion(double value) {
-                               return value;
-                       }       
-               };
-        } else {
-               pressureSymbol = values[1];
-               pressureUnitsConversor = new UnitsConversor(){
-
-                       @Override
-                       public double doConversion(double value) {
-                               return value / 113.25d;
-                       }       
-               };
-        }
-
-
-        // 2. Formatters
-        final DecimalFormat tempFormatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
-        tempFormatter.applyPattern("#####.#####");
-        
-
-        // 3. Prepare data for UI.
-        final de.example.exampletdd.model.forecastweather.List forecast = forecastWeatherData
-                .getList().get((chosenDay));
-
-        final SimpleDateFormat dayFormatter = new SimpleDateFormat("EEEE - MMM d", Locale.US);
-        final Calendar calendar = Calendar.getInstance();
-        final Long forecastUNIXDate = (Long) forecast.getDt();
-        calendar.setTimeInMillis(forecastUNIXDate * 1000L);
-        final Date date = calendar.getTime();     
-
-        String tempMax = "";
-        if (forecast.getTemp().getMax() != null) {
-            double conversion = (Double) forecast.getTemp().getMax();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempMax = tempFormatter.format(conversion) + tempSymbol;
-        }        
-        String tempMin = "";
-        if (forecast.getTemp().getMin() != null) {
-            double conversion = (Double) forecast.getTemp().getMin();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempMin = tempFormatter.format(conversion) + tempSymbol;
-        }
-        Bitmap picture;
-        if ((forecast.getWeather().size() > 0) && (forecast.getWeather().get(0).getIcon() != null)
-                && (IconsList.getIcon(forecast.getWeather().get(0).getIcon()) != null)) {
-            final String icon = forecast.getWeather().get(0).getIcon();
-            picture = BitmapFactory.decodeResource(this.getResources(), IconsList.getIcon(icon)
-                    .getResourceDrawable());
-        } else {
-            picture = BitmapFactory.decodeResource(this.getResources(),
-                    R.drawable.weather_severe_alert);
-        }       
-
-        // TODO: string resource
-        String description = "no description available";
-        if (forecast.getWeather().size() > 0) {
-            description = forecast.getWeather().get(0).getDescription();
-        }
-
-        // TODO: units!!!!
-        String humidityValue = "";
-        if (forecast.getHumidity() != null) {
-            final double conversion = (Double) forecast.getHumidity();
-            humidityValue = tempFormatter.format(conversion);
-        }        
-        String pressureValue = "";
-        if (forecast.getPressure() != null) {
-            double conversion = (Double) forecast.getPressure();
-            conversion = pressureUnitsConversor.doConversion(conversion);
-            pressureValue = tempFormatter.format(conversion);
-        }
-        String windValue = "";
-        if (forecast.getSpeed() != null) {
-            double conversion = (Double) forecast.getSpeed();
-            conversion = windUnitsConversor.doConversion(conversion);
-            windValue = tempFormatter.format(conversion);
-        }
-        String rainValue = "";
-        if (forecast.getRain() != null) {
-            final double conversion = (Double) forecast.getRain();
-            rainValue = tempFormatter.format(conversion);
-        }
-        String cloudsValue = "";
-        if (forecast.getRain() != null) {
-            final double conversion = (Double) forecast.getClouds();
-            cloudsValue = tempFormatter.format(conversion);
-        }
-
-        String tempDay = "";
-        if (forecast.getTemp().getDay() != null) {
-            double conversion = (Double) forecast.getTemp().getDay();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempDay = tempFormatter.format(conversion) + tempSymbol;
-        }
-        String tempMorn = "";
-        if (forecast.getTemp().getMorn() != null) {
-            double conversion = (Double) forecast.getTemp().getMorn();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempMorn = tempFormatter.format(conversion) + tempSymbol;
-        }
-        String tempEve = "";
-        if (forecast.getTemp().getEve() != null) {
-            double conversion = (Double) forecast.getTemp().getEve();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempEve = tempFormatter.format(conversion) + tempSymbol;
-        }   
-        String tempNight = "";
-        if (forecast.getTemp().getNight() != null) {
-            double conversion = (Double) forecast.getTemp().getNight();
-            conversion = tempUnitsConversor.doConversion(conversion);
-            tempNight = tempFormatter.format(conversion) + tempSymbol;
-        }   
-
-
-        // 4. Update UI.
-        this.getActivity().getActionBar().setSubtitle(dayFormatter.format(date).toUpperCase());
-        
-        final TextView tempMaxView = (TextView) getActivity().findViewById(R.id.weather_specific_temp_max);
-        tempMaxView.setText(tempMax);
-        final TextView tempMinView = (TextView) getActivity().findViewById(R.id.weather_specific_temp_min);
-        tempMinView.setText(tempMin);
-        final ImageView pictureView = (ImageView) getActivity().findViewById(R.id.weather_specific_picture);
-        pictureView.setImageBitmap(picture);    
-        
-        final TextView descriptionView = (TextView) getActivity().findViewById(R.id.weather_specific_description);
-        descriptionView.setText(description);
-        
-        final TextView humidityValueView = (TextView) getActivity().findViewById(R.id.weather_specific_humidity_value);
-        humidityValueView.setText(humidityValue);
-        ((TextView) getActivity().findViewById(R.id.weather_specific_pressure_value)).setText(pressureValue);
-        ((TextView) getActivity().findViewById(R.id.weather_specific_pressure_units)).setText(pressureSymbol);
-        ((TextView) getActivity().findViewById(R.id.weather_specific_wind_value)).setText(windValue);;
-        ((TextView) getActivity().findViewById(R.id.weather_specific_wind_units)).setText(windSymbol);
-        final TextView rainValueView = (TextView) getActivity().findViewById(R.id.weather_specific_rain_value);
-        rainValueView.setText(rainValue);
-        final TextView cloudsValueView = (TextView) getActivity().findViewById(R.id.weather_specific_clouds_value);
-        cloudsValueView.setText(cloudsValue); 
-        
-        final TextView tempDayView = (TextView) getActivity().findViewById(R.id.weather_specific_day_temperature);
-        tempDayView.setText(tempDay);
-        final TextView tempMornView = (TextView) getActivity().findViewById(R.id.weather_specific_morn_temperature);
-        tempMornView.setText(tempMorn);
-        final TextView tempEveView = (TextView) getActivity().findViewById(R.id.weather_specific_eve_temperature);
-        tempEveView.setText(tempEve);
-        final TextView tempNightView = (TextView) getActivity().findViewById(R.id.weather_specific_night_temperature);
-        tempNightView.setText(tempNight);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        final PermanentStorage store = new PermanentStorage(this.getActivity().getApplicationContext());
-        final Forecast forecast = store.getForecast();
-
-        if (forecast != null) {
-            this.updateUI(forecast, this.mChosenDay);
-        }
-        
-        // TODO: Overview is doing things with mListState... Why not here?
-    }
-}
diff --git a/src/de/example/exampletdd/httpclient/Consts.java b/src/de/example/exampletdd/httpclient/Consts.java
deleted file mode 100644 (file)
index 614849f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package de.example.exampletdd.httpclient;
-
-import java.nio.charset.Charset;
-
-/**
- * Commons constants.
- *
- * @since 4.2
- */
-public final class Consts {
-
-    public static final int CR = 13; // <US-ASCII CR, carriage return (13)>
-    public static final int LF = 10; // <US-ASCII LF, linefeed (10)>
-    public static final int SP = 32; // <US-ASCII SP, space (32)>
-    public static final int HT = 9;  // <US-ASCII HT, horizontal-tab (9)>
-
-    public static final Charset UTF_8 = Charset.forName("UTF-8");
-    public static final Charset ASCII = Charset.forName("US-ASCII");
-    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
-
-    private Consts() {
-    }
-
-}
diff --git a/src/de/example/exampletdd/httpclient/ContentType.java b/src/de/example/exampletdd/httpclient/ContentType.java
deleted file mode 100644 (file)
index 8c02532..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package de.example.exampletdd.httpclient;
-
-import java.nio.charset.Charset;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.Locale;
-
-import org.apache.http.Header;
-import org.apache.http.HeaderElement;
-import org.apache.http.HttpEntity;
-import org.apache.http.NameValuePair;
-import org.apache.http.ParseException;
-import org.apache.http.message.BasicHeaderValueParser;
-
-/**
- * Content type information consisting of a MIME type and an optional charset.
- * <p/>
- * This class makes no attempts to verify validity of the MIME type.
- * The input parameters of the {@link #create(String, String)} method, however, may not
- * contain characters <">, <;>, <,> reserved by the HTTP specification.
- *
- * @since 4.2
- */
-
-public final class ContentType {
-
-    // constants
-    public static final ContentType APPLICATION_ATOM_XML = create(
-            "application/atom+xml", Consts.ISO_8859_1);
-    public static final ContentType APPLICATION_FORM_URLENCODED = create(
-            "application/x-www-form-urlencoded", Consts.ISO_8859_1);
-    public static final ContentType APPLICATION_JSON = create(
-            "application/json", Consts.UTF_8);
-    public static final ContentType APPLICATION_OCTET_STREAM = create(
-            "application/octet-stream", (Charset) null);
-    public static final ContentType APPLICATION_SVG_XML = create(
-            "application/svg+xml", Consts.ISO_8859_1);
-    public static final ContentType APPLICATION_XHTML_XML = create(
-            "application/xhtml+xml", Consts.ISO_8859_1);
-    public static final ContentType APPLICATION_XML = create(
-            "application/xml", Consts.ISO_8859_1);
-    public static final ContentType MULTIPART_FORM_DATA = create(
-            "multipart/form-data", Consts.ISO_8859_1);
-    public static final ContentType TEXT_HTML = create(
-            "text/html", Consts.ISO_8859_1);
-    public static final ContentType TEXT_PLAIN = create(
-            "text/plain", Consts.ISO_8859_1);
-    public static final ContentType TEXT_XML = create(
-            "text/xml", Consts.ISO_8859_1);
-    public static final ContentType WILDCARD = create(
-            "*/*", (Charset) null);
-
-    // defaults
-    public static final ContentType DEFAULT_TEXT = TEXT_PLAIN;
-    public static final ContentType DEFAULT_BINARY = APPLICATION_OCTET_STREAM;
-
-    private final String mimeType;
-    private final Charset charset;
-
-    /**
-     * Given a MIME type and a character set, constructs a ContentType.
-     * @param mimeType The MIME type to use for the ContentType header.
-     * @param charset The optional character set to use with the ContentType header.
-     * @throws  UnsupportedCharsetException
-     *          If no support for the named charset is available in this Java virtual machine
-     */
-    ContentType(final String mimeType, final Charset charset) {
-        this.mimeType = mimeType;
-        this.charset = charset;
-    }
-
-    public String getMimeType() {
-        return this.mimeType;
-    }
-
-    public Charset getCharset() {
-        return this.charset;
-    }
-
-    /**
-     * Converts a ContentType to a string which can be used as a ContentType header.
-     * If a charset is provided by the ContentType, it will be included in the string.
-     */
-    @Override
-    public String toString() {
-        final StringBuilder buf = new StringBuilder();
-        buf.append(this.mimeType);
-        if (this.charset != null) {
-            buf.append("; charset=");
-            buf.append(this.charset);
-        }
-        return buf.toString();
-    }
-
-    private static boolean valid(final String s) {
-        for (int i = 0; i < s.length(); i++) {
-            final char ch = s.charAt(i);
-            if ((ch == '"') || (ch == ',') || (ch == ';')) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Creates a new instance of {@link ContentType}.
-     *
-     * @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
-     *        characters <">, <;>, <,> reserved by the HTTP specification.
-     * @param charset charset.
-     * @return content type
-     */
-    public static ContentType create(final String mimeType, final Charset charset) {
-        if (mimeType == null) {
-            throw new IllegalArgumentException("MIME type may not be null");
-        }
-        final String type = mimeType.trim().toLowerCase(Locale.US);
-        if (type.length() == 0) {
-            throw new IllegalArgumentException("MIME type may not be empty");
-        }
-        if (!valid(type)) {
-            throw new IllegalArgumentException("MIME type may not contain reserved characters");
-        }
-        return new ContentType(type, charset);
-    }
-
-    /**
-     * Creates a new instance of {@link ContentType} without a charset.
-     *
-     * @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
-     *        characters <">, <;>, <,> reserved by the HTTP specification.
-     * @return content type
-     */
-    public static ContentType create(final String mimeType) {
-        return new ContentType(mimeType, (Charset) null);
-    }
-
-    /**
-     * Creates a new instance of {@link ContentType}.
-     *
-     * @param mimeType MIME type. It may not be <code>null</code> or empty. It may not contain
-     *        characters <">, <;>, <,> reserved by the HTTP specification.
-     * @param charset charset. It may not contain characters <">, <;>, <,> reserved by the HTTP
-     *        specification. This parameter is optional.
-     * @return content type
-     */
-    public static ContentType create(
-            final String mimeType, final String charset) throws UnsupportedCharsetException {
-        return create(mimeType, charset != null ? Charset.forName(charset) : null);
-    }
-
-    private static ContentType create(final HeaderElement helem) {
-        final String mimeType = helem.getName();
-        String charset = null;
-        final NameValuePair param = helem.getParameterByName("charset");
-        if (param != null) {
-            charset = param.getValue();
-        }
-        return create(mimeType, charset);
-    }
-
-    /**
-     * Parses textual representation of <code>Content-Type</code> value.
-     *
-     * @param s text
-     * @return content type
-     * @throws ParseException if the given text does not represent a valid
-     * <code>Content-Type</code> value.
-     */
-    public static ContentType parse(
-            final String s) throws ParseException, UnsupportedCharsetException {
-        if (s == null) {
-            throw new IllegalArgumentException("Content type may not be null");
-        }
-        final HeaderElement[] elements = BasicHeaderValueParser.parseElements(s, null);
-        if (elements.length > 0) {
-            return create(elements[0]);
-        } else {
-            throw new ParseException("Invalid content type: " + s);
-        }
-    }
-
-    /**
-     * Extracts <code>Content-Type</code> value from {@link HttpEntity} exactly as
-     * specified by the <code>Content-Type</code> header of the entity. Returns <code>null</code>
-     * if not specified.
-     *
-     * @param entity HTTP entity
-     * @return content type
-     * @throws ParseException if the given text does not represent a valid
-     * <code>Content-Type</code> value.
-     */
-    public static ContentType get(
-            final HttpEntity entity) throws ParseException, UnsupportedCharsetException {
-        if (entity == null) {
-            return null;
-        }
-        final Header header = entity.getContentType();
-        if (header != null) {
-            final HeaderElement[] elements = header.getElements();
-            if (elements.length > 0) {
-                return create(elements[0]);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Extracts <code>Content-Type</code> value from {@link HttpEntity} or returns default value
-     * if not explicitly specified.
-     *
-     * @param entity HTTP entity
-     * @return content type
-     * @throws ParseException if the given text does not represent a valid
-     * <code>Content-Type</code> value.
-     */
-    public static ContentType getOrDefault(final HttpEntity entity) throws ParseException {
-        final ContentType contentType = get(entity);
-        return contentType != null ? contentType : DEFAULT_TEXT;
-    }
-
-}
diff --git a/src/de/example/exampletdd/httpclient/CustomHTTPClient.java b/src/de/example/exampletdd/httpclient/CustomHTTPClient.java
deleted file mode 100644 (file)
index ba1bb99..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-package de.example.exampletdd.httpclient;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.net.URL;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.methods.HttpGet;
-
-import android.net.http.AndroidHttpClient;
-
-public class CustomHTTPClient {
-    private final AndroidHttpClient httpClient;
-
-    public CustomHTTPClient(final AndroidHttpClient httpClient) {
-        this.httpClient = httpClient;
-    }
-
-    public String retrieveDataAsString(final URL url)
-            throws URISyntaxException, ClientProtocolException, IOException {
-
-        final ResponseHandler<String> handler = new ResponseHandler<String>() {
-            @Override
-            public String handleResponse(
-                    final HttpResponse response)
-                            throws UnsupportedEncodingException, IOException {
-
-                if (response != null) {
-                    final HttpEntity entity = response.getEntity();
-                    if (entity != null) {
-                        try {
-                            final ContentType contentType = ContentType.getOrDefault(entity);
-                            final ByteArrayOutputStream buffer = CustomHTTPClient.this
-                                    .sortResponse(response);
-                            return new String(buffer.toByteArray(), contentType.getCharset());
-                        } finally {
-                            entity.consumeContent();
-                        }
-                    }
-
-                    throw new IOException("There is no entity");
-                }
-
-                throw new IOException("There is no response");
-            }
-        };
-
-        final HttpGet httpGet = new HttpGet();
-        httpGet.setURI(url.toURI());
-
-        return this.httpClient.execute(httpGet, handler);
-    }
-
-    public ByteArrayOutputStream retrieveRawData(final URL url)
-            throws URISyntaxException, ClientProtocolException, IOException {
-        final ResponseHandler<ByteArrayOutputStream> handler = new ResponseHandler<ByteArrayOutputStream>() {
-
-            @Override
-            public ByteArrayOutputStream handleResponse(
-                    final HttpResponse response)
-                            throws UnsupportedEncodingException, IOException {
-
-                if (response != null) {
-                    final HttpEntity entity = response.getEntity();
-                    if (entity != null) {
-                        try {
-                            return CustomHTTPClient.this.sortResponse(response);
-                        } finally {
-                            entity.consumeContent();
-                        }
-                    }
-
-                    throw new IOException("There is no entity");
-                }
-
-                throw new IOException("There is no response");
-            }
-        };
-
-        final HttpGet httpGet = new HttpGet();
-        httpGet.setURI(url.toURI());
-
-        return this.httpClient.execute(httpGet, handler);
-    }
-
-    public void close() {
-        this.httpClient.close();
-    }
-
-    private ByteArrayOutputStream sortResponse(final HttpResponse httpResponse) throws IOException {
-
-        if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
-            throw new IOException("Unexpected response code: "
-                    + httpResponse.getStatusLine().getStatusCode());
-        }
-
-        final HttpEntity entity = httpResponse.getEntity();
-        final InputStream inputStream = entity.getContent();
-        try {
-            return this.readInputStream(inputStream);
-        } finally {
-            inputStream.close();
-        }
-
-    }
-
-    private ByteArrayOutputStream readInputStream (final InputStream inputStream) throws IOException {
-        final ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
-        final int bufferSize = 1024;
-        final byte[] buffer = new byte[bufferSize];
-
-        int len = 0;
-        while ((len = inputStream.read(buffer)) != -1) {
-            byteBuffer.write(buffer, 0, len);
-        }
-
-        return byteBuffer;
-    }
-}
diff --git a/src/de/example/exampletdd/model/DatabaseQueries.java b/src/de/example/exampletdd/model/DatabaseQueries.java
deleted file mode 100644 (file)
index e53f97d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-package de.example.exampletdd.model;
-
-import android.content.Context;
-
-public class DatabaseQueries {
-       private final Context localContext;
-
-       public DatabaseQueries(final Context context) {
-               this.localContext = context;
-       }
-       
-       public WeatherLocation queryDataBase() {
-        
-        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
-        try {
-               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
-               return queryDb.queryDataBase();
-        } finally {
-               dbHelper.close();
-        } 
-    }
-    
-       public long insertIntoDataBase(final WeatherLocation weatherLocation) {
-        
-        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
-        try {
-               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
-               return queryDb.insertIntoDataBase(weatherLocation);
-        } finally {
-               dbHelper.close();
-        } 
-    }
-    
-       public void updateDataBase(final WeatherLocation weatherLocation) {
-        
-        final WeatherLocationDbHelper dbHelper = new WeatherLocationDbHelper(this.localContext);
-        try {
-               final WeatherLocationDbQueries queryDb = new WeatherLocationDbQueries(dbHelper);        
-               queryDb.updateDataBase(weatherLocation);
-        } finally {
-               dbHelper.close();
-        } 
-    }
-}
diff --git a/src/de/example/exampletdd/model/WeatherLocation.java b/src/de/example/exampletdd/model/WeatherLocation.java
deleted file mode 100644 (file)
index f20b0b6..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-package de.example.exampletdd.model;
-
-import java.io.Serializable;
-import java.util.Date;
-
-
-public class WeatherLocation implements Serializable {
-       private static final long serialVersionUID = -1469725417020355109L;
-       private int id;
-       private String city;
-    private String country;
-    private boolean isSelected;
-    private double latitude;
-    private double longitude;
-    private Date lastCurrentUIUpdate;
-    private Date lastForecastUIUpdate;
-
-    public WeatherLocation setId(int id) {
-               this.id = id;
-               return this;
-       }
-
-       public WeatherLocation setCity(String city) {
-               this.city = city;
-               return this;
-       }
-
-       public WeatherLocation setCountry(String country) {
-               this.country = country;
-               return this;
-       }
-
-       public WeatherLocation setIsSelected(boolean isSelected) {
-               this.isSelected = isSelected;
-               return this;
-       }
-
-       public WeatherLocation setLatitude(double latitude) {
-               this.latitude = latitude;
-               return this;
-       }
-
-       public WeatherLocation setLongitude(double longitude) {
-               this.longitude = longitude;
-               return this;
-       }
-
-       public WeatherLocation setLastCurrentUIUpdate(Date lastCurrentUIUpdate) {
-               this.lastCurrentUIUpdate = lastCurrentUIUpdate;
-               return this;
-       }
-
-       public WeatherLocation setLastForecastUIUpdate(Date lastForecastUIUpdate) {
-               this.lastForecastUIUpdate = lastForecastUIUpdate;
-               return this;
-       }
-
-       public int getId() {
-       return this.id;
-    }
-    
-    public String getCity() {
-        return this.city;
-    }
-
-    public String getCountry() {
-        return this.country;
-    }
-    
-    public boolean getIsSelected() {
-       return this.isSelected;
-    }
-
-    public double getLatitude() {
-        return this.latitude;
-    }
-
-    public double getLongitude() {
-        return this.longitude;
-    }
-    
-    public Date getLastCurrentUIUpdate() {
-       return this.lastCurrentUIUpdate;
-    }
-    
-    public Date getLastForecastUIUpdate() {
-       return this.lastForecastUIUpdate;
-    }
-}
diff --git a/src/de/example/exampletdd/model/WeatherLocationContract.java b/src/de/example/exampletdd/model/WeatherLocationContract.java
deleted file mode 100644 (file)
index 91e3472..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-package de.example.exampletdd.model;
-
-import android.provider.BaseColumns;
-
-public class WeatherLocationContract {
-
-       // This class can't be instantiated
-       private WeatherLocationContract() {}
-       
-       public static final class WeatherLocation implements BaseColumns {
-               
-               // This class can't be instantiated
-               private WeatherLocation() {}
-               
-               public static final String TABLE_NAME = "locations";
-               
-               public static final String COLUMN_NAME_IS_SELECTED = "isSelected";
-               
-               public static final String COLUMN_NAME_LATITUDE = "latitude";
-               
-               public static final String COLUMN_NAME_LONGITUDE = "longitude";
-               
-               public static final String COLUMN_NAME_COUNTRY = "country";
-               
-               public static final String COLUMN_NAME_CITY = "city";
-               
-               public static final String COLUMN_NAME_LAST_FORECAST_UI_UPDATE = "lastForecastUpdate";
-               
-               public static final String COLUMN_NAME_LAST_CURRENT_UI_UPDATE = "lastCurrentUpdate";
-       }
-
-}
diff --git a/src/de/example/exampletdd/model/WeatherLocationDbHelper.java b/src/de/example/exampletdd/model/WeatherLocationDbHelper.java
deleted file mode 100644 (file)
index 8083516..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.example.exampletdd.model;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-public class WeatherLocationDbHelper extends SQLiteOpenHelper {
-       private static final String TAG = "LocationDbHelper";
-       public static final int DATABASE_VERSION = 1;
-    public static final String DATABASE_NAME = "Location.db";
-    
-    public WeatherLocationDbHelper(final Context context) {
-        super(context, DATABASE_NAME, null, DATABASE_VERSION);
-    }
-    
-       @Override
-       public void onCreate(final SQLiteDatabase db) {
-               db.execSQL("CREATE TABLE " + WeatherLocationContract.WeatherLocation.TABLE_NAME + " ("
-                               + WeatherLocationContract.WeatherLocation._ID + " INTEGER PRIMARY KEY, "
-                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY + " TEXT" + " NOT NULL, "
-                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY + " TEXT" + " NOT NULL, "
-                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " INTEGER" + " NOT NULL, "
-                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE + " INTEGER, "
-                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE + " INTEGER, "
-                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE + " REAL" + " NOT NULL, "
-                               + WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE + " REAL" + " NOT NULL "
-                               + ");");
-       }
-
-       @Override
-       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
-                + newVersion + ", which will destroy all old data");
-
-        // Kills the table and existing data
-        db.execSQL("DROP TABLE IF EXISTS " + WeatherLocationContract.WeatherLocation.TABLE_NAME);
-
-        // Recreates the database with a new version
-        onCreate(db);
-       }
-
-}
diff --git a/src/de/example/exampletdd/model/WeatherLocationDbQueries.java b/src/de/example/exampletdd/model/WeatherLocationDbQueries.java
deleted file mode 100644 (file)
index fa97ca2..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-package de.example.exampletdd.model;
-
-import java.util.Calendar;
-import java.util.Date;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-
-public class WeatherLocationDbQueries {
-       private final SQLiteOpenHelper mDbHelper;
-
-       public interface DoQuery {
-               
-               public WeatherLocation doQuery(final Cursor cursor);
-       }
-
-       public WeatherLocationDbQueries(final SQLiteOpenHelper dbHelper) {
-               this.mDbHelper = dbHelper;
-       }
-       
-       public WeatherLocation queryDataBase() {
-        final String selection = WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " = ?";
-        final String[] selectionArgs = { "1" };
-        final String[] projection = {
-                       WeatherLocationContract.WeatherLocation._ID,
-                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY,
-                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY,
-                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED,
-                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE,
-                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE,
-                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE,
-                       WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE
-                   };
-        
-
-        final WeatherLocationDbQueries.DoQuery doQuery = new WeatherLocationDbQueries.DoQuery() {
-
-               @Override
-               public WeatherLocation doQuery(final Cursor cursor) {                   
-                       final int id = cursor.getInt(cursor.getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation._ID));
-                       final String city = cursor.getString(cursor.
-                                       getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY));
-                       final String country = cursor.getString(cursor.
-                                       getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY));
-                       final boolean isSelected = (cursor.getInt(cursor
-                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED)) == 0) ? false : true;  
-                       Date lastCurrentUIUpdate = null;
-                       if (!cursor.isNull(cursor
-                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE))) {
-                       final long javaTime = cursor.getLong(cursor
-                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE));
-                       lastCurrentUIUpdate = new Date(javaTime);
-                       }
-                       Date lasForecastUIUpdate = null;
-                       if (!cursor.isNull(cursor
-                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE))) {
-                       final long javaTime = cursor.getLong(cursor
-                                       .getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE));
-                       lasForecastUIUpdate = new Date(javaTime);
-                       }
-                       final double latitude = cursor.getDouble(cursor.
-                                       getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE));
-                       final double longitude = cursor.getDouble(cursor.
-                                       getColumnIndexOrThrow(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE));
-                       
-                       
-                       return new WeatherLocation()
-                                       .setId(id)
-                                       .setCity(city)
-                                       .setCountry(country)
-                                       .setIsSelected(isSelected)
-                                       .setLastCurrentUIUpdate(lastCurrentUIUpdate)
-                                       .setLastForecastUIUpdate(lasForecastUIUpdate)
-                                       .setLatitude(latitude)
-                                       .setLongitude(longitude);
-               }
-        };
-
-        return this.queryDataBase(
-                       WeatherLocationContract.WeatherLocation.TABLE_NAME, projection,
-                       selectionArgs, selection, doQuery);
-    }
-       
-       public long insertIntoDataBase(final WeatherLocation weatherLocation) {
-               // Create a new map of values, where column names are the keys
-               final ContentValues values = new ContentValues();
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, weatherLocation.getCity());
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, weatherLocation.getCountry());
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, weatherLocation.getIsSelected());
-               Date javaTime = weatherLocation.getLastCurrentUIUpdate();
-               if (javaTime != null) {
-                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE, javaTime.getTime());
-               }
-               javaTime = weatherLocation.getLastForecastUIUpdate();
-               if (javaTime != null) {
-                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE, javaTime.getTime());
-               }
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, weatherLocation.getLatitude());
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE, weatherLocation.getLongitude());
-               
-               return this.insertIntoDataBase(WeatherLocationContract.WeatherLocation.TABLE_NAME, values);
-       }
-       
-       public void updateDataBase(final WeatherLocation weatherLocation) {
-               final String selection = WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED + " = ?";
-        final String[] selectionArgs = { "1" };
-               // Create a new map of values, where column names are the keys
-               final ContentValues values = new ContentValues();
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_CITY, weatherLocation.getCity());
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_COUNTRY, weatherLocation.getCountry());
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_IS_SELECTED, weatherLocation.getIsSelected());
-               Date javaTime = weatherLocation.getLastCurrentUIUpdate();
-               if (javaTime != null) {
-                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE, javaTime.getTime());
-               } else {
-                       values.putNull(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_CURRENT_UI_UPDATE);
-               }
-               javaTime = weatherLocation.getLastForecastUIUpdate();
-               if (javaTime != null) {
-                       values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE, javaTime.getTime());
-               } else {
-                       values.putNull(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LAST_FORECAST_UI_UPDATE);
-               }
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LATITUDE, weatherLocation.getLatitude());
-               values.put(WeatherLocationContract.WeatherLocation.COLUMN_NAME_LONGITUDE, weatherLocation.getLongitude());
-               
-               this.updateDataBase(WeatherLocationContract.WeatherLocation.TABLE_NAME, selectionArgs, selection, values);
-       }
-       
-       // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
-       private WeatherLocation queryDataBase(final String table,
-                       final String[] projection, final String[] selectionArgs,
-                       final String selection, final DoQuery doQuery) {
-        // TODO: execute around idiom? I miss try/finally with resources
-        final SQLiteDatabase db = this.mDbHelper.getReadableDatabase();
-        try {
-               final Cursor cursor = db.query(table, projection, selection, selectionArgs, null, null, null);
-               try {
-                       if (!cursor.moveToFirst()) {
-                       return null;
-                       }
-                       else {
-                               return doQuery.doQuery(cursor);
-                       }
-               } finally {
-                       cursor.close();
-               }
-        } finally {
-               db.close();
-        }
-    }
-       
-       // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
-       private long insertIntoDataBase(final String table, final ContentValues values) {
-        final SQLiteDatabase db = this.mDbHelper.getWritableDatabase();
-        try {
-               return db.insert(table, null, values);
-        } finally {
-               db.close();
-        }
-    }
-       
-       // TODO: May I perform another query after this method (after closing almost everything but mDbHelper)
-       private long updateDataBase(final String table, final String[] selectionArgs,
-                       final String selection, final ContentValues values) {
-        final SQLiteDatabase db = this.mDbHelper.getWritableDatabase();
-        try {
-               return db.update(table, values, selection, selectionArgs);
-        } finally {
-               db.close();
-        }
-    }
-       
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Clouds.java b/src/de/example/exampletdd/model/currentweather/Clouds.java
deleted file mode 100644 (file)
index 8da14c3..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-
-public class Clouds implements Serializable {
-    private static final long serialVersionUID = 3034435739326030899L;
-    private Number all;
-
-    public Number getAll(){
-        return this.all;
-    }
-    public void setAll(final Number all){
-        this.all = all;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Clouds [all=").append(this.all).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Coord.java b/src/de/example/exampletdd/model/currentweather/Coord.java
deleted file mode 100644 (file)
index 9eececd..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-
-public class Coord implements Serializable {
-    private static final long serialVersionUID = 7151637605146377486L;
-    private Number lat;
-    private Number lon;
-
-    public Number getLat(){
-        return this.lat;
-    }
-    public void setLat(final Number lat){
-        this.lat = lat;
-    }
-    public Number getLon(){
-        return this.lon;
-    }
-    public void setLon(final Number lon){
-        this.lon = lon;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Coord [lat=").append(this.lat).append(", lon=").append(this.lon)
-        .append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Current.java b/src/de/example/exampletdd/model/currentweather/Current.java
deleted file mode 100644 (file)
index a7bc22e..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Auto generated by: http://jsongen.byingtondesign.com/
- * (with my own modifications)
- *
- */
-public class Current implements Serializable {
-    private static final long serialVersionUID = -730690341739860818L;
-    private String base;
-    private Clouds clouds;
-    private Number cod;
-    private Coord coord;
-    private Number dt;
-    private Number id;
-    private Main main;
-    private String name;
-    private Rain rain;
-    private Snow snow;
-    private Sys sys;
-    private List<Weather> weather;
-    private Wind wind;
-    private byte[] iconData;
-    private Date date;
-
-    public String getBase(){
-        return this.base;
-    }
-    public void setBase(final String base){
-        this.base = base;
-    }
-    public Clouds getClouds(){
-        return this.clouds;
-    }
-    public void setClouds(final Clouds clouds){
-        this.clouds = clouds;
-    }
-
-    public Number getCod() {
-        return this.cod;
-    }
-
-    public void setCod(final Number cod) {
-        this.cod = cod;
-    }
-    public Coord getCoord(){
-        return this.coord;
-    }
-    public void setCoord(final Coord coord){
-        this.coord = coord;
-    }
-    public Number getDt(){
-        return this.dt;
-    }
-    public void setDt(final Number dt){
-        this.dt = dt;
-    }
-    public Number getId(){
-        return this.id;
-    }
-    public void setId(final Number id){
-        this.id = id;
-    }
-    public Main getMain(){
-        return this.main;
-    }
-    public void setMain(final Main main){
-        this.main = main;
-    }
-    public String getName(){
-        return this.name;
-    }
-    public void setName(final String name){
-        this.name = name;
-    }
-    public Rain getRain(){
-        return this.rain;
-    }
-    public void setRain(final Rain rain){
-        this.rain = rain;
-    }
-    public Snow getSnow() {
-        return this.snow;
-    }
-    public void setSnow(final Snow snow) {
-        this.snow = snow;
-    }
-    public Sys getSys(){
-        return this.sys;
-    }
-    public void setSys(final Sys sys){
-        this.sys = sys;
-    }
-    public List<Weather> getWeather(){
-        return this.weather;
-    }
-    public void setWeather(final List<Weather> weather){
-        this.weather = weather;
-    }
-    public Wind getWind(){
-        return this.wind;
-    }
-    public void setWind(final Wind wind){
-        this.wind = wind;
-    }
-
-    public byte[] getIconData() {
-        return this.iconData;
-    }
-
-    public void setIconData(final byte[] iconData) {
-        this.iconData = iconData;
-    }
-
-    public Date getDate() {
-        return this.date;
-    }
-
-    public void setDate(final Date date) {
-        this.date = date;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Current [base=").append(this.base).append(", clouds=")
-        .append(this.clouds).append(", cod=").append(this.cod).append(", coord=")
-        .append(this.coord).append(", dt=").append(this.dt).append(", id=").append(this.id)
-        .append(", main=").append(this.main).append(", name=").append(this.name)
-        .append(", rain=").append(this.rain).append(", snow=").append(this.snow)
-        .append(", sys=").append(this.sys).append(", weather=").append(this.weather)
-        .append(", wind=").append(this.wind).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Main.java b/src/de/example/exampletdd/model/currentweather/Main.java
deleted file mode 100644 (file)
index 397f71b..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-
-public class Main implements Serializable {
-    private static final long serialVersionUID = -6000879164436289447L;
-    private Number grnd_level;
-    private Number humidity;
-    private Number pressure;
-    private Number sea_level;
-    private Number temp;
-    private Number temp_max;
-    private Number temp_min;
-
-    public Number getGrnd_level() {
-        return this.grnd_level;
-    }
-
-    public void setGrnd_level(final Number grnd_level) {
-        this.grnd_level = grnd_level;
-    }
-
-    public Number getHumidity(){
-        return this.humidity;
-    }
-    public void setHumidity(final Number humidity){
-        this.humidity = humidity;
-    }
-    public Number getPressure(){
-        return this.pressure;
-    }
-    public void setPressure(final Number pressure){
-        this.pressure = pressure;
-    }
-
-    public Number getSea_level() {
-        return this.sea_level;
-    }
-
-    public void setSea_level(final Number sea_level) {
-        this.sea_level = sea_level;
-    }
-
-    public Number getTemp(){
-        return this.temp;
-    }
-    public void setTemp(final Number temp){
-        this.temp = temp;
-    }
-    public Number getTemp_max(){
-        return this.temp_max;
-    }
-    public void setTemp_max(final Number temp_max){
-        this.temp_max = temp_max;
-    }
-    public Number getTemp_min(){
-        return this.temp_min;
-    }
-    public void setTemp_min(final Number temp_min){
-        this.temp_min = temp_min;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Main [grnd_level=").append(this.grnd_level).append(", humidity=")
-        .append(this.humidity).append(", pressure=").append(this.pressure)
-        .append(", sea_level=").append(this.sea_level).append(", temp=").append(this.temp)
-        .append(", temp_max=").append(this.temp_max).append(", temp_min=")
-        .append(this.temp_min).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Rain.java b/src/de/example/exampletdd/model/currentweather/Rain.java
deleted file mode 100644 (file)
index 0e151ef..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-
-public class Rain implements Serializable {
-    private static final long serialVersionUID = 1318464783605029435L;
-    private Number three;
-
-    public Number get3h(){
-        return this.three;
-    }
-
-    public void set3h(final Number threeh) {
-        this.three = threeh;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Rain [three=").append(this.three).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Snow.java b/src/de/example/exampletdd/model/currentweather/Snow.java
deleted file mode 100644 (file)
index 5174763..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-
-public class Snow implements Serializable {
-    private static final long serialVersionUID = 6769716772818311879L;
-    private Number three;
-
-    public Number get3h() {
-        return this.three;
-    }
-
-    public void set3h(final Number threeh) {
-        this.three = threeh;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Snow [three=").append(this.three).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Sys.java b/src/de/example/exampletdd/model/currentweather/Sys.java
deleted file mode 100644 (file)
index 3e20bef..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-
-
-public class Sys implements Serializable {
-    private static final long serialVersionUID = 5333083785731053139L;
-    private String country;
-    private Number message;
-    private Number sunrise;
-    private Number sunset;
-
-    public String getCountry(){
-        return this.country;
-    }
-    public void setCountry(final String country){
-        this.country = country;
-    }
-    public Number getMessage(){
-        return this.message;
-    }
-    public void setMessage(final Number message){
-        this.message = message;
-    }
-    public Number getSunrise(){
-        return this.sunrise;
-    }
-    public void setSunrise(final Number sunrise){
-        this.sunrise = sunrise;
-    }
-    public Number getSunset(){
-        return this.sunset;
-    }
-    public void setSunset(final Number sunset){
-        this.sunset = sunset;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Sys [country=").append(this.country).append(", message=")
-        .append(this.message).append(", sunrise=").append(this.sunrise).append(", sunset=")
-        .append(this.sunset).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Weather.java b/src/de/example/exampletdd/model/currentweather/Weather.java
deleted file mode 100644 (file)
index fc44d20..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-
-public class Weather implements Serializable {
-    private static final long serialVersionUID = -34336548786316655L;
-    private String description;
-    private String icon;
-    private Number id;
-    private String main;
-
-    public String getDescription(){
-        return this.description;
-    }
-    public void setDescription(final String description){
-        this.description = description;
-    }
-    public String getIcon(){
-        return this.icon;
-    }
-    public void setIcon(final String icon){
-        this.icon = icon;
-    }
-    public Number getId(){
-        return this.id;
-    }
-    public void setId(final Number id){
-        this.id = id;
-    }
-    public String getMain(){
-        return this.main;
-    }
-    public void setMain(final String main){
-        this.main = main;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Weather [description=").append(this.description).append(", icon=")
-        .append(this.icon).append(", id=").append(this.id).append(", main=")
-        .append(this.main).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/currentweather/Wind.java b/src/de/example/exampletdd/model/currentweather/Wind.java
deleted file mode 100644 (file)
index 4edc55d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.example.exampletdd.model.currentweather;
-
-import java.io.Serializable;
-
-public class Wind implements Serializable {
-    private static final long serialVersionUID = 5495842422633674631L;
-    private Number deg;
-    private Number speed;
-
-    public Number getDeg(){
-        return this.deg;
-    }
-    public void setDeg(final Number deg){
-        this.deg = deg;
-    }
-    public Number getSpeed(){
-        return this.speed;
-    }
-    public void setSpeed(final Number speed){
-        this.speed = speed;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Wind [deg=").append(this.deg).append(", speed=").append(this.speed)
-        .append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/forecastweather/City.java b/src/de/example/exampletdd/model/forecastweather/City.java
deleted file mode 100644 (file)
index 904ff5d..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-package de.example.exampletdd.model.forecastweather;
-
-import java.io.Serializable;
-
-
-public class City implements Serializable {
-    private static final long serialVersionUID = 3079687975077030704L;
-    private Coord coord;
-    private String country;
-    private Number id;
-    private String name;
-    private Number population;
-
-    public Coord getCoord(){
-        return this.coord;
-    }
-    public void setCoord(final Coord coord){
-        this.coord = coord;
-    }
-    public String getCountry(){
-        return this.country;
-    }
-    public void setCountry(final String country){
-        this.country = country;
-    }
-    public Number getId(){
-        return this.id;
-    }
-    public void setId(final Number id){
-        this.id = id;
-    }
-    public String getName(){
-        return this.name;
-    }
-    public void setName(final String name){
-        this.name = name;
-    }
-    public Number getPopulation(){
-        return this.population;
-    }
-    public void setPopulation(final Number population){
-        this.population = population;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("City [coord=").append(this.coord).append(", country=").append(this.country)
-        .append(", id=").append(this.id).append(", name=").append(this.name)
-        .append(", population=").append(this.population).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/forecastweather/Coord.java b/src/de/example/exampletdd/model/forecastweather/Coord.java
deleted file mode 100644 (file)
index fcfee58..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.example.exampletdd.model.forecastweather;
-
-import java.io.Serializable;
-
-public class Coord implements Serializable {
-    private static final long serialVersionUID = 8069257976701986700L;
-    private Number lat;
-    private Number lon;
-
-    public Number getLat(){
-        return this.lat;
-    }
-    public void setLat(final Number lat){
-        this.lat = lat;
-    }
-    public Number getLon(){
-        return this.lon;
-    }
-    public void setLon(final Number lon){
-        this.lon = lon;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Coord [lat=").append(this.lat).append(", lon=").append(this.lon)
-        .append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/forecastweather/Forecast.java b/src/de/example/exampletdd/model/forecastweather/Forecast.java
deleted file mode 100644 (file)
index 5a59a02..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-package de.example.exampletdd.model.forecastweather;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * Auto generated by: http://jsongen.byingtondesign.com/
- * (with my own modifications)
- *
- */
-public class Forecast implements Serializable {
-    private static final long serialVersionUID = 5095443678019686190L;
-    private City city;
-    private Number cnt;
-    private Number cod;
-    private List<de.example.exampletdd.model.forecastweather.List> list;
-    private Number message;
-
-    public City getCity(){
-        return this.city;
-    }
-    public void setCity(final City city){
-        this.city = city;
-    }
-    public Number getCnt(){
-        return this.cnt;
-    }
-    public void setCnt(final Number cnt){
-        this.cnt = cnt;
-    }
-
-    public Number getCod() {
-        return this.cod;
-    }
-
-    public void setCod(final Number cod) {
-        this.cod = cod;
-    }
-
-    public List<de.example.exampletdd.model.forecastweather.List> getList() {
-        return this.list;
-    }
-
-    public void setList(final List<de.example.exampletdd.model.forecastweather.List> list) {
-        this.list = list;
-    }
-    public Number getMessage(){
-        return this.message;
-    }
-    public void setMessage(final Number message){
-        this.message = message;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Forecast [city=").append(this.city).append(", cnt=")
-        .append(this.cnt).append(", cod=").append(this.cod).append(", list=")
-        .append(this.list).append(", message=").append(this.message).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/forecastweather/List.java b/src/de/example/exampletdd/model/forecastweather/List.java
deleted file mode 100644 (file)
index 2104579..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-package de.example.exampletdd.model.forecastweather;
-
-import java.io.Serializable;
-
-
-public class List implements Serializable {
-    private static final long serialVersionUID = 838468273188666785L;
-    private Number clouds;
-    private Number deg;
-    private Number dt;
-    private Number humidity;
-    private Number pressure;
-    private Number rain;
-    private Number snow;
-    private Number speed;
-    private Temp temp;
-    private java.util.List<Weather> weather;
-
-    public Number getClouds(){
-        return this.clouds;
-    }
-    public void setClouds(final Number clouds){
-        this.clouds = clouds;
-    }
-    public Number getDeg(){
-        return this.deg;
-    }
-    public void setDeg(final Number deg){
-        this.deg = deg;
-    }
-    public Number getDt(){
-        return this.dt;
-    }
-    public void setDt(final Number dt){
-        this.dt = dt;
-    }
-    public Number getHumidity(){
-        return this.humidity;
-    }
-    public void setHumidity(final Number humidity){
-        this.humidity = humidity;
-    }
-    public Number getPressure(){
-        return this.pressure;
-    }
-    public void setPressure(final Number pressure){
-        this.pressure = pressure;
-    }
-    public Number getRain(){
-        return this.rain;
-    }
-    public void setRain(final Number rain){
-        this.rain = rain;
-    }
-    public Number getSnow() {
-        return this.snow;
-    }
-    public void setSnow(final Number snow) {
-        this.snow = snow;
-    }
-    public Number getSpeed(){
-        return this.speed;
-    }
-    public void setSpeed(final Number speed){
-        this.speed = speed;
-    }
-    public Temp getTemp(){
-        return this.temp;
-    }
-    public void setTemp(final Temp temp){
-        this.temp = temp;
-    }
-
-    public java.util.List<Weather> getWeather() {
-        return this.weather;
-    }
-
-    public void setWeather(final java.util.List<Weather> weather) {
-        this.weather = weather;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("List [clouds=").append(this.clouds).append(", deg=").append(this.deg)
-        .append(", dt=").append(this.dt).append(", humidity=").append(this.humidity)
-        .append(", pressure=").append(this.pressure).append(", rain=").append(this.rain)
-        .append(", snow=").append(this.snow).append(", speed=").append(this.speed)
-        .append(", temp=").append(this.temp).append(", weather=").append(this.weather)
-        .append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/forecastweather/Temp.java b/src/de/example/exampletdd/model/forecastweather/Temp.java
deleted file mode 100644 (file)
index e4b1a7a..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-package de.example.exampletdd.model.forecastweather;
-
-import java.io.Serializable;
-
-public class Temp implements Serializable {
-    private static final long serialVersionUID = -7614799035018271127L;
-    private Number day;
-    private Number eve;
-    private Number max;
-    private Number min;
-    private Number morn;
-    private Number night;
-
-    public Number getDay(){
-        return this.day;
-    }
-    public void setDay(final Number day){
-        this.day = day;
-    }
-    public Number getEve(){
-        return this.eve;
-    }
-    public void setEve(final Number eve){
-        this.eve = eve;
-    }
-    public Number getMax(){
-        return this.max;
-    }
-    public void setMax(final Number max){
-        this.max = max;
-    }
-    public Number getMin(){
-        return this.min;
-    }
-    public void setMin(final Number min){
-        this.min = min;
-    }
-    public Number getMorn(){
-        return this.morn;
-    }
-    public void setMorn(final Number morn){
-        this.morn = morn;
-    }
-    public Number getNight(){
-        return this.night;
-    }
-    public void setNight(final Number night){
-        this.night = night;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Temp [day=").append(this.day).append(", eve=").append(this.eve)
-        .append(", max=").append(this.max).append(", min=").append(this.min)
-        .append(", morn=").append(this.morn).append(", night=").append(this.night)
-        .append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/model/forecastweather/Weather.java b/src/de/example/exampletdd/model/forecastweather/Weather.java
deleted file mode 100644 (file)
index f0de236..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-package de.example.exampletdd.model.forecastweather;
-
-import java.io.Serializable;
-
-public class Weather implements Serializable {
-    private static final long serialVersionUID = -5066357704517363241L;
-    private String description;
-    private String icon;
-    private Number id;
-    private String main;
-
-    public String getDescription(){
-        return this.description;
-    }
-    public void setDescription(final String description){
-        this.description = description;
-    }
-    public String getIcon(){
-        return this.icon;
-    }
-    public void setIcon(final String icon){
-        this.icon = icon;
-    }
-    public Number getId(){
-        return this.id;
-    }
-    public void setId(final Number id){
-        this.id = id;
-    }
-    public String getMain(){
-        return this.main;
-    }
-    public void setMain(final String main){
-        this.main = main;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("Weather [description=").append(this.description).append(", icon=")
-        .append(this.icon).append(", id=").append(this.id).append(", main=")
-        .append(this.main).append("]");
-        return builder.toString();
-    }
-}
diff --git a/src/de/example/exampletdd/parser/IJPOSParser.java b/src/de/example/exampletdd/parser/IJPOSParser.java
deleted file mode 100644 (file)
index 14a1d55..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.example.exampletdd.parser;
-
-import java.io.IOException;
-
-import com.fasterxml.jackson.core.JsonParseException;
-
-import de.example.exampletdd.model.currentweather.Current;
-import de.example.exampletdd.model.forecastweather.Forecast;
-
-public interface IJPOSParser {
-
-    public Current retrieveCurrenFromJPOS(final String jsonData)
-            throws JsonParseException, IOException;
-
-    public Forecast retrieveForecastFromJPOS(final String jsonData)
-            throws JsonParseException, IOException;
-}
diff --git a/src/de/example/exampletdd/parser/JPOSWeatherParser.java b/src/de/example/exampletdd/parser/JPOSWeatherParser.java
deleted file mode 100644 (file)
index b71e342..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-package de.example.exampletdd.parser;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-
-import de.example.exampletdd.model.currentweather.Clouds;
-import de.example.exampletdd.model.currentweather.Coord;
-import de.example.exampletdd.model.currentweather.Current;
-import de.example.exampletdd.model.currentweather.Main;
-import de.example.exampletdd.model.currentweather.Rain;
-import de.example.exampletdd.model.currentweather.Sys;
-import de.example.exampletdd.model.currentweather.Wind;
-import de.example.exampletdd.model.forecastweather.City;
-import de.example.exampletdd.model.forecastweather.Forecast;
-import de.example.exampletdd.model.forecastweather.Temp;
-
-public class JPOSWeatherParser implements IJPOSParser {
-
-    @Override
-    public Current retrieveCurrenFromJPOS(final String jsonData)
-            throws JsonParseException, IOException {
-        final JsonFactory f = new JsonFactory();
-
-        final Current currentWeatherData = new Current();
-        currentWeatherData.setClouds(new Clouds());
-        currentWeatherData.setCoord(new Coord());
-        currentWeatherData.setMain(new Main());
-        currentWeatherData.setRain(new Rain());
-        currentWeatherData.setSys(new Sys());
-        currentWeatherData
-        .setWeather(new ArrayList<de.example.exampletdd.model.currentweather.Weather>());
-        currentWeatherData.setWind(new Wind());
-        final JsonParser jParser = f.createParser(jsonData);
-
-        this.getCurrentWeatherData(currentWeatherData, jParser);
-
-        return currentWeatherData;
-    }
-
-    @Override
-    public Forecast retrieveForecastFromJPOS(final String jsonData)
-            throws JsonParseException, IOException {
-        final JsonFactory f = new JsonFactory();
-
-        final Forecast forecastWeatherData = new Forecast();
-        forecastWeatherData
-        .setList(new ArrayList<de.example.exampletdd.model.forecastweather.List>(15));
-        final City city = new City();
-        city.setCoord(new de.example.exampletdd.model.forecastweather.Coord());
-        forecastWeatherData.setCity(city);
-        final JsonParser jParser = f.createParser(jsonData);
-
-        this.getForecastWeatherData(forecastWeatherData, jParser);
-
-        return forecastWeatherData;
-    }
-
-    private void getCurrentWeatherData(final Current currentWeatherData,
-            final JsonParser jParser) throws JsonParseException, IOException {
-        if (jParser.nextToken() == JsonToken.START_OBJECT) {
-
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String fieldname = jParser.getCurrentName();
-                final JsonToken nextToken = jParser.nextToken();
-                if (nextToken == JsonToken.START_OBJECT) {
-                    this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname);
-                }
-                if (nextToken == JsonToken.START_ARRAY) {
-                    JsonToken tokenNext = jParser.nextToken();
-                    while (tokenNext != JsonToken.END_ARRAY) {
-                        if (tokenNext == JsonToken.START_OBJECT) {
-                            this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname);
-                        }
-                        tokenNext = jParser.nextToken();
-                    }
-                }
-                if ((nextToken == JsonToken.VALUE_NUMBER_INT)
-                        || (nextToken == JsonToken.VALUE_STRING)) {
-                    this.getCurrentWeatherDataObjects(currentWeatherData, jParser, fieldname);
-                }
-            }
-        }
-    }
-
-    private void getCurrentWeatherDataObjects(final Current currentWeatherData,
-            final JsonParser jParser, final String fieldname) throws JsonParseException,
-            IOException {
-        if (fieldname == "coord") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("lon".equals(namefield)) {
-                    currentWeatherData.getCoord().setLon(jParser.getDoubleValue());
-                }
-                if ("lat".equals(namefield)) {
-                    currentWeatherData.getCoord().setLat(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "sys") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("message".equals(namefield)) {
-                    currentWeatherData.getSys().setMessage(jParser.getDoubleValue());
-                }
-                if ("country".equals(namefield)) {
-                    currentWeatherData.getSys().setCountry(jParser.getValueAsString());
-                }
-                if ("sunrise".equals(namefield)) {
-                    currentWeatherData.getSys().setSunrise(jParser.getValueAsLong());
-                }
-                if ("sunset".equals(namefield)) {
-                    currentWeatherData.getSys().setSunset(jParser.getValueAsLong());
-                }
-            }
-        }
-        if (fieldname == "weather") {
-            final de.example.exampletdd.model.currentweather.Weather weather = new de.example.exampletdd.model.currentweather.Weather();
-            currentWeatherData.getWeather().add(weather);
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("id".equals(namefield)) {
-                    weather.setId(jParser.getIntValue());
-                }
-                if ("main".equals(namefield)) {
-                    weather.setMain(jParser.getText());
-                }
-                if ("description".equals(namefield)) {
-                    weather.setDescription(jParser.getText());
-                }
-                if ("icon".equals(namefield)) {
-                    weather.setIcon(jParser.getText());
-                }
-
-            }
-        }
-        if (fieldname == "base") {
-            currentWeatherData.setBase(jParser.getText());
-        }
-        if (fieldname == "main") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("temp".equals(namefield)) {
-                    currentWeatherData.getMain().setTemp(jParser.getDoubleValue());
-                }
-                if ("temp_min".equals(namefield)) {
-                    currentWeatherData.getMain().setTemp_min(jParser.getDoubleValue());
-                }
-                if ("temp_max".equals(namefield)) {
-                    currentWeatherData.getMain().setTemp_max(jParser.getDoubleValue());
-                }
-                if ("pressure".equals(namefield)) {
-                    currentWeatherData.getMain().setPressure(jParser.getDoubleValue());
-                }
-                if ("sea_level".equals(namefield)) {
-                    currentWeatherData.getMain().setSea_level(jParser.getDoubleValue());
-                }
-                if ("grnd_level".equals(namefield)) {
-                    currentWeatherData.getMain().setGrnd_level(jParser.getDoubleValue());
-                }
-                if ("humidity".equals(namefield)) {
-                    currentWeatherData.getMain().setHumidity(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "wind") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("speed".equals(namefield)) {
-                    currentWeatherData.getWind().setSpeed(jParser.getDoubleValue());
-                }
-                if ("deg".equals(namefield)) {
-                    currentWeatherData.getWind().setDeg(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "clouds") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("all".equals(namefield)) {
-                    currentWeatherData.getClouds().setAll(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "dt") {
-            currentWeatherData.setDt(jParser.getLongValue());
-        }
-        if (fieldname == "rain") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("3h".equals(namefield)) {
-                    currentWeatherData.getRain().set3h(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "snow") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("3h".equals(namefield)) {
-                    currentWeatherData.getSnow().set3h(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "id") {
-            currentWeatherData.setId(jParser.getLongValue());
-        }
-        if (fieldname == "name") {
-            currentWeatherData.setName(jParser.getText());
-        }
-        if (fieldname == "cod") {
-            currentWeatherData.setCod(jParser.getIntValue());
-        }
-    }
-
-    private void getForecastWeatherData(final Forecast forecastWeatherData,
-            final JsonParser jParser) throws JsonParseException, IOException {
-        if (jParser.nextToken() == JsonToken.START_OBJECT) {
-
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String fieldname = jParser.getCurrentName();
-                final JsonToken nextToken = jParser.nextToken();
-                if (nextToken == JsonToken.START_OBJECT) {
-                    this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname);
-                }
-                if (nextToken == JsonToken.START_ARRAY) {
-                    JsonToken tokenNext = jParser.nextToken();
-                    while (tokenNext != JsonToken.END_ARRAY) {
-                        if (tokenNext == JsonToken.START_OBJECT) {
-                            this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname);
-                        }
-                        tokenNext = jParser.nextToken();
-                    }
-                }
-                if ((nextToken == JsonToken.VALUE_NUMBER_INT)
-                        || (nextToken == JsonToken.VALUE_STRING)) {
-                    this.getForecastWeatherDataObjects(forecastWeatherData, jParser, fieldname);
-                }
-            }
-        }
-    }
-
-    private void getForecastWeatherDataObjects(final Forecast forecastWeatherData,
-            final JsonParser jParser, final String fieldname) throws JsonParseException,
-            IOException {
-
-        if (fieldname == "cod") {
-            final String stringCod = jParser.getText();
-            forecastWeatherData.setCod(Long.valueOf(stringCod));
-        }
-        if (fieldname == "message") {
-            forecastWeatherData.setMessage(jParser.getDoubleValue());
-        }
-        if (fieldname == "city") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                final JsonToken nextToken = jParser.nextToken(); // move to
-                // value
-                if ("id".equals(namefield)) {
-                    forecastWeatherData.getCity().setId(jParser.getLongValue());
-                }
-                if ("name".equals(namefield)) {
-                    forecastWeatherData.getCity().setName(jParser.getText());
-                }
-                if ("coord".equals(namefield)) {
-                    if (nextToken == JsonToken.START_OBJECT) {
-                        this.getForecastWeatherDataObjects(forecastWeatherData, jParser, namefield);
-                    }
-                }
-                if ("country".equals(namefield)) {
-                    forecastWeatherData.getCity().setCountry(jParser.getText());
-                }
-                if ("population".equals(namefield)) {
-                    forecastWeatherData.getCity().setPopulation(jParser.getLongValue());
-                }
-            }
-        }
-        if (fieldname == "cnt") {
-            forecastWeatherData.setCnt(jParser.getIntValue());
-        }
-        if (fieldname == "coord") {
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("lon".equals(namefield)) {
-                    forecastWeatherData.getCity().getCoord().setLon(jParser.getDoubleValue());
-                }
-                if ("lat".equals(namefield)) {
-                    forecastWeatherData.getCity().getCoord().setLat(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "list") {
-            final de.example.exampletdd.model.forecastweather.List list = new de.example.exampletdd.model.forecastweather.List();
-            list.setTemp(new Temp());
-            list.setWeather(new ArrayList<de.example.exampletdd.model.forecastweather.Weather>());
-            forecastWeatherData.getList().add(list);
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                final JsonToken nextToken = jParser.nextToken(); // move to
-                // value
-                if ("dt".equals(namefield)) {
-                    list.setDt(jParser.getLongValue());
-                }
-                if ("temp".equals(namefield)) {
-                    if (nextToken == JsonToken.START_OBJECT) {
-                        this.getForecastWeatherDataObjects(forecastWeatherData, jParser, namefield);
-                    }
-                }
-                if ("pressure".equals(namefield)) {
-                    list.setPressure(jParser.getDoubleValue());
-                }
-                if ("humidity".equals(namefield)) {
-                    list.setHumidity(jParser.getDoubleValue());
-                }
-                if ("weather".equals(namefield)) {
-                    if (nextToken == JsonToken.START_ARRAY) {
-                        JsonToken tokenNext = jParser.nextToken();
-                        while (tokenNext != JsonToken.END_ARRAY) {
-                            if (tokenNext == JsonToken.START_OBJECT) {
-                                this.getForecastWeatherDataObjects(forecastWeatherData, jParser,
-                                        namefield);
-                            }
-                            tokenNext = jParser.nextToken();
-                        }
-                    }
-                }
-                if ("speed".equals(namefield)) {
-                    list.setSpeed(jParser.getDoubleValue());
-                }
-                if ("deg".equals(namefield)) {
-                    list.setDeg(jParser.getDoubleValue());
-                }
-                if ("clouds".equals(namefield)) {
-                    list.setClouds(jParser.getDoubleValue());
-                }
-                if ("rain".equals(namefield)) {
-                    list.setRain(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "temp") {
-            final de.example.exampletdd.model.forecastweather.List list = forecastWeatherData
-                    .getList().get(
-                            (forecastWeatherData.getList().size() - 1));
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-                if ("day".equals(namefield)) {
-                    list.getTemp().setDay(jParser.getDoubleValue());
-                }
-                if ("min".equals(namefield)) {
-                    list.getTemp().setMin(jParser.getDoubleValue());
-                }
-                if ("max".equals(namefield)) {
-                    list.getTemp().setMax(jParser.getDoubleValue());
-                }
-                if ("night".equals(namefield)) {
-                    list.getTemp().setNight(jParser.getDoubleValue());
-                }
-                if ("eve".equals(namefield)) {
-                    list.getTemp().setEve(jParser.getDoubleValue());
-                }
-                if ("morn".equals(namefield)) {
-                    list.getTemp().setMorn(jParser.getDoubleValue());
-                }
-            }
-        }
-        if (fieldname == "weather") {
-            final de.example.exampletdd.model.forecastweather.List list = forecastWeatherData
-                    .getList().get(
-                            (forecastWeatherData.getList().size() - 1));
-            final de.example.exampletdd.model.forecastweather.Weather weather = new de.example.exampletdd.model.forecastweather.Weather();
-            while (jParser.nextToken() != JsonToken.END_OBJECT) {
-                final String namefield = jParser.getCurrentName();
-                jParser.nextToken(); // move to value
-
-                if ("id".equals(namefield)) {
-                    weather.setId(jParser.getIntValue());
-                }
-                if ("main".equals(namefield)) {
-                    weather.setMain(jParser.getText());
-                }
-                if ("description".equals(namefield)) {
-                    weather.setDescription(jParser.getText());
-                }
-                if ("icon".equals(namefield)) {
-                    weather.setIcon(jParser.getText());
-                }
-            }
-            list.getWeather().add(weather);
-        }
-    }
-}
diff --git a/src/de/example/exampletdd/service/IconsList.java b/src/de/example/exampletdd/service/IconsList.java
deleted file mode 100644 (file)
index ea53085..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-package de.example.exampletdd.service;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import de.example.exampletdd.R;
-
-public enum IconsList {
-    ICON_01d("01d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_clear;
-        }
-    },
-    ICON_01n("01n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_clear_night;
-        }
-    },
-    ICON_02d("02d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_few_clouds;
-        }
-    },
-    ICON_02n("02n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_few_clouds_night;
-        }
-    },
-    ICON_03d("03d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_few_clouds;
-        }
-    },
-    ICON_03n("03n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_few_clouds;
-        }
-    },
-    ICON_04d("04d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_overcast;
-        }
-    },
-    ICON_04n("04n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_overcast;
-        }
-    },
-    ICON_09d("09d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_showers;
-        }
-    },
-    ICON_09n("09n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_showers;
-        }
-    },
-    ICON_10d("10d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_showers_scattered;
-        }
-    },
-    ICON_10n("10n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_showers_scattered;
-        }
-    },
-    ICON_11d("11d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_storm;
-        }
-    },
-    ICON_11n("11n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_storm;
-        }
-    },
-    ICON_13d("13d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_snow;
-        }
-    },
-    ICON_13n("13n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_snow;
-        }
-    },
-    ICON_50d("50d") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_fog;
-        }
-    },
-    ICON_50n("50n") {
-        @Override
-        public int getResourceDrawable() {
-            return R.drawable.weather_fog;
-        }
-    };
-
-    private final String icon;
-    // Map with every enum constant. Class variable initializer. JLS§12.4.2
-    // Executed in textual order.
-    private static final Map<String, IconsList> codeMap = new HashMap<String, IconsList>();
-
-    // Static initializer. JLS§12.4.2 Executed in textual order.
-    static {
-        for (final IconsList code : IconsList.values()) {
-            codeMap.put(code.getIcon(), code);
-        }
-    }
-
-    private IconsList(final String icon) {
-        this.icon = icon;
-    }
-
-    public static final IconsList getIcon(final String icon) {
-        return codeMap.get(icon);
-    }
-
-    private String getIcon() {
-        return this.icon;
-    }
-
-    public abstract int getResourceDrawable();
-}
diff --git a/src/de/example/exampletdd/service/PermanentStorage.java b/src/de/example/exampletdd/service/PermanentStorage.java
deleted file mode 100644 (file)
index 49eac40..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-package de.example.exampletdd.service;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.StreamCorruptedException;
-
-import android.content.Context;
-import android.util.Log;
-import de.example.exampletdd.model.currentweather.Current;
-import de.example.exampletdd.model.forecastweather.Forecast;
-
-
-/**
- * TODO: show some error message when there is no enough space for saving files. :/
- *
- */
-public class PermanentStorage {
-       private static final String TAG = "PermanentStorage";
-    private static final String CURRENT_DATA_FILE = "current.file";
-    private static final String FORECAST_DATA_FILE = "forecast.file";
-    private final Context context;
-
-    public PermanentStorage(final Context context) {
-        this.context = context;
-    }
-
-    public void saveCurrent(final Current current) {
-       
-        try {
-                       this.saveObject(CURRENT_DATA_FILE, current);
-               } catch (FileNotFoundException e) {
-                       Log.e(TAG, "saveCurrent exception: ", e);
-               } catch (IOException e) {
-                       Log.e(TAG, "saveCurrent exception: ", e);
-               }
-    }
-
-    public Current getCurrent() {
-       
-       try {
-                       return (Current) this.getObject(CURRENT_DATA_FILE);
-               } catch (final StreamCorruptedException e) {
-                       Log.e(TAG, "getCurrent exception: ", e);
-               } catch (final FileNotFoundException e) {
-                       Log.e(TAG, "getCurrent exception: ", e);
-               } catch (final IOException e) {
-                       Log.e(TAG, "getCurrent exception: ", e);
-               } catch (final ClassNotFoundException e) {
-                       Log.e(TAG, "getCurrent exception: ", e);
-               }
-       
-       return null;
-    }
-
-    public void saveForecast(final Forecast forecast) {
-
-       try {
-                       this.saveObject(FORECAST_DATA_FILE, forecast);
-               } catch (FileNotFoundException e) {
-                       Log.e(TAG, "saveForecast exception: ", e);
-               } catch (IOException e) {
-                       Log.e(TAG, "saveForecast exception: ", e);
-               }
-    }
-
-    public Forecast getForecast() {
-        
-       try {
-                       return (Forecast) this.getObject(FORECAST_DATA_FILE);
-               } catch (final StreamCorruptedException e) {
-                       Log.e(TAG, "getForecast exception: ", e);
-               } catch (final FileNotFoundException e) {
-                       Log.e(TAG, "getForecast exception: ", e);
-               } catch (final IOException e) {
-                       Log.e(TAG, "getForecast exception: ", e);
-               } catch (final ClassNotFoundException e) {
-                       Log.e(TAG, "getForecast exception: ", e);
-               }
-       
-       return null;
-    }
-
-    private void saveObject(final String fileName, final Object objectToStore)
-               throws FileNotFoundException, IOException {
-       final String temporaryFileName = fileName.concat(".tmp");
-       
-        final FileOutputStream tmpPersistFile = this.context.openFileOutput(
-                       temporaryFileName, Context.MODE_PRIVATE);
-        try {
-               final ObjectOutputStream oos = new ObjectOutputStream(tmpPersistFile);
-               try {
-                       oos.writeObject(objectToStore);
-                       
-                       // Don't fear the fsync!
-                       // http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/
-                       tmpPersistFile.flush();
-                       tmpPersistFile.getFD().sync();
-               } finally {
-                       oos.close();
-               }
-        } finally {
-               tmpPersistFile.close();
-        }
-
-        this.renameFile(temporaryFileName, fileName);
-    }
-    private Object getObject(final String fileName) throws StreamCorruptedException, FileNotFoundException,
-                                                                                                          IOException, ClassNotFoundException {
-       final InputStream persistFile = this.context.openFileInput(fileName);
-       try {
-               final ObjectInputStream ois = new ObjectInputStream(persistFile);
-               try {
-                       return ois.readObject();
-               } finally {
-                       ois.close();
-               }
-       } finally {
-               persistFile.close();
-       }
-    } 
-    
-    private void renameFile(final String fromFileName, final String toFileName) throws IOException {
-        final File filesDir = this.context.getFilesDir();
-        final File fromFile = new File(filesDir, fromFileName);
-        final File toFile = new File(filesDir, toFileName);
-        if (!fromFile.renameTo(toFile)) {
-               if (!fromFile.delete()) {
-                       throw new IOException("PermanentStorage, delete file error");
-               }       
-               throw new IOException("PermanentStorage, rename file error");
-        }
-    }
-}
-
diff --git a/src/de/example/exampletdd/service/ServiceParser.java b/src/de/example/exampletdd/service/ServiceParser.java
deleted file mode 100644 (file)
index e05a67f..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-package de.example.exampletdd.service;
-
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.Locale;
-
-import com.fasterxml.jackson.core.JsonParseException;
-
-import de.example.exampletdd.model.currentweather.Current;
-import de.example.exampletdd.model.forecastweather.Forecast;
-import de.example.exampletdd.parser.IJPOSParser;
-
-public class ServiceParser {
-    private final IJPOSParser JPOSParser;
-
-    public ServiceParser(final IJPOSParser JPOSWeatherParser) {
-        this.JPOSParser = JPOSWeatherParser;
-    }
-
-    public Current retrieveCurrentFromJPOS(final String jsonData)
-            throws JsonParseException, IOException {
-        return this.JPOSParser.retrieveCurrenFromJPOS(jsonData);
-    }
-
-    public Forecast retrieveForecastFromJPOS(final String jsonData)
-            throws JsonParseException, IOException {
-        return this.JPOSParser.retrieveForecastFromJPOS(jsonData);
-    }
-
-    public String createURIAPIForecast(final String urlAPI, final String APIVersion,
-            final double latitude, final double longitude, final String resultsNumber) {
-
-        final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US);
-        final Object[] values = new Object[4];
-        values[0] = APIVersion;
-        values[1] = latitude;
-        values[2] = longitude;
-        values[3] = resultsNumber;
-
-        return formatURIAPI.format(values);
-    }
-
-    public String createURIAPICurrent(final String urlAPI, final String APIVersion,
-            final double latitude, final double longitude) {
-
-        final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US);
-        final Object[] values = new Object[3];
-        values[0] = APIVersion;
-        values[1] = latitude;
-        values[2] = longitude;
-
-        return formatURIAPI.format(values);
-    }
-
-    public String createURIAPIicon(final String icon, final String urlAPI) {
-
-        final MessageFormat formatURIAPI = new MessageFormat(urlAPI, Locale.US);
-        final Object[] values = new Object[1];
-        values[0] = icon;
-
-        return formatURIAPI.format(values);
-    }
-
-}
diff --git a/src/de/example/exampletdd/widget/WidgetConfigure.java b/src/de/example/exampletdd/widget/WidgetConfigure.java
deleted file mode 100644 (file)
index bb5d8ca..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-package de.example.exampletdd.widget;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.Fragment;
-import android.appwidget.AppWidgetManager;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import de.example.exampletdd.R;
-
-public class WidgetConfigure extends Activity {
-       private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
-       
-    final View.OnClickListener mOnClickListener = new View.OnClickListener() {
-        public void onClick(View v) {
-
-               
-            // When the button is clicked, save the string in our prefs and return that they
-            // clicked OK.
-            // Push widget update to surface with newly set prefix
-            final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(
-                       WidgetConfigure.this.getApplicationContext());
-            WidgetProvider.updateAppWidget(
-                       WidgetConfigure.this.getApplicationContext(),
-                       appWidgetManager,
-                    mAppWidgetId);
-
-            // Make sure we pass back the original appWidgetId
-            final Intent resultValue = new Intent();
-            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
-            WidgetConfigure.this.setResult(RESULT_OK, resultValue);
-            finish();
-        }
-    };
-
-    @Override
-    public void onCreate(final Bundle icicle) {
-        super.onCreate(icicle);
-
-        // Find the widget id from the intent. 
-        final Intent intent = getIntent();
-        final Bundle extras = intent.getExtras();
-        boolean isActionFromUser = false;
-
-        if (extras != null) {
-            mAppWidgetId = extras.getInt(
-                    AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
-            
-            isActionFromUser = extras.getBoolean("actionFromUser", false);
-        }
-        
-        // If they gave us an intent without the widget id, just bail.
-       if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
-               this.finish();
-       }
-       
-        if (!isActionFromUser) {
-            // Set the result to CANCELED.  This will cause the widget host to cancel
-            // out of the widget placement if they press the back button.
-            this.setResult(RESULT_CANCELED);
-        }
-        
-        // Set the view layout resource to use.
-        this.setContentView(R.layout.appwidget_configure);
-        
-       final Bundle args = new Bundle();
-       args.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
-       final Fragment preferences = new WidgetPreferences();
-        preferences.setRetainInstance(true);
-       preferences.setArguments(args);
-        this.getFragmentManager()
-        .beginTransaction()
-        .replace(R.id.weather_appwidget_configure_preferences, preferences)
-        .commit();
-        
-        // Bind the action for the save button.
-        this.findViewById(R.id.weather_appwidget_configure_save_button).setOnClickListener(mOnClickListener);
-    }
-    
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        final ActionBar actionBar = this.getActionBar();
-        actionBar.setTitle(this.getString(R.string.widget_preferences_action_settings));
-    }
-}
diff --git a/src/de/example/exampletdd/widget/WidgetPreferences.java b/src/de/example/exampletdd/widget/WidgetPreferences.java
deleted file mode 100644 (file)
index 7744ea8..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-package de.example.exampletdd.widget;
-
-import android.appwidget.AppWidgetManager;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Bundle;
-import android.preference.ListPreference;
-import android.preference.PreferenceFragment;
-import android.preference.SwitchPreference;
-import de.example.exampletdd.R;
-
-/**
- * TODO:
- * IT DOES NOT WORK IF USER IS WORKING WITH TWO OR MORE WIDGET PREFERENCE WINDOWS AT THE SAME TIME
- * (hopefully nobody will realize...)
- * How to implement custom preference activities (no extending from PreferenceActivity or PreferenceFragment)
- * without pain?
- */
-public class WidgetPreferences extends PreferenceFragment implements OnSharedPreferenceChangeListener {
-       private int appWidgetId;
-       
-    @Override
-    public void onCreate(final Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Retain this fragment across configuration changes.
-       this.setRetainInstance(true);
-       
-       final Bundle bundle = this.getArguments();
-       appWidgetId = bundle.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
-       
-        // Load the preferences from an XML resource
-        this.addPreferencesFromResource(R.xml.appwidget_preferences);
-
-
-        /******************* Show/hide country field *******************/
-        String keyPreference = this.getActivity().getApplicationContext().getString(
-                R.string.widget_preferences_country_switch_key);
-        String realKeyPreference = keyPreference + "_" + appWidgetId;
-        
-        // What was saved to permanent storage (or default values if it is the first time)
-        boolean countryValue = this.getActivity().getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE)
-                       .getBoolean(realKeyPreference, false);
-        
-        // What is shown on the screen
-        final SwitchPreference countryPref = (SwitchPreference) this.findPreference(keyPreference);
-        countryPref.setChecked(countryValue);
-
-        /********************* Temperature units  **********************/
-        final String[] values = this.getResources().getStringArray(R.array.weather_preferences_temperature);
-        final String[] humanValues = this.getResources().getStringArray(R.array.weather_preferences_temperature_human_value);
-
-        keyPreference = this.getActivity().getApplicationContext().getString(
-                R.string.widget_preferences_temperature_key);
-        realKeyPreference = keyPreference + "_" + appWidgetId;
-
-
-        // What was saved to permanent storage (or default values if it is the first time)
-        final String tempValue = this.getActivity().getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE)
-                       .getString(realKeyPreference, this.getString(R.string.weather_preferences_temperature_celsius));
-        String humanValue = this.getString(R.string.weather_preferences_temperature_celsius_human_value);
-        int index = 0;
-        if (tempValue.equals(values[0])) {
-               index = 0;
-            humanValue = humanValues[0];
-        } else if (tempValue.equals(values[1])) {
-               index = 1;
-            humanValue = humanValues[1];
-        } else if (tempValue.equals(values[2])) {
-               index = 2;
-            humanValue = humanValues[2];
-        }
-
-
-        // What is shown on the screen
-        final ListPreference listPref = (ListPreference) this.findPreference(keyPreference);
-        listPref.setSummary(humanValue);
-        listPref.setValueIndex(index);
-        listPref.setValue(tempValue);
-    }
-
-    @Override
-       public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
-
-       /******************* Show/hide country field *******************/
-        String keyPreference = this.getActivity().getApplicationContext().getString(
-                       R.string.widget_preferences_country_switch_key);
-        if (key.equals(keyPreference)) {
-               final String realKeyPreference = keyPreference + "_" + appWidgetId;
-               // Saving to permanent storage.
-               final SharedPreferences.Editor prefs =
-                               this.getActivity().getSharedPreferences(
-                                               "WIDGET_PREFERENCES", 
-                                               Context.MODE_PRIVATE).edit();
-               // What is shown on the screen
-               final SwitchPreference preference = (SwitchPreference) this.findPreference(key);
-               if (preference.isChecked())
-               {
-                       // Saving to permanent storage.
-                       prefs.putBoolean(realKeyPreference, true); 
-               } else {
-                       // Saving to permanent storage.
-                       prefs.putBoolean(realKeyPreference, false); 
-               }
-               prefs.commit();
-        }
-
-       /********************* Temperature units  **********************/
-        keyPreference = this.getActivity().getApplicationContext().getString(
-                R.string.widget_preferences_temperature_key);
-        if (key.equals(keyPreference)) {
-               final String[] values = this.getResources().getStringArray(
-                               R.array.weather_preferences_temperature);
-               final String[] humanValues = this.getResources().getStringArray(
-                               R.array.weather_preferences_temperature_human_value);
-               
-               // What is shown on the screen
-               final ListPreference listPref = (ListPreference) this.findPreference(key);
-               final String value = listPref.getValue();
-               String humanValue = "";
-               if (value.equals(values[0])) {
-                       humanValue = humanValues[0];
-               } else if (value.equals(values[1])) {
-                       humanValue = humanValues[1];
-               } else if (value.equals(values[2])) {
-                       humanValue = humanValues[2];
-               }
-               // Update data on screen
-               listPref.setSummary(humanValue);
-               
-               
-               // Saving to permanent storage.
-            final String realKeyPreference = keyPreference + "_" + appWidgetId;
-            
-               final SharedPreferences.Editor prefs =
-                               this.getActivity().getSharedPreferences(
-                                               "WIDGET_PREFERENCES", 
-                                               Context.MODE_PRIVATE).edit();
-            prefs.putString(realKeyPreference, value);
-            prefs.commit();
-               return;
-        }
-        
-        
-
-       }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        this.getPreferenceManager().getSharedPreferences()
-        .registerOnSharedPreferenceChangeListener(this);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        this.getPreferenceManager().getSharedPreferences()
-        .unregisterOnSharedPreferenceChangeListener(this);
-    }
-    
-    public static void deletePreference(final Context context, final int appWidgetId) {
-       final String keyPreference = context.getApplicationContext().getString(
-                R.string.widget_preferences_temperature_key);
-        final String realKeyPreference = keyPreference + "_" + appWidgetId;
-
-       final SharedPreferences.Editor prefs = context.getSharedPreferences("WIDGET_PREFERENCES", Context.MODE_PRIVATE).edit();
-       prefs.remove(realKeyPreference);
-       prefs.commit();
-    }
-}
diff --git a/src/de/example/exampletdd/widget/WidgetProvider.java b/src/de/example/exampletdd/widget/WidgetProvider.java
deleted file mode 100644 (file)
index b5126f6..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-package de.example.exampletdd.widget;
-
-
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProvider;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import de.example.exampletdd.WidgetIntentService;
-
-public class WidgetProvider extends AppWidgetProvider {
-
-    @Override
-    public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
-        // For each widget that needs an update, get the text that we should display:
-        //   - Create a RemoteViews object for it
-        //   - Set the text in the RemoteViews object
-        //   - Tell the AppWidgetManager to show that views object for the widget.
-        final int N = appWidgetIds.length;
-        for (int i=0; i<N; i++) {
-            int appWidgetId = appWidgetIds[i];
-            // To prevent any ANR timeouts, we perform the update in a service
-               final Intent intent = new Intent(context.getApplicationContext(), WidgetIntentService.class);
-               intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-               intent.putExtra("updateByApp", false);
-            context.startService(intent);
-        }
-    }
-    
-    @Override
-    public void onDeleted(final Context context, final int[] appWidgetIds) {
-        // When the user deletes the widget, delete the preference associated with it.
-        final int N = appWidgetIds.length;
-        for (int i=0; i<N; i++) {
-               WidgetPreferences.deletePreference(context, appWidgetIds[i]);
-        }
-    }
-    
-    static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager, final int appWidgetId) {
-
-        int widgetId;
-        Bundle myOptions = appWidgetManager.getAppWidgetOptions(appWidgetId);
-
-        // Get the value of OPTION_APPWIDGET_HOST_CATEGORY
-        int category = myOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1);
-
-        // If the value is WIDGET_CATEGORY_KEYGUARD, it's a lockscreen widget
-        boolean isKeyguard = category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
-        
-        // Once you know the widget's category, you can optionally load a different base layout, set different 
-        // properties, and so on. For example:
-        //int baseLayout = isKeyguard ? R.layout.keyguard_widget_layout : R.layout.widget_layout;
-        
-        // Construct the RemoteViews object.  It takes the package name (in our case, it's our
-        // package, but it needs this because on the other side it's the widget host inflating
-        // the layout from our package).
-        //final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget);
-        
-        final Intent intent = new Intent(context.getApplicationContext(), WidgetIntentService.class);
-       intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-        context.startService(intent);
-    }
-}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
deleted file mode 100644 (file)
index 80c69cf..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="de.example.exampletdd.test"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-sdk android:minSdkVersion="18" android:maxSdkVersion="18" android:targetSdkVersion="18"/>
-
-    <instrumentation
-        android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="de.example.exampletdd" />
-
-    <application
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name" >
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-</manifest>
\ No newline at end of file
diff --git a/tests/gen/de/example/exampletdd/test/BuildConfig.java b/tests/gen/de/example/exampletdd/test/BuildConfig.java
deleted file mode 100644 (file)
index 4da8fd7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/** Automatically generated file. DO NOT MODIFY */
-package de.example.exampletdd.test;
-
-public final class BuildConfig {
-    public final static boolean DEBUG = true;
-}
\ No newline at end of file
diff --git a/tests/gen/de/example/exampletdd/test/R.java b/tests/gen/de/example/exampletdd/test/R.java
deleted file mode 100644 (file)
index e4a8d5e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* AUTO-GENERATED FILE.  DO NOT MODIFY.
- *
- * This class was automatically generated by the
- * aapt tool from the resource data it found.  It
- * should not be modified by hand.
- */
-
-package de.example.exampletdd.test;
-
-public final class R {
-    public static final class attr {
-    }
-    public static final class drawable {
-        public static final int ic_launcher=0x7f020000;
-    }
-    public static final class string {
-        public static final int app_name=0x7f030000;
-    }
-}
diff --git a/tests/proguard-project.txt b/tests/proguard-project.txt
deleted file mode 100644 (file)
index f2fe155..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
diff --git a/tests/project.properties b/tests/project.properties
deleted file mode 100644 (file)
index ce39f2d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-18
diff --git a/tests/res/drawable-hdpi/ic_launcher.png b/tests/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644 (file)
index 96a442e..0000000
Binary files a/tests/res/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/tests/res/drawable-ldpi/ic_launcher.png b/tests/res/drawable-ldpi/ic_launcher.png
deleted file mode 100644 (file)
index 9923872..0000000
Binary files a/tests/res/drawable-ldpi/ic_launcher.png and /dev/null differ
diff --git a/tests/res/drawable-mdpi/ic_launcher.png b/tests/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644 (file)
index 359047d..0000000
Binary files a/tests/res/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/tests/res/drawable-xhdpi/ic_launcher.png b/tests/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644 (file)
index 71c6d76..0000000
Binary files a/tests/res/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/tests/res/values/strings.xml b/tests/res/values/strings.xml
deleted file mode 100644 (file)
index 00a3f66..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <string name="app_name">Weather Information Test</string>
-
-</resources>
diff --git a/tests/src/de/example/exampletdd/test/JPOSWeatherParserTest.java b/tests/src/de/example/exampletdd/test/JPOSWeatherParserTest.java
deleted file mode 100644 (file)
index 42e89eb..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package de.example.exampletdd.test;
-
-import junit.framework.TestCase;
-
-import org.json.JSONException;
-
-import de.example.exampletdd.model.WeatherData;
-import de.example.exampletdd.parser.JPOSWeatherParser;
-
-public class JPOSWeatherParserTest extends TestCase {
-    private JPOSWeatherParser jposWeatherParser;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        this.jposWeatherParser = new JPOSWeatherParser();
-    }
-
-    public void testRetrieveWeatherFromJPOS() throws JSONException {
-        // Arrange
-        final String jsonData = "{\"coord\":{\"lon\":139,\"lat\":35}}";
-        final double longitude = 139;
-        final double latitude = 35;
-        final WeatherData.Coord coord = new WeatherData.Coord(longitude, latitude);
-        final WeatherData expectedWeather = new WeatherData.Builder().setCoord(coord).build();
-
-        // Act
-        final WeatherData finalWeather = this.jposWeatherParser.retrieveWeatherFromJPOS(jsonData);
-
-        // Assert
-        assertEquals(expectedWeather.toString(), finalWeather.toString());
-    }
-
-}
diff --git a/tests/src/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java b/tests/src/de/example/exampletdd/test/WeatherInformationActivityUnitTest.java
deleted file mode 100644 (file)
index 90c0d07..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-package de.example.exampletdd.test;
-
-import android.content.Intent;
-import android.test.ActivityUnitTestCase;
-import android.widget.Button;
-import de.example.exampletdd.WeatherInformationActivity;
-
-public class WeatherInformationActivityUnitTest extends
-        ActivityUnitTestCase<WeatherInformationActivity> {
-
-    private WeatherInformationActivity activity;
-
-    public WeatherInformationActivityUnitTest() {
-        super(WeatherInformationActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        final Intent intent = new Intent(this.getInstrumentation().getTargetContext(),
-                WeatherInformationActivity.class);
-        this.startActivity(intent, null, null);
-        this.activity = this.getActivity();
-    }
-
-    public void testIntentTriggerViaOnClick() {
-        final int buttonweather = de.example.exampletdd.R.id.buttonweather;
-        final Button view = (Button) this.activity.findViewById(buttonweather);
-        assertNotNull("Button Weather not allowed to be null", view);
-
-        view.performClick();
-
-        // TouchUtils cannot be used, only allowed in
-        // InstrumentationTestCase or ActivityInstrumentationTestCase2
-
-        // Check the intent which was started
-        final Intent triggeredIntent = this.getStartedActivityIntent();
-        assertNotNull("Intent was null", triggeredIntent);
-        final String data = triggeredIntent.getDataString();
-
-        assertEquals("Incorrect data passed via the intent",
-                "http://gumartinm.name", data);
-    }
-}