diff --git a/app/build.gradle b/app/build.gradle index 68d22f95..bf3452cc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,9 +7,10 @@ android { defaultConfig { applicationId "cz.martykan.forecastie" minSdkVersion 15 + //noinspection ExpiringTargetSdkVersion targetSdkVersion 29 - versionCode 68 - versionName "1.18.2" + versionCode 69 + versionName "1.19.0" } lintOptions { @@ -36,7 +37,6 @@ dependencies { implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation "com.google.android.material:material:1.2.1" implementation "com.google.android.flexbox:flexbox:3.0.0" - implementation "androidx.core:core:1.5.0" /** Lifecycle */ implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion" diff --git a/app/src/main/java/cz/martykan/forecastie/activities/SplashActivity.java b/app/src/main/java/cz/martykan/forecastie/activities/SplashActivity.java index 0355545e..4244f833 100644 --- a/app/src/main/java/cz/martykan/forecastie/activities/SplashActivity.java +++ b/app/src/main/java/cz/martykan/forecastie/activities/SplashActivity.java @@ -15,35 +15,27 @@ import cz.martykan.forecastie.notifications.WeatherNotificationService; public class SplashActivity extends AppCompatActivity { + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - showWeatherNotificationIfNeeded(); - - Intent intent = new Intent(this, MainActivity.class); - startActivity(intent); - finish(); - } - - private void showWeatherNotificationIfNeeded() { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - if (prefs == null) - return; - // we should check permission here because user can update Android version between app launches - boolean foregroundServicesPermissionGranted = isForegroundServicesPermissionGranted(); - boolean isWeatherNotificationEnabled = - prefs.getBoolean(getString(R.string.settings_enable_notification_key), false); - if (isWeatherNotificationEnabled && foregroundServicesPermissionGranted) { + boolean foregroundServicesPermissionGranted = + Build.VERSION.SDK_INT < Build.VERSION_CODES.P + || + ContextCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE) + == PackageManager.PERMISSION_GRANTED; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + if (prefs != null + && prefs.getBoolean(getString(R.string.settings_enable_notification_key), false) + && foregroundServicesPermissionGranted + ) { WeatherNotificationService.start(this); } - } - private boolean isForegroundServicesPermissionGranted() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) - return true; // There is no need for this permission prior Android Pie (Android SDK 28) - return ContextCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE) - == PackageManager.PERMISSION_GRANTED; + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + finish(); } } diff --git a/app/src/main/java/cz/martykan/forecastie/models/WeatherPresentation.java b/app/src/main/java/cz/martykan/forecastie/models/WeatherPresentation.java index d15ba8ad..56f364a8 100644 --- a/app/src/main/java/cz/martykan/forecastie/models/WeatherPresentation.java +++ b/app/src/main/java/cz/martykan/forecastie/models/WeatherPresentation.java @@ -15,15 +15,12 @@ public class WeatherPresentation { public static final String DEFAULT_WIND_DIRECTION_FORMAT = "arrow"; /** Default pressure units is hPa/mBar. */ public static final String DEFAULT_PRESSURE_UNITS = "hPa/mBar"; - /** Show temperature in status bar by default. */ - public static final boolean DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR = true; private final boolean roundedTemperature; private final String temperatureUnits; private final String windSpeedUnits; private final String windDirectionFormat; private final String pressureUnits; - private final boolean showTemperatureInStatusBar; /** Weather information. */ private final ImmutableWeather weather; private final WeatherFormatterType type; @@ -34,16 +31,13 @@ public WeatherPresentation() { windSpeedUnits = DEFAULT_WIND_SPEED_UNITS; windDirectionFormat = DEFAULT_WIND_DIRECTION_FORMAT; pressureUnits = DEFAULT_PRESSURE_UNITS; - showTemperatureInStatusBar = DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR; weather = ImmutableWeather.EMPTY; type = WeatherFormatterType.NOTIFICATION_SIMPLE; } - public WeatherPresentation( - boolean roundedTemperature, @NonNull String temperatureUnits, + public WeatherPresentation(boolean roundedTemperature, @NonNull String temperatureUnits, @NonNull String windSpeedUnits, @NonNull String windDirectionFormat, - @NonNull String pressureUnits, boolean showTemperatureInStatusBar, - @NonNull ImmutableWeather weather, + @NonNull String pressureUnits, @NonNull ImmutableWeather weather, @NonNull WeatherFormatterType type ) { this.roundedTemperature = roundedTemperature; @@ -51,7 +45,6 @@ public WeatherPresentation( this.windSpeedUnits = windSpeedUnits; this.windDirectionFormat = windDirectionFormat; this.pressureUnits = pressureUnits; - this.showTemperatureInStatusBar = showTemperatureInStatusBar; this.weather = weather; this.type = type; } @@ -64,14 +57,6 @@ public boolean isRoundedTemperature() { return roundedTemperature; } - /** - * Returns {@code true} if temperature should be shown in status bar and {@code false} if shouldn't. - * @return {@code true} if temperature should be shown in status bar and {@code false} if shouldn't - */ - public boolean shouldShowTemperatureInStatusBar() { - return showTemperatureInStatusBar; - } - /** * Returns temperature units as temperature unit key. * @return temperature units @@ -121,67 +106,38 @@ public WeatherFormatterType getType() { } public WeatherPresentation copy(boolean roundedTemperature) { - return new WeatherPresentation( - roundedTemperature, temperatureUnits, windSpeedUnits, - windDirectionFormat, pressureUnits, showTemperatureInStatusBar, - weather, type - ); + return new WeatherPresentation(roundedTemperature, temperatureUnits, windSpeedUnits, + windDirectionFormat, pressureUnits, weather, type); } public WeatherPresentation copyTemperatureUnits(@NonNull String temperatureUnits) { - return new WeatherPresentation( - roundedTemperature, temperatureUnits, windSpeedUnits, - windDirectionFormat, pressureUnits, showTemperatureInStatusBar, - weather, type - ); + return new WeatherPresentation(roundedTemperature, temperatureUnits, windSpeedUnits, + windDirectionFormat, pressureUnits, weather, type); } public WeatherPresentation copyWindSpeedUnits(@NonNull String windSpeedUnits) { - return new WeatherPresentation( - roundedTemperature, temperatureUnits, windSpeedUnits, - windDirectionFormat, pressureUnits, showTemperatureInStatusBar, - weather, type - ); + return new WeatherPresentation(roundedTemperature, temperatureUnits, windSpeedUnits, + windDirectionFormat, pressureUnits, weather, type); } public WeatherPresentation copyWindDirectionFormat(@NonNull String windDirectionFormat) { - return new WeatherPresentation( - roundedTemperature, temperatureUnits, windSpeedUnits, - windDirectionFormat, pressureUnits, showTemperatureInStatusBar, - weather, type - ); + return new WeatherPresentation(roundedTemperature, temperatureUnits, windSpeedUnits, + windDirectionFormat, pressureUnits, weather, type); } public WeatherPresentation copyPressureUnits(@NonNull String pressureUnits) { - return new WeatherPresentation( - roundedTemperature, temperatureUnits, windSpeedUnits, - windDirectionFormat, pressureUnits, showTemperatureInStatusBar, - weather, type - ); - } - - public WeatherPresentation copyShowTemperatureInStatusBar(boolean showTemperatureInStatusBar) { - return new WeatherPresentation( - roundedTemperature, temperatureUnits, windSpeedUnits, - windDirectionFormat, pressureUnits, showTemperatureInStatusBar, - weather, type - ); + return new WeatherPresentation(roundedTemperature, temperatureUnits, windSpeedUnits, + windDirectionFormat, pressureUnits, weather, type); } public WeatherPresentation copy(@NonNull ImmutableWeather weather) { - return new WeatherPresentation( - roundedTemperature, temperatureUnits, windSpeedUnits, - windDirectionFormat, pressureUnits, showTemperatureInStatusBar, - weather, type - ); + return new WeatherPresentation(roundedTemperature, temperatureUnits, windSpeedUnits, + windDirectionFormat, pressureUnits, weather, type); } public WeatherPresentation copy(@NonNull WeatherFormatterType type) { - return new WeatherPresentation( - roundedTemperature, temperatureUnits, windSpeedUnits, - windDirectionFormat, pressureUnits, showTemperatureInStatusBar, - weather, type - ); + return new WeatherPresentation(roundedTemperature, temperatureUnits, windSpeedUnits, + windDirectionFormat, pressureUnits, weather, type); } @Override @@ -197,7 +153,6 @@ public boolean equals(Object o) { if (!windDirectionFormat.equals(that.windDirectionFormat)) return false; if (!pressureUnits.equals(that.pressureUnits)) return false; if (!weather.equals(that.weather)) return false; - if (showTemperatureInStatusBar != that.showTemperatureInStatusBar) return false; return type == that.type; } @@ -208,13 +163,11 @@ public int hashCode() { result = 31 * result + windSpeedUnits.hashCode(); result = 31 * result + windDirectionFormat.hashCode(); result = 31 * result + pressureUnits.hashCode(); - result = 31 * result + (showTemperatureInStatusBar ? 1 : 0); result = 31 * result + weather.hashCode(); result = 31 * result + type.hashCode(); return result; } - @NonNull @Override public String toString() { return "WeatherPresentation{" + @@ -223,7 +176,6 @@ public String toString() { ", windSpeedUnits='" + windSpeedUnits + '\'' + ", windDirectionFormat='" + windDirectionFormat + '\'' + ", pressureUnits='" + pressureUnits + '\'' + - ", shouldShowTemperatureInStatusBar=" + showTemperatureInStatusBar + ", weather=" + weather + ", type=" + type + '}'; diff --git a/app/src/main/java/cz/martykan/forecastie/notifications/WeatherNotificationService.java b/app/src/main/java/cz/martykan/forecastie/notifications/WeatherNotificationService.java index 428a28c1..906e43f7 100644 --- a/app/src/main/java/cz/martykan/forecastie/notifications/WeatherNotificationService.java +++ b/app/src/main/java/cz/martykan/forecastie/notifications/WeatherNotificationService.java @@ -32,7 +32,6 @@ * Service for showing and updating notification. */ public class WeatherNotificationService extends Service { - private static final String TAG = "WeatherNotificationServ"; public static int WEATHER_NOTIFICATION_ID = 1; private static final String WEATHER_NOTIFICATION_CHANNEL_ID = "weather_notification_channel"; @@ -57,6 +56,7 @@ public void onCreate() { repositoryListener = new WeatherRepository.RepositoryListener() { @Override public void onChange(@NonNull WeatherPresentation newData) { + Log.e("f", "RepositoryListener: " + newData.toString()); updateNotification(newData); } }; @@ -74,7 +74,7 @@ public void onConfigurationChanged(Configuration newConfig) { private void configureNotification(PendingIntent pendingIntent) { notification = new NotificationCompat.Builder(this, WEATHER_NOTIFICATION_CHANNEL_ID) - .setSmallIcon(NotificationContentUpdater.DEFAULT_NOTIFICATION_ICON) + .setSmallIcon(R.drawable.cloud) .setContentIntent(pendingIntent) .setOngoing(true) .setOnlyAlertOnce(true) @@ -127,7 +127,7 @@ public IBinder onBind(Intent intent) { * Put data into notification. */ private void updateNotification(@NonNull WeatherPresentation weatherPresentation) { - Log.e(TAG, "notification update: " + weatherPresentation.toString()); + Log.e("f", "notification update: " + weatherPresentation.toString()); NotificationContentUpdater updater = getContentUpdater(weatherPresentation.getType()); if (updater.isLayoutCustom()) { RemoteViews layout = updater.prepareRemoteView(this); diff --git a/app/src/main/java/cz/martykan/forecastie/notifications/repository/WeatherRepository.java b/app/src/main/java/cz/martykan/forecastie/notifications/repository/WeatherRepository.java index 93d8a2b1..7e2bc7b5 100644 --- a/app/src/main/java/cz/martykan/forecastie/notifications/repository/WeatherRepository.java +++ b/app/src/main/java/cz/martykan/forecastie/notifications/repository/WeatherRepository.java @@ -29,11 +29,10 @@ * Intent when some class updates data because Observer pattern grants us one source of truth. */ public class WeatherRepository { - private String notificationTypeKey; - private String notificationTypeDefaultKey; - private String notificationTypeSimpleKey; - private String notificationTypeDefault; - private String showTemperatureInStatusBarKey; + private String typeKey; + private String typeDefaultKey; + private String typeSimpleKey; + private String typeDefault; private final Executor executor; private SharedPreferences prefs; @@ -119,7 +118,6 @@ private WeatherPresentation readValuesFromStorage() { prefs.getString("speedUnit", WeatherPresentation.DEFAULT_WIND_SPEED_UNITS), prefs.getString("windDirectionFormat", WeatherPresentation.DEFAULT_WIND_DIRECTION_FORMAT), prefs.getString("pressureUnit", WeatherPresentation.DEFAULT_PRESSURE_UNITS), - prefs.getBoolean(showTemperatureInStatusBarKey, WeatherPresentation.DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR), weather, type ); } @@ -128,13 +126,13 @@ private WeatherPresentation readValuesFromStorage() { @NonNull private WeatherFormatterType readNotificationType(@NonNull SharedPreferences prefs) { WeatherFormatterType result; - String typePref = prefs.getString(notificationTypeKey, notificationTypeDefault); - if (typePref != null && typePref.equalsIgnoreCase(notificationTypeDefaultKey)) { + String typePref = prefs.getString(typeKey, typeDefault); + if (typePref != null && typePref.equalsIgnoreCase(typeDefaultKey)) { result = WeatherFormatterType.NOTIFICATION_DEFAULT; - } else if (typePref != null && typePref.equalsIgnoreCase(notificationTypeSimpleKey)) { + } else if (typePref != null && typePref.equalsIgnoreCase(typeSimpleKey)) { result = WeatherFormatterType.NOTIFICATION_SIMPLE; } else { - if (notificationTypeDefault == null || notificationTypeDefault.equalsIgnoreCase(notificationTypeDefaultKey)) { + if (typeDefault == null || typeDefault.equalsIgnoreCase(typeDefaultKey)) { result = WeatherFormatterType.NOTIFICATION_DEFAULT; } else { result = WeatherFormatterType.NOTIFICATION_SIMPLE; @@ -144,11 +142,10 @@ private WeatherFormatterType readNotificationType(@NonNull SharedPreferences pre } private void prepareSettingsConstants(@NonNull Context context) { - notificationTypeKey = context.getString(R.string.settings_notification_type_key); - notificationTypeDefaultKey = context.getString(R.string.settings_notification_type_key_default); - notificationTypeSimpleKey = context.getString(R.string.settings_notification_type_key_simple); - notificationTypeDefault = context.getString(R.string.settings_notification_type_default_value); - showTemperatureInStatusBarKey = context.getString(R.string.settings_show_temperature_in_status_bar_key); + typeKey = context.getString(R.string.settings_notification_type_key); + typeDefaultKey = context.getString(R.string.settings_notification_type_key_default); + typeSimpleKey = context.getString(R.string.settings_notification_type_key_simple); + typeDefault = context.getString(R.string.settings_notification_type_default_value); } /** Callback method to get updated weather data and settings. */ @@ -198,7 +195,7 @@ public void run() { case "lastUpdate": case "lastToday": String json = sharedPreferences.getString("lastToday", ""); - if (json != null && !json.isEmpty()) { + if (!json.isEmpty()) { long lastUpdate = sharedPreferences.getLong("lastUpdate", -1L); ImmutableWeather weather = ImmutableWeather.fromJson(json, lastUpdate); result = weatherPresentation.copy(weather); @@ -212,41 +209,27 @@ public void run() { case "unit": String temperatureUnits = sharedPreferences.getString(key, WeatherPresentation.DEFAULT_TEMPERATURE_UNITS); - if (temperatureUnits != null) { - result = weatherPresentation.copyTemperatureUnits(temperatureUnits); - } + result = weatherPresentation.copyTemperatureUnits(temperatureUnits); break; case "speedUnit": String windSpeedUnits = sharedPreferences.getString(key, WeatherPresentation.DEFAULT_WIND_SPEED_UNITS); - if (windSpeedUnits != null) { - result = weatherPresentation.copyWindSpeedUnits(windSpeedUnits); - } + result = weatherPresentation.copyWindSpeedUnits(windSpeedUnits); break; case "windDirectionFormat": String windDirectionFormat = sharedPreferences.getString(key, WeatherPresentation.DEFAULT_WIND_DIRECTION_FORMAT); - if (windDirectionFormat != null) { - result = weatherPresentation.copyWindDirectionFormat(windDirectionFormat); - } + result = weatherPresentation.copyWindDirectionFormat(windDirectionFormat); break; case "pressureUnit": String pressureUnits = sharedPreferences.getString(key, WeatherPresentation.DEFAULT_PRESSURE_UNITS); - if (pressureUnits != null) { - result = weatherPresentation.copyPressureUnits(pressureUnits); - } + result = weatherPresentation.copyPressureUnits(pressureUnits); break; default: - if (key.equalsIgnoreCase(notificationTypeKey)) { + if (key.equalsIgnoreCase(typeKey)) { result = weatherPresentation.copy(readNotificationType(sharedPreferences)); - } else if (key.equalsIgnoreCase(showTemperatureInStatusBarKey)) { - boolean showTemperatureInStatusBar = sharedPreferences.getBoolean( - showTemperatureInStatusBarKey, - WeatherPresentation.DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR - ); - result = weatherPresentation.copyShowTemperatureInStatusBar(showTemperatureInStatusBar); } break; } diff --git a/app/src/main/java/cz/martykan/forecastie/notifications/ui/DefaultNotificationContentUpdater.java b/app/src/main/java/cz/martykan/forecastie/notifications/ui/DefaultNotificationContentUpdater.java index 6a8ecf90..99b6e7d5 100644 --- a/app/src/main/java/cz/martykan/forecastie/notifications/ui/DefaultNotificationContentUpdater.java +++ b/app/src/main/java/cz/martykan/forecastie/notifications/ui/DefaultNotificationContentUpdater.java @@ -39,8 +39,6 @@ public void updateNotification(@NonNull WeatherPresentation weatherPresentation, if (context == null) throw new NullPointerException("context is null"); - super.updateNotification(weatherPresentation, notification, context); - notification .setCustomContentView(null) .setContent(null) diff --git a/app/src/main/java/cz/martykan/forecastie/notifications/ui/NotificationContentUpdater.java b/app/src/main/java/cz/martykan/forecastie/notifications/ui/NotificationContentUpdater.java index 8bb67dd4..70a46706 100644 --- a/app/src/main/java/cz/martykan/forecastie/notifications/ui/NotificationContentUpdater.java +++ b/app/src/main/java/cz/martykan/forecastie/notifications/ui/NotificationContentUpdater.java @@ -1,19 +1,12 @@ package cz.martykan.forecastie.notifications.ui; import android.content.Context; -import android.graphics.Bitmap; -import android.os.Build; import android.widget.RemoteViews; -import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; -import androidx.core.content.ContextCompat; -import androidx.core.graphics.drawable.IconCompat; -import cz.martykan.forecastie.R; import cz.martykan.forecastie.models.WeatherPresentation; -import cz.martykan.forecastie.utils.formatters.WeatherFormatter; /** * Notification content updater populates notification with data from {@link WeatherPresentation}. @@ -24,8 +17,6 @@ * {@link #updateNotification(WeatherPresentation, NotificationCompat.Builder, Context)}. */ public abstract class NotificationContentUpdater { - public static final int DEFAULT_NOTIFICATION_ICON = R.drawable.cloud; - /** * Returns {@code true} if notification has custom layout and {@code false} otherwise. * @return {@code true} if notification has custom layout and {@code false} otherwise @@ -44,9 +35,7 @@ public boolean isLayoutCustom() { public void updateNotification(@NonNull WeatherPresentation weatherPresentation, @NonNull NotificationCompat.Builder notification, @NonNull Context context - ) throws NullPointerException { - setTemperatureAsIcon(weatherPresentation, notification, context); - } + ) throws NullPointerException {} /** * Create custom layout for notification. @@ -70,36 +59,9 @@ public RemoteViews prepareRemoteView(@NonNull Context context) throws NullPointe * @param context android context. * @throws NullPointerException if any of parameters are {@code null} */ - @CallSuper public void updateNotification(@NonNull WeatherPresentation weatherPresentation, @NonNull NotificationCompat.Builder notification, @NonNull RemoteViews notificationLayout, @NonNull Context context - ) throws NullPointerException { - setTemperatureAsIcon(weatherPresentation, notification, context); - } - - // TODO add tests - private void setTemperatureAsIcon( - @NonNull WeatherPresentation weatherPresentation, - @NonNull NotificationCompat.Builder notification, - @NonNull Context context - ) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - final IconCompat icon; - if (weatherPresentation.shouldShowTemperatureInStatusBar()) { - int color = ContextCompat.getColor(context, R.color.notification_icon_color); - Bitmap statusBarIcon = WeatherFormatter.getTemperatureAsBitmap(context, - weatherPresentation.getWeather(), - weatherPresentation.getTemperatureUnits(), - color); - icon = IconCompat.createWithBitmap(statusBarIcon); - } else { - icon = IconCompat.createWithResource(context, DEFAULT_NOTIFICATION_ICON); - } - notification.setSmallIcon(icon); - } else { - notification.setSmallIcon(DEFAULT_NOTIFICATION_ICON); - } - } + ) throws NullPointerException {} } \ No newline at end of file diff --git a/app/src/main/java/cz/martykan/forecastie/notifications/ui/SimpleNotificationContentUpdater.java b/app/src/main/java/cz/martykan/forecastie/notifications/ui/SimpleNotificationContentUpdater.java index efecd330..f845259f 100644 --- a/app/src/main/java/cz/martykan/forecastie/notifications/ui/SimpleNotificationContentUpdater.java +++ b/app/src/main/java/cz/martykan/forecastie/notifications/ui/SimpleNotificationContentUpdater.java @@ -49,8 +49,6 @@ public void updateNotification(@NonNull WeatherPresentation weatherPresentation, if (context == null) throw new NullPointerException("context is null"); - super.updateNotification(weatherPresentation, notification, notificationLayout, context); - notification // Too much information for decorated view. Only two strings fit. /*.setStyle(new NotificationCompat.DecoratedCustomViewStyle()) diff --git a/app/src/main/java/cz/martykan/forecastie/utils/formatters/WeatherFormatter.java b/app/src/main/java/cz/martykan/forecastie/utils/formatters/WeatherFormatter.java index a684a60f..7fdb77f2 100644 --- a/app/src/main/java/cz/martykan/forecastie/utils/formatters/WeatherFormatter.java +++ b/app/src/main/java/cz/martykan/forecastie/utils/formatters/WeatherFormatter.java @@ -4,11 +4,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; -import android.graphics.Rect; import android.graphics.Typeface; -import android.os.Build; -import android.util.DisplayMetrics; -import android.util.TypedValue; import androidx.annotation.NonNull; @@ -22,9 +18,6 @@ */ @SuppressWarnings("unused") public abstract class WeatherFormatter { - public static final int DEFAULT_ICON_TEXT_SIZE = 24; - public static final int MIN_ICON_TEXT_SIZE = 14; - /** * Check is {@code weather} has enough valid data to show all necessary weather information to * a user or {@code no data} should be shown. @@ -326,87 +319,16 @@ public static Bitmap getWeatherIconAsBitmap(@NonNull Context context, @NonNull S int color) { Bitmap myBitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_4444); Canvas myCanvas = new Canvas(myBitmap); - Paint paint = getPaint(color); - Typeface clock = Typeface.createFromAsset(context.getAssets(), "fonts/weather.ttf"); - paint.setTypeface(clock); - paint.setTextSize(150); - myCanvas.drawText(text, 128, 180, paint); - return myBitmap; - } - - /** - * Returns weather icon as {@link Bitmap}. - * @param context android context - * @param weather weather information - * @param temperatureUnit temperature unit - * @param color text color (not a color resource) - * @return weather icon as {@link Bitmap} - */ - // TODO static is temporary solution to avoid code duplication. Should be moved in another - // class and retrieved through DI. - @NonNull - public static Bitmap getTemperatureAsBitmap( - @NonNull Context context, - @NonNull ImmutableWeather weather, - @NonNull String temperatureUnit, - int color - ) { - DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); - final float size = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_ICON_TEXT_SIZE, displayMetrics); - final float oneDp = size / DEFAULT_ICON_TEXT_SIZE; - final float minTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, MIN_ICON_TEXT_SIZE - 1, displayMetrics); - final Bitmap bitmap = Bitmap.createBitmap((int) size, (int) size, Bitmap.Config.ARGB_4444); - final int temperature = Math.round(weather.getTemperature(temperatureUnit)); - drawTemperature(bitmap, getTemperaturePaint(color), temperature, size, oneDp, minTextSize); - return bitmap; - } - - private static void drawTemperature( - @NonNull Bitmap bitmap, - @NonNull Paint paint, - final int temperature, - final float size, final float oneDp, final float minTextSize - ) { - final Canvas canvas = new Canvas(bitmap); - float textSize = size; - final String text = temperature + "°"; - - Rect bounds = new Rect(); - float measuredWidth; - do { - paint.setTextSize(textSize); - paint.getTextBounds(text, 0, text.length(), bounds); - measuredWidth = bounds.width(); - textSize -= oneDp; - } while (measuredWidth > size && textSize > minTextSize); - - final float textHeight = (float) bounds.height(); - final float verticalPadding = (size - textHeight) / 2f; - - final float x = size / 2f; - final float y = verticalPadding + textHeight; - canvas.drawText(text, x, y, paint); - } - - @NonNull - private static Paint getTemperaturePaint(int color) { - final Paint paint = getPaint(color); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - paint.setLetterSpacing(-0.05f); - } - //paint.setTextAlign(Paint.Align.LEFT); - paint.setTypeface(Typeface.DEFAULT_BOLD); - return paint; - } - - @NonNull - private static Paint getPaint(int color) { Paint paint = new Paint(); + Typeface clock = Typeface.createFromAsset(context.getAssets(), "fonts/weather.ttf"); paint.setAntiAlias(true); paint.setSubpixelText(true); - paint.setStyle(Paint.Style.FILL_AND_STROKE); + paint.setTypeface(clock); + paint.setStyle(Paint.Style.FILL); paint.setColor(color); + paint.setTextSize(150); paint.setTextAlign(Paint.Align.CENTER); - return paint; + myCanvas.drawText(text, 128, 180, paint); + return myBitmap; } -} \ No newline at end of file +} diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 743d9d72..c6998b84 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -20,8 +20,8 @@ 풍량 풍속 - 기압 - 습도 + 압력 + 습기 일출 일몰 자외선 지수 @@ -31,21 +31,21 @@ 길이 단위 풍속 단위 온도 단위 - 온도의 소수점 표시안함 + 온도 단위를 정수로 표현 기압 단위 위치 설정 날짜들을 색으로 구별 - m/s - km/h - mile/h + 초당 미터 + 시간당 킬로미터 + 시간당 마일 보 퍼트 바람 규모 매듭 - - °F - K + 섭씨 + 화씨 + 켈빈 - mm + 밀리미터 인치 날짜 형식 @@ -66,30 +66,30 @@ API 키 날씨지도 쿼리를 위한 사용자 API 키 - hpa - kpa - mmhg - inhg + 헥토파스칼 + 킬로파스칼 + 수은주 밀리미터 + 수은주 인치 - m/s - km/h - mi/h - 노트 + 초당 미터 + 시간당 킬로미터 + 시간당 마일 + 매듭 표시 없음 화살표 축약표시 - hpa - kpa - mmHg + 헥토파스칼 + 킬로파스칼 + 수은주 밀리미터 - 블루 화이트 - 클래식 화이트 - 블루 그레이 - 클래식 그레이 - 블루 다크 - 클래식 다크 + 밝은 + 클래식한 + 밝은 어두운 + 클래식하게 어두운 + 밝은 검정 + 클래식한 검정 확인 취소 @@ -145,7 +145,7 @@ 화면 데이터 - 소수값 표시 + 십진수 0을 표시 위치 백그라운드에서 위치 업데이트 @@ -163,13 +163,4 @@ Creative Commons CC-BY-SA라이센스에 따라 OpenWeatherMap 에서 제공한 데이터입니다. 아이콘은 SIL OFL 1.1 라이센스에 따라 Lukas BischoffErik Flowers의 날씨 아이콘입니다. 구름량 - - - 알림 - 알림에 날씨를 표시 - 알림 형식 - 기본 안드로이드 형식 - 간단한 알림 - 상태바에 기온을 표시 - 기능을 사용할려면 해당 단말기의 안드로이드 버전이 Android 6.0 (Marshmallow)을 만족해야합니다. diff --git a/app/src/main/res/values-ro/strings_main_graphs_map_about.xml b/app/src/main/res/values-ro/strings_main_graphs_map_about.xml deleted file mode 100644 index 427d01a8..00000000 --- a/app/src/main/res/values-ro/strings_main_graphs_map_about.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - Forecastie - - Căutare - Actualizare - Setări - Despre - Căutare oraș - Descărcarea datelor dvs. ... - Obținerea locației dvs. ... - Încărcare... - - - Astăzi - Mâine - Mai târziu - - - Vânt - Viteza vântului - Presiune - Umiditate - Răsărit - Apus - Indice UV - Atingeți ușor pentru grafice - - - Grafice - Mai multe zile - - - Hartă meteo - Ploaie - Temperatură - Nori - - - Nu s-a putut obține numele versiunii - O aplicație meteo ușoară, de tip Free Software, lansată sub licența GPL3. - Dezvoltată de Tomáš Martykán şi alte persoane, cu asistență de la mulţi alţii. - Codul este disponibil pe Github. - Bug-urile și îmbunătățirile pot fi postate pe pagina Github cu probleme. - Date furnizate de OpenWeatherMap, în conformitate cu licența Creative Commons CC-BY-SA 2.0. - Pictogramele sunt Pictograme meteo, de către Lukas Bischoff şi Erik Flowers, în conformitate cu licența SIL OFL 1.1. - diff --git a/app/src/main/res/values-ro/strings_notification.xml b/app/src/main/res/values-ro/strings_notification.xml deleted file mode 100644 index 6de4d5cd..00000000 --- a/app/src/main/res/values-ro/strings_notification.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - Serviciu pentru afișarea notificării meteo Forecastie. - Notificare meteo - Fără date - - Notificare - Afișați vremea în notificare - Tipul notificării - Vizualizare implicită Android - Notificare simplă - Afișarea temperaturii în bara de stare - Dacă această opțiune este activată, temperatura curentă este afișată în bara de stare în loc de pictograma aplicației. Această opțiune este disponibilă începând cu Android 6.0 (Marshmallow). - diff --git a/app/src/main/res/values-ro/strings_other.xml b/app/src/main/res/values-ro/strings_other.xml deleted file mode 100644 index 9f9a673d..00000000 --- a/app/src/main/res/values-ro/strings_other.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - Eroare la parsarea JSON. - Eroare în timpul solicitării sau primirii datelor. - Conexiunea nu este disponibilă. - Orașul specificat nu a fost găsit. - Prea multe cereri. Vă rugăm să încercați din nou. - Cheie API invalidă. - - - Locație - Actualizarea locației în fundal - Setări privind locația - Locația nu este activată. Doriți să accesați meniul de setări? - Setări - Locaţii - - - Forecastie Extensiv - Forecastie Timp - Forecastie Simplu - Forecastie Clasic - diff --git a/app/src/main/res/values-ro/strings_settings_other.xml b/app/src/main/res/values-ro/strings_settings_other.xml deleted file mode 100644 index b222842f..00000000 --- a/app/src/main/res/values-ro/strings_settings_other.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Afișaj - Temă - Faceți widget-ul transparent - Formatul direcției vântului - Proaspăt - Clasic - Proaspăt Întunecat - Clasic Întunecat - Proaspăt Negru - Clasic Negru - - Nicio indicație - Săgeți - Abrevieri - Afișați zerouri zecimale - - - Ultima actualizare:\n%s - \nUltima actualizare: %s - Date - Intervalul de reîmprospătare a datelor în fundal - Nici unul - 15 min - 30 min - 1 h - 2 h - 6 h - 12 h - 24 h - Cheie API - Cheie API personalizată pentru interogări OpenWeatherMap - - - EROARE DE FORMAT DE DATĂ - Format de dată - Format de dată personalizat - Furnizați șirul personalizat SimpleDateFormat care urmează să fie utilizat - OK - Anulare - diff --git a/app/src/main/res/values-ro/strings_settings_units.xml b/app/src/main/res/values-ro/strings_settings_units.xml deleted file mode 100644 index b0972ce9..00000000 --- a/app/src/main/res/values-ro/strings_settings_units.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - Unități - Unități de lungime - Unități de viteză - Unități de temperatură - Afișează temperatura doar ca număr întreg - Unități de presiune - Detectarea locației - Diferențiați zilele cu ajutorul culorilor - - Metri pe secondă (m/s) - Kilometri pe oră (km/h) - Mile pe oră (mi/h) - Scara de vânt Beaufort (bf) - Noduri (kt) - Celsius - Fahrenheit - Kelvin - - Millimetri (mm) - Ţol (in) - - hPa/mBar - kPa - mm Hg - în Hg - - m/s - km/h - mi/h - kt - - hPa/mBar - kPa - mm Hg - în Hg - - Nicio informație - Scăzut - Moderat - Ridicat - Foarte Ridicat - Extrem - diff --git a/app/src/main/res/values-ro/strings_wind.xml b/app/src/main/res/values-ro/strings_wind.xml deleted file mode 100644 index 485c8430..00000000 --- a/app/src/main/res/values-ro/strings_wind.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - N - NNE - NE - ENE - E - ESE - SE - SSE - S - SSW - SW - WSW - W - WNW - NW - NNW - - - Calm (0) - Adiere ușoară (1) - Briză ușoară (2) - Vânt slab (3) - Vânt moderat (4) - Vânt tare (5) - Vânt foarte tare (6) - Vânt puternic (7) - Vânt foarte puternic (8) - Furtună (9) - Furtună puternică (10) - Furtună violentă (11) - Uragan (12) - diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index b5451589..be7d6559 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -121,8 +121,6 @@ Вид уведомления Стандартное уведомление Android Простое уведомление - Показывать температуру в статусной строке - Если эта функция включена, то вместо значка в статусной строке будет отображаться текущее значение температуры. Функция доступна с Android 6.0 (Marshmallow). Ошибка разбора JSON. @@ -190,7 +188,7 @@ Код доступен на GitHub. Ошибки и советы можно разместить в нашей системе отслеживания ошибок на GitHub. Данные предоставляются сайтом OpenWeatherMap под лицензией Creative Commons CC-BY-SA 2.0. - Значки Weather Icons, созданные Lukas Bischoff и Erik Flowers, под лицензией SIL OFL 1.1. + Иконки Weather Icons, созданные Lukas Bischoff и Erik Flowers, под лицензией SIL OFL 1.1. Forecastie расширенный diff --git a/app/src/main/res/values/strings_not_translated.xml b/app/src/main/res/values/strings_not_translated.xml index 19447e58..fa5b5d2d 100644 --- a/app/src/main/res/values/strings_not_translated.xml +++ b/app/src/main/res/values/strings_not_translated.xml @@ -36,7 +36,6 @@ showNotification - showTemperatureInStatusBar notificationType default simple diff --git a/app/src/main/res/values/strings_notification.xml b/app/src/main/res/values/strings_notification.xml index 61f447b3..3f8ae0d6 100644 --- a/app/src/main/res/values/strings_notification.xml +++ b/app/src/main/res/values/strings_notification.xml @@ -9,6 +9,4 @@ Notification type Default Android view Simple notification - Show temperature in status bar - If this is enabled, current temperature is shown in the status bar instead of app icon. This option available from Android 6.0 (Marshmallow). - + \ No newline at end of file diff --git a/app/src/main/res/xml/prefs.xml b/app/src/main/res/xml/prefs.xml index eb00d437..ae83f052 100644 --- a/app/src/main/res/xml/prefs.xml +++ b/app/src/main/res/xml/prefs.xml @@ -117,12 +117,5 @@ android:entries="@array/settings_notification_type_value_titles" android:defaultValue="@string/settings_notification_type_default_value" android:dependency="@string/settings_enable_notification_key" /> - - diff --git a/app/src/test/java/cz/martykan/forecastie/notifications/repository/WeatherRepositoryTests.java b/app/src/test/java/cz/martykan/forecastie/notifications/repository/WeatherRepositoryTests.java index 03fa36e6..6247ff83 100644 --- a/app/src/test/java/cz/martykan/forecastie/notifications/repository/WeatherRepositoryTests.java +++ b/app/src/test/java/cz/martykan/forecastie/notifications/repository/WeatherRepositoryTests.java @@ -69,8 +69,6 @@ public void onChange(@NonNull WeatherPresentation newData) { actual[0].getWindDirectionFormat()); Assert.assertEquals("pressure unit isn't default", WeatherPresentation.DEFAULT_PRESSURE_UNITS, actual[0].getPressureUnits()); - Assert.assertEquals("show temperature in status bar isn't default", - WeatherPresentation.DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR, actual[0].shouldShowTemperatureInStatusBar()); } @Test @@ -80,10 +78,7 @@ public void observeWeatherEmitsWeatherPresentationWithCurrentValuesFromSharedPre String windSpeedUnit = "kn"; String windDirectionFormat = "none"; String pressureUnit = "in Hg"; - putValuesIntoPrefs( - type, temperatureUnit, windSpeedUnit, windDirectionFormat, pressureUnit, - !WeatherPresentation.DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR - ); + putValuesIntoPrefs(type, temperatureUnit, windSpeedUnit, windDirectionFormat, pressureUnit); final WeatherPresentation[] actual = new WeatherPresentation[1]; WeatherRepository repository = new WeatherRepository(context, executor); @@ -110,12 +105,10 @@ public void onChange(@NonNull WeatherPresentation newData) { windDirectionFormat, actual[0].getWindDirectionFormat()); Assert.assertEquals("pressure unit is default", pressureUnit, actual[0].getPressureUnits()); - Assert.assertEquals("show temperature in status bar is default", - !WeatherPresentation.DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR, actual[0].shouldShowTemperatureInStatusBar()); } @Test - public void observeWeatherEmitsNewValuesWhenTheyAreUpdatedInSharedPreference() { + public void observeWeatherEmitsNewValuesWhenTheyAreUpdatedInSharedPreference() throws InterruptedException { String type = context.getString(R.string.settings_notification_type_key_default); String temperatureUnit = "°F"; String windSpeedUnit = "kn"; @@ -185,25 +178,10 @@ public void onChange(@NonNull WeatherPresentation newData) { Assert.assertEquals("pressure unit is default", pressureUnit, actual[0].getPressureUnits()); - - prefs.edit() - .putBoolean( - context.getString(R.string.settings_show_temperature_in_status_bar_key), - !WeatherPresentation.DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR - ) - .commit(); - executor.runAll(); - Shadows.shadowOf(Looper.getMainLooper()).idle(); - - Assert.assertEquals( - "show temperature in status bar is default", - !WeatherPresentation.DEFAULT_SHOW_TEMPERATURE_IN_STATUS_BAR, - actual[0].shouldShowTemperatureInStatusBar() - ); } @Test - public void observeWeatherEmitsNewValuesInEveryListener() { + public void observeWeatherEmitsNewValuesInEveryListener() throws InterruptedException { final WeatherPresentation[] actual = new WeatherPresentation[2]; WeatherRepository repository = new WeatherRepository(context, executor); repository.observeWeather(new WeatherRepository.RepositoryListener() { @@ -260,15 +238,10 @@ public void getWeatherReturnsCurrentValues() { // TODO add tests for clear method - @SuppressWarnings("SameParameterValue") - private void putValuesIntoPrefs( - @NonNull String type, - @NonNull String temperatureUnit, - @NonNull String windSpeedUnit, - @NonNull String windDirectionFormat, - @NonNull String pressureUnit, - boolean showTemperatureInStatusBar - ) { + private void putValuesIntoPrefs(@NonNull String type, @NonNull String temperatureUnit, + @NonNull String windSpeedUnit, + @NonNull String windDirectionFormat, + @NonNull String pressureUnit) { prefs.edit() .putString("lastToday", "{\"main\": {\"temp\": 315.25}}") .putLong("lastUpdate", 100L) @@ -278,7 +251,6 @@ private void putValuesIntoPrefs( .putString("speedUnit", windSpeedUnit) .putString("windDirectionFormat", windDirectionFormat) .putString("pressureUnit", pressureUnit) - .putBoolean(context.getString(R.string.settings_show_temperature_in_status_bar_key), showTemperatureInStatusBar) .commit(); } -} +} \ No newline at end of file diff --git a/app/src/test/java/cz/martykan/forecastie/notifications/ui/SimpleNotificationContentUpdaterTests.java b/app/src/test/java/cz/martykan/forecastie/notifications/ui/SimpleNotificationContentUpdaterTests.java index 126c7c96..895b2619 100644 --- a/app/src/test/java/cz/martykan/forecastie/notifications/ui/SimpleNotificationContentUpdaterTests.java +++ b/app/src/test/java/cz/martykan/forecastie/notifications/ui/SimpleNotificationContentUpdaterTests.java @@ -252,7 +252,7 @@ public void run() { assertThrows(NullPointerException.class, new ThrowingRunnable() { @Override public void run() { - contentUpdater.updateNotification(weatherPresentation, (NotificationCompat.Builder) null, layoutSpy, context); + contentUpdater.updateNotification(weatherPresentation, null, layoutSpy, context); } });