├── .gitignore
├── .travis.yml
├── CHANGELOG
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── org
│ │ └── asdtm
│ │ └── goodweather
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── fonts
│ │ │ ├── Roboto-Light.ttf
│ │ │ ├── Roboto-Thin.ttf
│ │ │ └── weathericons-regular-webfont.ttf
│ │ └── licenses
│ │ │ ├── Gson
│ │ │ ├── JeepTrail
│ │ │ ├── MPAndroidChart
│ │ │ ├── OpenWeatherMap
│ │ │ ├── Roboto
│ │ │ └── WeatherIcons
│ ├── java
│ │ └── org
│ │ │ └── asdtm
│ │ │ └── goodweather
│ │ │ ├── AppCompatPreferenceActivity.java
│ │ │ ├── BaseActivity.java
│ │ │ ├── BitcoinDonationDialog.java
│ │ │ ├── ConnectionDetector.java
│ │ │ ├── GoodWeatherApp.java
│ │ │ ├── GraphsActivity.java
│ │ │ ├── LicenseActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── SearchActivity.java
│ │ │ ├── SettingsActivity.java
│ │ │ ├── WeatherForecastActivity.java
│ │ │ ├── WeatherJSONParser.java
│ │ │ ├── WeatherRequest.java
│ │ │ ├── adapter
│ │ │ ├── WeatherForecastAdapter.java
│ │ │ └── WeatherForecastViewHolder.java
│ │ │ ├── fragment
│ │ │ └── ForecastBottomSheetDialogFragment.java
│ │ │ ├── model
│ │ │ ├── CitySearch.java
│ │ │ ├── Weather.java
│ │ │ └── WeatherForecast.java
│ │ │ ├── receiver
│ │ │ └── StartupReceiver.java
│ │ │ ├── service
│ │ │ ├── CurrentWeatherService.java
│ │ │ ├── LocationUpdateService.java
│ │ │ └── NotificationService.java
│ │ │ ├── utils
│ │ │ ├── ApiKeys.java
│ │ │ ├── AppPreference.java
│ │ │ ├── AppWidgetProviderAlarm.java
│ │ │ ├── CityParser.java
│ │ │ ├── Constants.java
│ │ │ ├── CustomValueFormatter.java
│ │ │ ├── LanguageUtil.java
│ │ │ ├── PermissionUtil.java
│ │ │ ├── PreferenceUtil.java
│ │ │ ├── Utils.java
│ │ │ ├── XAxisValueFormatter.java
│ │ │ └── YAxisValueFormatter.java
│ │ │ └── widget
│ │ │ ├── LessWidgetProvider.java
│ │ │ ├── LessWidgetService.java
│ │ │ ├── MoreWidgetProvider.java
│ │ │ └── MoreWidgetService.java
│ └── res
│ │ ├── drawable-hdpi
│ │ ├── background_nav_header.png
│ │ ├── ic_barometer_light_32dp.png
│ │ ├── ic_current_weather_black_24dp.png
│ │ ├── ic_daily_forecast_dark_24dp.png
│ │ ├── ic_feedback.png
│ │ ├── ic_graphs_black_32dp.png
│ │ ├── ic_humidity_light_32dp.png
│ │ ├── ic_menu_settings.png
│ │ ├── ic_my_location_white_24dp.png
│ │ ├── ic_rain_light_32dp.png
│ │ ├── ic_refresh_white_18dp.png
│ │ ├── ic_refresh_white_24dp.png
│ │ ├── ic_search_white_24dp.png
│ │ ├── ic_snow_light_32dp.png
│ │ ├── ic_thumb_up_black_24dp.png
│ │ ├── ic_wind_light_32dp.png
│ │ └── small_icon.png
│ │ ├── drawable-mdpi
│ │ ├── background_nav_header.png
│ │ ├── ic_barometer_light_32dp.png
│ │ ├── ic_current_weather_black_24dp.png
│ │ ├── ic_daily_forecast_dark_24dp.png
│ │ ├── ic_feedback.png
│ │ ├── ic_graphs_black_32dp.png
│ │ ├── ic_humidity_light_32dp.png
│ │ ├── ic_menu_settings.png
│ │ ├── ic_my_location_white_24dp.png
│ │ ├── ic_rain_light_32dp.png
│ │ ├── ic_refresh_white_18dp.png
│ │ ├── ic_refresh_white_24dp.png
│ │ ├── ic_search_white_24dp.png
│ │ ├── ic_snow_light_32dp.png
│ │ ├── ic_thumb_up_black_24dp.png
│ │ ├── ic_wind_light_32dp.png
│ │ └── small_icon.png
│ │ ├── drawable-nodpi
│ │ ├── background_appbar.png
│ │ ├── preview_less_widget.png
│ │ └── preview_more_widget.png
│ │ ├── drawable-xhdpi
│ │ ├── background_nav_header.png
│ │ ├── bitcoin_address_qr.png
│ │ ├── ic_barometer_light_32dp.png
│ │ ├── ic_current_weather_black_24dp.png
│ │ ├── ic_daily_forecast_dark_24dp.png
│ │ ├── ic_feedback.png
│ │ ├── ic_graphs_black_32dp.png
│ │ ├── ic_humidity_light_32dp.png
│ │ ├── ic_menu_settings.png
│ │ ├── ic_my_location_white_24dp.png
│ │ ├── ic_rain_light_32dp.png
│ │ ├── ic_refresh_white_18dp.png
│ │ ├── ic_refresh_white_24dp.png
│ │ ├── ic_search_white_24dp.png
│ │ ├── ic_snow_light_32dp.png
│ │ ├── ic_thumb_up_black_24dp.png
│ │ ├── ic_wind_light_32dp.png
│ │ └── small_icon.png
│ │ ├── drawable-xxhdpi
│ │ ├── background_nav_header.png
│ │ ├── ic_barometer_light_32dp.png
│ │ ├── ic_current_weather_black_24dp.png
│ │ ├── ic_daily_forecast_dark_24dp.png
│ │ ├── ic_feedback.png
│ │ ├── ic_graphs_black_32dp.png
│ │ ├── ic_humidity_light_32dp.png
│ │ ├── ic_menu_settings.png
│ │ ├── ic_my_location_white_24dp.png
│ │ ├── ic_rain_light_32dp.png
│ │ ├── ic_refresh_white_18dp.png
│ │ ├── ic_refresh_white_24dp.png
│ │ ├── ic_search_white_24dp.png
│ │ ├── ic_snow_light_32dp.png
│ │ ├── ic_thumb_up_black_24dp.png
│ │ ├── ic_wind_light_32dp.png
│ │ └── small_icon.png
│ │ ├── drawable-xxxhdpi
│ │ ├── background_nav_header.png
│ │ ├── ic_current_weather_black_24dp.png
│ │ ├── ic_daily_forecast_dark_24dp.png
│ │ ├── ic_feedback.png
│ │ ├── ic_menu_settings.png
│ │ ├── ic_my_location_white_24dp.png
│ │ ├── ic_rain_light_32dp.png
│ │ ├── ic_refresh_white_18dp.png
│ │ ├── ic_refresh_white_24dp.png
│ │ ├── ic_search_white_24dp.png
│ │ ├── ic_snow_light_32dp.png
│ │ ├── ic_thumb_up_black_24dp.png
│ │ └── small_icon.png
│ │ ├── drawable
│ │ ├── ic_android_black_24dp.xml
│ │ └── ic_share.xml
│ │ ├── layout
│ │ ├── activity_graphs.xml
│ │ ├── activity_license.xml
│ │ ├── activity_main.xml
│ │ ├── activity_search.xml
│ │ ├── activity_settings.xml
│ │ ├── activity_weather_forecast.xml
│ │ ├── city_item.xml
│ │ ├── dialog_donation_bitcoin.xml
│ │ ├── forecast_item.xml
│ │ ├── fragment_forecast_bottom_sheet.xml
│ │ ├── main_content.xml
│ │ ├── nav_header.xml
│ │ ├── widget_less_3x1.xml
│ │ └── widget_more_3x3.xml
│ │ ├── menu
│ │ ├── activity_main_menu.xml
│ │ ├── draw_menu.xml
│ │ ├── menu_graphs.xml
│ │ ├── search.xml
│ │ └── weather_forecast_menu.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-ar
│ │ └── strings.xml
│ │ ├── values-be-rBY
│ │ └── strings.xml
│ │ ├── values-be
│ │ └── strings.xml
│ │ ├── values-ca
│ │ └── strings.xml
│ │ ├── values-cs
│ │ └── strings.xml
│ │ ├── values-cy
│ │ └── strings.xml
│ │ ├── values-de
│ │ └── strings.xml
│ │ ├── values-el
│ │ └── strings.xml
│ │ ├── values-es
│ │ └── strings.xml
│ │ ├── values-et
│ │ └── strings.xml
│ │ ├── values-eu
│ │ └── strings.xml
│ │ ├── values-fi
│ │ └── strings.xml
│ │ ├── values-fr
│ │ └── strings.xml
│ │ ├── values-hi
│ │ └── strings.xml
│ │ ├── values-hr
│ │ └── strings.xml
│ │ ├── values-hu
│ │ └── strings.xml
│ │ ├── values-id
│ │ └── strings.xml
│ │ ├── values-it
│ │ └── strings.xml
│ │ ├── values-ja
│ │ └── strings.xml
│ │ ├── values-kab
│ │ └── strings.xml
│ │ ├── values-nb-rNO
│ │ └── strings.xml
│ │ ├── values-nl
│ │ └── strings.xml
│ │ ├── values-ny
│ │ └── strings.xml
│ │ ├── values-pa
│ │ └── strings.xml
│ │ ├── values-pl
│ │ └── strings.xml
│ │ ├── values-ps
│ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ └── strings.xml
│ │ ├── values-pt
│ │ └── strings.xml
│ │ ├── values-ro
│ │ └── strings.xml
│ │ ├── values-ru
│ │ └── strings.xml
│ │ ├── values-si
│ │ └── strings.xml
│ │ ├── values-sk
│ │ └── strings.xml
│ │ ├── values-sl
│ │ └── strings.xml
│ │ ├── values-sw
│ │ └── strings.xml
│ │ ├── values-ta
│ │ └── strings.xml
│ │ ├── values-tr
│ │ └── strings.xml
│ │ ├── values-uk
│ │ └── strings.xml
│ │ ├── values-v21
│ │ └── styles.xml
│ │ ├── values-vi
│ │ └── strings.xml
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ ├── values-zh-rCN
│ │ └── strings.xml
│ │ ├── values-zh-rTW
│ │ └── strings.xml
│ │ ├── values
│ │ ├── arrays.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── licenses.xml
│ │ ├── nontranslatable.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ ├── pref_about.xml
│ │ ├── pref_general.xml
│ │ ├── pref_headers.xml
│ │ ├── pref_widget.xml
│ │ ├── searchable.xml
│ │ ├── widget_provider_less.xml
│ │ └── widget_provider_more.xml
│ └── test
│ └── java
│ └── org
│ └── asdtm
│ └── goodweather
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle/
3 | .DS_Store
4 | build/
5 | captures/
6 | out/
7 | .idea/
8 | *.apk
9 | release.properties
10 | gradle.properties
11 | local.properties
12 | /.nb-gradle/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | jdk: oraclejdk8
3 | os: linux
4 | sudo: required
5 |
6 | android:
7 | components:
8 | - tools
9 | - tools
10 | - platfom-tools
11 | - build-tools-25.0.2
12 | - android-25
13 | - extra-android-m2repository
14 | licenses:
15 | - 'android-sdk-preview-license-.+'
16 | - 'android-sdk-license-.+'
17 |
18 | # Accept ConstraintLayout license
19 | before_install:
20 | - mkdir "$ANDROID_HOME/licenses" || true
21 | - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"
22 | - echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
23 | - chmod +x gradlew
24 | - ./gradlew dependencies || true
25 |
26 | script: ./gradlew build --stacktrace
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | v4.4
2 |
3 | - Added option to change app theme
4 | - Added dark theme
5 |
6 | v4.3
7 |
8 | - Added option to change language
9 | - Added transparent widget theme
10 | - Added option to change widget theme
11 | - Added translations: Czech, French
12 | - Updated translations
13 |
14 | v4.2.1
15 |
16 | - Fix bug when updated forecast
17 |
18 | v4.2
19 |
20 | - Fixed small bugs
21 |
22 | v4.1
23 |
24 | - Support runtime permissions for Android 6.0
25 | - Added translations: Basque, Belarusian, Japanese, Spanish
26 | - Minor bugfixes
27 |
28 | v4.0
29 |
30 | - Improved main screen
31 | - Added forecast
32 | - Added graphs
33 | - Fixed small bugs
34 |
35 | v3.0
36 |
37 | - Added widgets
38 | - Produced by the redesign of the main screen
39 | - Fix bug: in some cases the app crashed when it updates the weather
40 | - Fix bug: the app is not closed by pressing the back button
41 |
42 | v2.1
43 |
44 | - Support for Android 3.0 (Honeycomb) has ended
45 |
46 | v2.0
47 |
48 | - Add notifications
49 | - Update Settings screen
50 | - Update translations
51 |
52 | v1.3
53 |
54 | - Change the settings screen
55 | - Added search location screen
56 | - Update translations
57 |
58 | v1.2
59 |
60 | - Add Polish and German translations
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/qqq3/good-weather)
2 | [](https://github.com/qqq3/good-weather/releases)
3 | [](https://raw.githubusercontent.com/qqq3/good-weather/HEAD/LICENSE)
4 |
5 | # Good Weather
6 | Open source weather app for Android.
7 |
8 | [
](https://f-droid.org/repository/browse/?fdid=org.asdtm.goodweather)
9 | [
](https://play.google.com/store/apps/details?id=org.asdtm.goodweather)
10 |
11 | ## Features
12 | * Different languages: Basque, Belarusian, Czech, English, French, German, Japanese, Spanish, Polish, Russian
13 | * Current weather
14 | * 7 day forecast
15 | * Many locations
16 | * Notifications
17 | * Support different measuring units
18 | * Ad-free
19 |
20 | ## Screenshots
21 | [
](http://i.imgur.com/FntbN8S.png)
22 | [
](http://i.imgur.com/WVFXEoo.png)
23 | [
](http://i.imgur.com/pDjCCqo.png)
24 | [
](http://i.imgur.com/lQKKBYY.png)
25 |
26 | ## To-Do
27 | - [ ] Add weather map
28 | - [ ] Improve accessibility for people with disabilities
29 |
30 | # Translations
31 | [https://hosted.weblate.org/projects/good-weather/strings/](https://hosted.weblate.org/projects/good-weather/strings/)
32 |
33 | The strings are translated using [Weblate](https://weblate.org/en/). Follow
34 | [these instructions](https://hosted.weblate.org/engage/good-weather/) if you would like to contribute
35 | [here](https://hosted.weblate.org/projects/good-weather/strings/).
36 |
37 | ## Donations
38 | If you would like to help, you can donate Bitcoin on ```1FV8m1MKqZ9ZKB8YNwpsjsuubHTznJSiT8``` address.
39 | Thanks!
40 |
41 | ## List of contributors
42 | [berian](https://github.com/beriain), [mahula](https://github.com/mahula), [naofum](https://github.com/naofum),
43 | [thuryn](https://github.com/thuryn), [monolifed](https://github.com/monolifed), [marcoM32](https://github.com/marcoM32),
44 | [Zagur](https://github.com/Zagur)
45 |
46 | ## License
47 | ```
48 | Good Weather. App displays weather information.
49 | Copyright (C) 2015-2017 Eugene Kislyakov
50 |
51 | This program is free software: you can redistribute it and/or modify
52 | it under the terms of the GNU General Public License as published by
53 | the Free Software Foundation, either version 3 of the License, or
54 | (at your option) any later version.
55 |
56 | This program is distributed in the hope that it will be useful,
57 | but WITHOUT ANY WARRANTY; without even the implied warranty of
58 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59 | GNU General Public License for more details.
60 |
61 | You should have received a copy of the GNU General Public License
62 | along with this program. If not, see .
63 | ```
64 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion '25.0.2'
6 | defaultConfig {
7 | applicationId "org.asdtm.goodweather"
8 | minSdkVersion 14
9 | targetSdkVersion 25
10 | versionCode 13
11 | versionName "4.4"
12 | vectorDrawables.useSupportLibrary = true
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled true
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | applicationVariants.all { variant ->
19 | variant.outputs.each { output ->
20 | output.outputFile = new File(
21 | output.outputFile.parent,
22 | output.outputFile.name.replace("app-release.apk", "GoodWeather-release-${variant.versionName}.apk"))
23 | }
24 | }
25 | }
26 | debug {
27 | minifyEnabled false
28 | applicationVariants.all { variant ->
29 | variant.outputs.each { output ->
30 | output.outputFile = new File(
31 | output.outputFile.parent,
32 | output.outputFile.name.replace("app-debug.apk", "GoodWeather-debug-${variant.versionName}.apk"))
33 | }
34 | }
35 | }
36 | }
37 | lintOptions {
38 | disable 'GoogleAppIndexingWarning'
39 | abortOnError false
40 | }
41 | }
42 |
43 | dependencies {
44 | compile fileTree(include: ['*.jar'], dir: 'libs')
45 | compile 'com.android.support:appcompat-v7:25.3.1'
46 | compile 'com.android.support:design:25.3.1'
47 | compile 'com.android.support:cardview-v7:25.3.1'
48 | compile 'com.android.support:support-v4:25.3.1'
49 | testCompile 'junit:junit:4.12'
50 | compile 'com.google.code.gson:gson:2.6.2'
51 | compile 'com.github.PhilJay:MPAndroidChart:v3.0.0-beta1'
52 | compile 'com.android.support.constraint:constraint-layout:1.0.2'
53 | }
54 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/qqq3/Android/Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | -keep class org.asdtm.goodweather.model.WeatherForecast { *; }
--------------------------------------------------------------------------------
/app/src/androidTest/java/org/asdtm/goodweather/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase
10 | {
11 | public ApplicationTest()
12 | {
13 | super(Application.class);
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
36 |
39 |
40 |
45 |
46 |
47 |
48 |
49 |
52 |
55 |
56 |
60 |
63 |
64 |
68 |
71 |
72 |
76 |
77 |
78 |
79 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/assets/fonts/Roboto-Light.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/assets/fonts/Roboto-Thin.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/weathericons-regular-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/assets/fonts/weathericons-regular-webfont.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/licenses/Gson:
--------------------------------------------------------------------------------
1 | Copyright 2008 Google Inc.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/app/src/main/assets/licenses/JeepTrail:
--------------------------------------------------------------------------------
1 | JEEP TRAIL IN LAKE CITY, by DEBRA DANIEL
2 |
3 | Under Creative Commons Attribution-ShareAlike 2.0 Generic (CC BY-SA 2.0) license: https://creativecommons.org/licenses/by-sa/2.0/legalcode
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/assets/licenses/MPAndroidChart:
--------------------------------------------------------------------------------
1 | Copyright 2016 Philipp Jahoda
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/app/src/main/assets/licenses/WeatherIcons:
--------------------------------------------------------------------------------
1 | Copyright (c) , (),
2 | with Reserved Font Name .
3 | Copyright (c) , (),
4 | with Reserved Font Name .
5 | Copyright (c) , ().
6 |
7 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
8 | This license is copied below, and is also available with a FAQ at:
9 | http://scripts.sil.org/OFL
10 |
11 |
12 | -----------------------------------------------------------
13 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
14 | -----------------------------------------------------------
15 |
16 | PREAMBLE
17 | The goals of the Open Font License (OFL) are to stimulate worldwide
18 | development of collaborative font projects, to support the font creation
19 | efforts of academic and linguistic communities, and to provide a free and
20 | open framework in which fonts may be shared and improved in partnership
21 | with others.
22 |
23 | The OFL allows the licensed fonts to be used, studied, modified and
24 | redistributed freely as long as they are not sold by themselves. The
25 | fonts, including any derivative works, can be bundled, embedded,
26 | redistributed and/or sold with any software provided that any reserved
27 | names are not used by derivative works. The fonts and derivatives,
28 | however, cannot be released under any other type of license. The
29 | requirement for fonts to remain under this license does not apply
30 | to any document created using the fonts or their derivatives.
31 |
32 | DEFINITIONS
33 | "Font Software" refers to the set of files released by the Copyright
34 | Holder(s) under this license and clearly marked as such. This may
35 | include source files, build scripts and documentation.
36 |
37 | "Reserved Font Name" refers to any names specified as such after the
38 | copyright statement(s).
39 |
40 | "Original Version" refers to the collection of Font Software components as
41 | distributed by the Copyright Holder(s).
42 |
43 | "Modified Version" refers to any derivative made by adding to, deleting,
44 | or substituting -- in part or in whole -- any of the components of the
45 | Original Version, by changing formats or by porting the Font Software to a
46 | new environment.
47 |
48 | "Author" refers to any designer, engineer, programmer, technical
49 | writer or other person who contributed to the Font Software.
50 |
51 | PERMISSION & CONDITIONS
52 | Permission is hereby granted, free of charge, to any person obtaining
53 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
54 | redistribute, and sell modified and unmodified copies of the Font
55 | Software, subject to the following conditions:
56 |
57 | 1) Neither the Font Software nor any of its individual components,
58 | in Original or Modified Versions, may be sold by itself.
59 |
60 | 2) Original or Modified Versions of the Font Software may be bundled,
61 | redistributed and/or sold with any software, provided that each copy
62 | contains the above copyright notice and this license. These can be
63 | included either as stand-alone text files, human-readable headers or
64 | in the appropriate machine-readable metadata fields within text or
65 | binary files as long as those fields can be easily viewed by the user.
66 |
67 | 3) No Modified Version of the Font Software may use the Reserved Font
68 | Name(s) unless explicit written permission is granted by the corresponding
69 | Copyright Holder. This restriction only applies to the primary font name as
70 | presented to the users.
71 |
72 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
73 | Software shall not be used to promote, endorse or advertise any
74 | Modified Version, except to acknowledge the contribution(s) of the
75 | Copyright Holder(s) and the Author(s) or with their explicit written
76 | permission.
77 |
78 | 5) The Font Software, modified or unmodified, in part or in whole,
79 | must be distributed entirely under this license, and must not be
80 | distributed under any other license. The requirement for fonts to
81 | remain under this license does not apply to any document created
82 | using the Font Software.
83 |
84 | TERMINATION
85 | This license becomes null and void if any of the above conditions are
86 | not met.
87 |
88 | DISCLAIMER
89 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
90 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
91 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
92 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
93 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
94 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
95 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
96 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
97 | OTHER DEALINGS IN THE FONT SOFTWARE.
98 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/AppCompatPreferenceActivity.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import android.content.res.Configuration;
4 | import android.os.Bundle;
5 | import android.preference.PreferenceActivity;
6 | import android.support.annotation.LayoutRes;
7 | import android.support.annotation.Nullable;
8 | import android.support.v7.app.ActionBar;
9 | import android.support.v7.app.AppCompatDelegate;
10 | import android.support.v7.widget.Toolbar;
11 | import android.view.MenuInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 |
15 | /**
16 | * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
17 | * to be used with AppCompat.
18 | */
19 | public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
20 |
21 | private AppCompatDelegate mDelegate;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | getDelegate().installViewFactory();
26 | getDelegate().onCreate(savedInstanceState);
27 | super.onCreate(savedInstanceState);
28 | }
29 |
30 | @Override
31 | protected void onPostCreate(Bundle savedInstanceState) {
32 | super.onPostCreate(savedInstanceState);
33 | getDelegate().onPostCreate(savedInstanceState);
34 | }
35 |
36 | public ActionBar getSupportActionBar() {
37 | return getDelegate().getSupportActionBar();
38 | }
39 |
40 | public void setSupportActionBar(@Nullable Toolbar toolbar) {
41 | getDelegate().setSupportActionBar(toolbar);
42 | }
43 |
44 | @Override
45 | public MenuInflater getMenuInflater() {
46 | return getDelegate().getMenuInflater();
47 | }
48 |
49 | @Override
50 | public void setContentView(@LayoutRes int layoutResID) {
51 | getDelegate().setContentView(layoutResID);
52 | }
53 |
54 | @Override
55 | public void setContentView(View view) {
56 | getDelegate().setContentView(view);
57 | }
58 |
59 | @Override
60 | public void setContentView(View view, ViewGroup.LayoutParams params) {
61 | getDelegate().setContentView(view, params);
62 | }
63 |
64 | @Override
65 | public void addContentView(View view, ViewGroup.LayoutParams params) {
66 | getDelegate().addContentView(view, params);
67 | }
68 |
69 | @Override
70 | protected void onPostResume() {
71 | super.onPostResume();
72 | getDelegate().onPostResume();
73 | }
74 |
75 | @Override
76 | protected void onTitleChanged(CharSequence title, int color) {
77 | super.onTitleChanged(title, color);
78 | getDelegate().setTitle(title);
79 | }
80 |
81 | @Override
82 | public void onConfigurationChanged(Configuration newConfig) {
83 | super.onConfigurationChanged(newConfig);
84 | getDelegate().onConfigurationChanged(newConfig);
85 | }
86 |
87 | @Override
88 | protected void onStop() {
89 | super.onStop();
90 | getDelegate().onStop();
91 | }
92 |
93 | @Override
94 | protected void onDestroy() {
95 | super.onDestroy();
96 | getDelegate().onDestroy();
97 | }
98 |
99 | public void invalidateOptionsMenu() {
100 | getDelegate().invalidateOptionsMenu();
101 | }
102 |
103 | private AppCompatDelegate getDelegate() {
104 | if (mDelegate == null) {
105 | mDelegate = AppCompatDelegate.create(this, null);
106 | }
107 | return mDelegate;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/BitcoinDonationDialog.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import android.app.Dialog;
4 | import android.app.DialogFragment;
5 | import android.content.ActivityNotFoundException;
6 | import android.content.DialogInterface;
7 | import android.content.Intent;
8 | import android.net.Uri;
9 | import android.os.Bundle;
10 | import android.support.v7.app.AlertDialog;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.widget.Button;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 |
17 | import org.asdtm.goodweather.utils.Constants;
18 | import org.asdtm.goodweather.utils.Utils;
19 |
20 | public class BitcoinDonationDialog extends DialogFragment {
21 |
22 | public static BitcoinDonationDialog newInstance() {
23 | return new BitcoinDonationDialog();
24 | }
25 |
26 | @Override
27 | public Dialog onCreateDialog(Bundle savedInstanceState) {
28 | LayoutInflater inflater = getActivity().getLayoutInflater();
29 | View v = inflater.inflate(R.layout.dialog_donation_bitcoin, null);
30 | TextView bitcoinAddress = (TextView) v.findViewById(R.id.bitcoin_address);
31 | Button copyBitcoinAddress = (Button) v.findViewById(R.id.copy_bitcoin_address_button);
32 | Button openBitcoinApp = (Button) v.findViewById(R.id.open_bitcoin_app_button);
33 |
34 | bitcoinAddress.setText(Constants.BITCOIN_ADDRESS);
35 | copyBitcoinAddress.setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View view) {
38 | Utils.copyToClipboard(getActivity(), Constants.BITCOIN_ADDRESS);
39 | Toast.makeText(getActivity(),
40 | R.string.donation_bitcoin_copy_message,
41 | Toast.LENGTH_SHORT).show();
42 | }
43 | });
44 | openBitcoinApp.setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View view) {
47 | try {
48 | Intent intent = new Intent(Intent.ACTION_VIEW);
49 | intent.setData(Uri.parse("bitcoin:" + Constants.BITCOIN_ADDRESS));
50 | startActivity(intent);
51 | } catch (ActivityNotFoundException e) {
52 | Toast.makeText(getActivity(),
53 | R.string.donation_bitcoin_copy_message,
54 | Toast.LENGTH_SHORT).show();
55 | }
56 | }
57 | });
58 |
59 | AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
60 | alertDialog.setTitle("Bitcoin");
61 | alertDialog.setView(v);
62 | alertDialog.setNegativeButton(android.R.string.cancel,
63 | new DialogInterface.OnClickListener() {
64 | @Override
65 | public void onClick(DialogInterface dialogInterface,
66 | int i) {
67 | dialogInterface.cancel();
68 | }
69 | });
70 | return alertDialog.create();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/ConnectionDetector.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | public class ConnectionDetector {
8 |
9 | private Context mContext;
10 |
11 | public ConnectionDetector(Context context) {
12 | mContext = context;
13 | }
14 |
15 | public boolean isNetworkAvailableAndConnected() {
16 | ConnectivityManager connectivityManager
17 | = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
18 |
19 | NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
20 |
21 | return networkInfo != null && networkInfo.isConnected();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/GoodWeatherApp.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.content.res.Configuration;
6 |
7 | import org.asdtm.goodweather.utils.LanguageUtil;
8 | import org.asdtm.goodweather.utils.PreferenceUtil;
9 | import org.asdtm.goodweather.utils.PreferenceUtil.Theme;
10 |
11 | public class GoodWeatherApp extends Application {
12 |
13 | private static final String TAG = "GoodWeatherApp";
14 |
15 | private static Theme sTheme = Theme.light;
16 |
17 | @Override
18 | public void onCreate() {
19 | super.onCreate();
20 | LanguageUtil.setLanguage(this, PreferenceUtil.getLanguage(this));
21 |
22 | sTheme = PreferenceUtil.getTheme(this);
23 | }
24 |
25 | @Override
26 | public void onConfigurationChanged(Configuration newConfig) {
27 | super.onConfigurationChanged(newConfig);
28 | LanguageUtil.setLanguage(this, PreferenceUtil.getLanguage(this));
29 | }
30 |
31 | public void reloadTheme() {
32 | sTheme = PreferenceUtil.getTheme(this);
33 | }
34 |
35 | public void applyTheme(Activity activity) {
36 | activity.setTheme(getThemeResId());
37 | }
38 |
39 | public static int getThemeResId() {
40 | switch (sTheme) {
41 | case light:
42 | return R.style.AppThemeLight;
43 | case dark:
44 | return R.style.AppThemeDark;
45 | default:
46 | return R.style.AppThemeLight;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/LicenseActivity.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import android.os.Build;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.ActionBar;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.support.v7.widget.Toolbar;
9 | import android.text.Html;
10 | import android.view.MenuItem;
11 | import android.widget.TextView;
12 |
13 | import java.io.BufferedReader;
14 | import java.io.IOException;
15 | import java.io.InputStream;
16 | import java.io.InputStreamReader;
17 |
18 | public class LicenseActivity extends AppCompatActivity {
19 |
20 | @Override
21 | protected void onCreate(@Nullable Bundle savedInstanceState) {
22 | ((GoodWeatherApp) getApplication()).applyTheme(this);
23 | super.onCreate(savedInstanceState);
24 | setContentView(R.layout.activity_license);
25 | setupActionBar();
26 |
27 | final String path = getIntent().getData().getPath();
28 |
29 | setTitle(getString(R.string.title_activity_license, path.substring(24)));
30 |
31 | try {
32 | TextView licenseTextView = (TextView) findViewById(R.id.license_license_text);
33 | final String licenseText = readLicense(getAssets().open(path.substring(15)));
34 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
35 | licenseTextView.setText(Html.fromHtml(licenseText.replace("\n\n", "
"), Html.FROM_HTML_MODE_LEGACY));
36 | } else {
37 | licenseTextView.setText(Html.fromHtml(licenseText.replace("\n\n", "
")));
38 | }
39 | } catch (IOException e) {
40 | e.printStackTrace();
41 | }
42 | }
43 |
44 | private void setupActionBar() {
45 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
46 | setSupportActionBar(toolbar);
47 | ActionBar actionBar = getSupportActionBar();
48 | if (actionBar != null) {
49 | actionBar.setDisplayHomeAsUpEnabled(true);
50 | }
51 | }
52 |
53 | @Override
54 | public boolean onOptionsItemSelected(MenuItem item) {
55 | switch (item.getItemId()) {
56 | case android.R.id.home:
57 | this.onBackPressed();
58 | return true;
59 | }
60 | return super.onOptionsItemSelected(item);
61 | }
62 |
63 | private String readLicense(final InputStream inputStream) throws IOException {
64 | InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
65 | BufferedReader reader = new BufferedReader(inputStreamReader);
66 | StringBuilder builder = new StringBuilder();
67 | try {
68 | String stringRead;
69 | while ((stringRead = reader.readLine()) != null) {
70 | builder.append(stringRead).append("\n");
71 | }
72 | } catch (IOException e) {
73 | e.printStackTrace();
74 | } finally {
75 | reader.close();
76 | }
77 | return builder.toString();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/WeatherJSONParser.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import org.asdtm.goodweather.model.CitySearch;
4 | import org.asdtm.goodweather.model.Weather;
5 | import org.json.JSONArray;
6 | import org.json.JSONException;
7 | import org.json.JSONObject;
8 |
9 | public class WeatherJSONParser {
10 |
11 | private static final String TAG = "WeatherJSONParser";
12 |
13 | public static Weather getWeather(String data) throws JSONException {
14 | Weather weather = new Weather();
15 | CitySearch location = new CitySearch();
16 |
17 | JSONObject weatherData = new JSONObject(data);
18 |
19 | JSONArray weatherArray = weatherData.getJSONArray("weather");
20 |
21 | JSONObject weatherObj = weatherArray.getJSONObject(0);
22 | if (weatherObj.has("description")) {
23 | weather.currentWeather.setDescription(weatherObj.getString("description"));
24 | }
25 | if (weatherObj.has("icon")) {
26 | weather.currentWeather.setIdIcon(weatherObj.getString("icon"));
27 | }
28 |
29 | JSONObject mainObj = weatherData.getJSONObject("main");
30 | if (mainObj.has("temp")) {
31 | weather.temperature.setTemp(Float.parseFloat(mainObj.getString("temp")));
32 | }
33 | if (mainObj.has("pressure")) {
34 | weather.currentCondition.setPressure(Float.parseFloat(mainObj.getString("pressure")));
35 | }
36 | if (mainObj.has("humidity")) {
37 | weather.currentCondition.setHumidity(mainObj.getInt("humidity"));
38 | }
39 |
40 | JSONObject windObj = weatherData.getJSONObject("wind");
41 | if (windObj.has("speed")) {
42 | weather.wind.setSpeed(Float.parseFloat(windObj.getString("speed")));
43 | }
44 | if (windObj.has("deg")) {
45 | weather.wind.setDirection(Float.parseFloat(windObj.getString("deg")));
46 | }
47 |
48 | JSONObject cloudsObj = weatherData.getJSONObject("clouds");
49 | if (cloudsObj.has("all")) {
50 | weather.cloud.setClouds(cloudsObj.getInt("all"));
51 | }
52 |
53 | if (weatherData.has("name")) {
54 | location.setCityName(weatherData.getString("name"));
55 | }
56 |
57 | JSONObject sysObj = weatherData.getJSONObject("sys");
58 | if (sysObj.has("country")) {
59 | location.setCountryCode(sysObj.getString("country"));
60 | }
61 | weather.sys.setSunrise(sysObj.getLong("sunrise"));
62 | weather.sys.setSunset(sysObj.getLong("sunset"));
63 |
64 | weather.location = location;
65 |
66 | return weather;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/WeatherRequest.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.net.HttpURLConnection;
7 | import java.net.URL;
8 | import org.asdtm.goodweather.utils.Constants;
9 | import org.asdtm.goodweather.utils.Utils;
10 |
11 | public class WeatherRequest
12 | {
13 | private static final String TAG = "WeatherRequest";
14 |
15 | byte[] getWeatherByte(URL url) throws IOException
16 | {
17 | // Вызов метода openConnection() создает объект подключения к заданному url-адресу
18 | HttpURLConnection connection = (HttpURLConnection) url.openConnection();
19 |
20 | try {
21 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
22 | InputStream inputStream = connection.getInputStream();
23 |
24 | if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
25 | return null;
26 | }
27 |
28 | int bytesRead = 0;
29 | byte[] buffer = new byte[1024];
30 |
31 | while ((bytesRead = inputStream.read(buffer)) > 0) {
32 | outputStream.write(buffer, 0, bytesRead);
33 | }
34 | outputStream.close();
35 |
36 | return outputStream.toByteArray();
37 | } finally {
38 | connection.disconnect();
39 | }
40 | }
41 |
42 | public String getResultAsString(URL url) throws IOException
43 | {
44 | return new String(getWeatherByte(url));
45 | }
46 |
47 | public String getItems(String lat, String lon, String units, String lang) throws IOException
48 | {
49 | return getResultAsString(Utils.getWeatherForecastUrl(Constants.WEATHER_ENDPOINT, lat, lon, units, lang));
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/adapter/WeatherForecastAdapter.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import org.asdtm.goodweather.R;
11 | import org.asdtm.goodweather.model.WeatherForecast;
12 |
13 | import java.util.List;
14 |
15 | public class WeatherForecastAdapter extends RecyclerView.Adapter {
16 |
17 | private Context mContext;
18 | private List mWeatherList;
19 | private FragmentManager mFragmentManager;
20 |
21 | public WeatherForecastAdapter(Context context, List weather, FragmentManager fragmentManager) {
22 | mContext = context;
23 | mWeatherList = weather;
24 | mFragmentManager = fragmentManager;
25 | }
26 |
27 | @Override
28 | public WeatherForecastViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
29 | LayoutInflater inflater = LayoutInflater.from(parent.getContext());
30 | View v = inflater.inflate(R.layout.forecast_item, parent, false);
31 | return new WeatherForecastViewHolder(v, mContext, mFragmentManager);
32 | }
33 |
34 | @Override
35 | public void onBindViewHolder(WeatherForecastViewHolder holder, int position) {
36 | WeatherForecast weather = mWeatherList.get(position);
37 | holder.bindWeather(weather);
38 | }
39 |
40 | @Override
41 | public int getItemCount() {
42 | return (mWeatherList != null ? mWeatherList.size() : 0);
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/adapter/WeatherForecastViewHolder.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.adapter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Typeface;
5 | import android.support.v4.app.FragmentManager;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.view.View;
8 | import android.widget.TextView;
9 |
10 | import org.asdtm.goodweather.R;
11 | import org.asdtm.goodweather.fragment.ForecastBottomSheetDialogFragment;
12 | import org.asdtm.goodweather.model.WeatherForecast;
13 | import org.asdtm.goodweather.utils.Utils;
14 |
15 | import java.text.SimpleDateFormat;
16 | import java.util.Date;
17 | import java.util.Locale;
18 |
19 | public class WeatherForecastViewHolder extends RecyclerView.ViewHolder implements
20 | View.OnClickListener {
21 |
22 | private final String TAG = "ForecastViewHolder";
23 |
24 | private WeatherForecast mWeatherForecast;
25 | private Context mContext;
26 | private FragmentManager mFragmentManager;
27 |
28 | private TextView mDateTime;
29 | private TextView mIcon;
30 | private TextView mTemperatureMin;
31 | private TextView mTemperatureMax;
32 |
33 | public WeatherForecastViewHolder(View itemView, Context context,
34 | FragmentManager fragmentManager) {
35 | super(itemView);
36 | mContext = context;
37 | mFragmentManager = fragmentManager;
38 | itemView.setOnClickListener(this);
39 |
40 | mDateTime = (TextView) itemView.findViewById(R.id.forecast_date_time);
41 | mIcon = (TextView) itemView.findViewById(R.id.forecast_icon);
42 | mTemperatureMin = (TextView) itemView.findViewById(R.id.forecast_temperature_min);
43 | mTemperatureMax = (TextView) itemView.findViewById(R.id.forecast_temperature_max);
44 | }
45 |
46 | void bindWeather(WeatherForecast weather) {
47 | mWeatherForecast = weather;
48 |
49 | Typeface typeface = Typeface.createFromAsset(mContext.getAssets(),
50 | "fonts/weathericons-regular-webfont.ttf");
51 | SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMMM", Locale.getDefault());
52 | Date date = new Date(weather.getDateTime() * 1000);
53 | String temperatureMin = mContext.getString(R.string.temperature_with_degree,
54 | String.format(Locale.getDefault(), "%.0f",
55 | weather.getTemperatureMin()));
56 | String temperatureMax = mContext.getString(R.string.temperature_with_degree,
57 | String.format(Locale.getDefault(), "%.0f",
58 | weather.getTemperatureMax()));
59 |
60 | mDateTime.setText(format.format(date));
61 | mIcon.setTypeface(typeface);
62 | mIcon.setText(Utils.getStrIcon(mContext, weather.getIcon()));
63 | if (weather.getTemperatureMin() > 0) {
64 | temperatureMin = "+" + temperatureMin;
65 | }
66 | mTemperatureMin.setText(temperatureMin);
67 | if (weather.getTemperatureMax() > 0) {
68 | temperatureMax = "+" + temperatureMax;
69 | }
70 | mTemperatureMax.setText(temperatureMax);
71 | }
72 |
73 | @Override
74 | public void onClick(View view) {
75 | new ForecastBottomSheetDialogFragment()
76 | .newInstance(mWeatherForecast)
77 | .show(mFragmentManager, "forecastBottomSheet");
78 | }
79 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/fragment/ForecastBottomSheetDialogFragment.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.fragment;
2 |
3 | import android.graphics.Typeface;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.design.widget.BottomSheetDialogFragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import org.asdtm.goodweather.R;
13 | import org.asdtm.goodweather.model.WeatherForecast;
14 | import org.asdtm.goodweather.utils.Utils;
15 |
16 | import java.util.Locale;
17 |
18 | public class ForecastBottomSheetDialogFragment extends BottomSheetDialogFragment {
19 |
20 | private WeatherForecast mWeather;
21 |
22 | public ForecastBottomSheetDialogFragment newInstance(WeatherForecast weather) {
23 | ForecastBottomSheetDialogFragment fragment = new ForecastBottomSheetDialogFragment();
24 | Bundle args = new Bundle();
25 | args.putSerializable("weatherForecast", weather);
26 | fragment.setArguments(args);
27 | return fragment;
28 | }
29 |
30 | @Override
31 | public void onCreate(@Nullable Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | mWeather = (WeatherForecast) getArguments().getSerializable("weatherForecast");
34 | }
35 |
36 | @Override
37 | public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
38 | View v = inflater.inflate(R.layout.fragment_forecast_bottom_sheet, parent, false);
39 |
40 | String speedScale = Utils.getSpeedScale(getActivity());
41 | String percentSign = getActivity().getString(R.string.percent_sign);
42 | String pressureMeasurement = getActivity().getString(R.string.pressure_measurement);
43 | String mmLabel = getString(R.string.millimetre_label);
44 |
45 | Float temperatureMorning = mWeather.getTemperatureMorning();
46 | Float temperatureDay = mWeather.getTemperatureDay();
47 | Float temperatureEvening = mWeather.getTemperatureEvening();
48 | Float temperatureNight = mWeather.getTemperatureNight();
49 |
50 | String description = mWeather.getDescription();
51 | String temperatureMorningStr = getActivity().getString(R.string.temperature_with_degree,
52 | String.format(Locale.getDefault(),
53 | "%.0f",
54 | temperatureMorning));
55 | String temperatureDayStr = getActivity().getString(R.string.temperature_with_degree,
56 | String.format(Locale.getDefault(),
57 | "%.0f",
58 | temperatureDay));
59 | String temperatureEveningStr = getActivity().getString(R.string.temperature_with_degree,
60 | String.format(Locale.getDefault(),
61 | "%.0f",
62 | temperatureEvening));
63 | String temperatureNightStr = getActivity().getString(R.string.temperature_with_degree,
64 | String.format(Locale.getDefault(),
65 | "%.0f",
66 | temperatureNight));
67 | String wind = getActivity().getString(R.string.wind_label, mWeather.getWindSpeed(), speedScale);
68 | String windDegree = mWeather.getWindDegree();
69 | String windDirection = Utils.windDegreeToDirections(getActivity(),
70 | Double.parseDouble(windDegree));
71 | String rain = getString(R.string.rain_label, mWeather.getRain(), mmLabel);
72 | String snow = getString(R.string.snow_label, mWeather.getSnow(), mmLabel);
73 | String pressure = getActivity().getString(R.string.pressure_label, mWeather.getPressure(), pressureMeasurement);
74 | String humidity = getActivity().getString(R.string.humidity_label, mWeather.getHumidity(), percentSign);
75 |
76 | TextView descriptionView = (TextView) v.findViewById(R.id.forecast_description);
77 | TextView windView = (TextView) v.findViewById(R.id.forecast_wind);
78 | TextView rainView = (TextView) v.findViewById(R.id.forecast_rain);
79 | TextView snowView = (TextView) v.findViewById(R.id.forecast_snow);
80 | TextView humidityView = (TextView) v.findViewById(R.id.forecast_humidity);
81 | TextView pressureView = (TextView) v.findViewById(R.id.forecast_pressure);
82 |
83 | TextView temperatureMorningView = (TextView) v.findViewById(
84 | R.id.forecast_morning_temperature);
85 | TextView temperatureDayView = (TextView) v.findViewById(
86 | R.id.forecast_day_temperature);
87 | TextView temperatureEveningView = (TextView) v.findViewById(
88 | R.id.forecast_evening_temperature);
89 | TextView temperatureNightView = (TextView) v.findViewById(
90 | R.id.forecast_night_temperature);
91 | Typeface typeface = Typeface.createFromAsset(getActivity().getAssets(),
92 | "fonts/weathericons-regular-webfont.ttf");
93 |
94 | descriptionView.setText(description);
95 | windView.setTypeface(typeface);
96 | windView.setText(wind + " " + windDirection);
97 | rainView.setText(rain);
98 | snowView.setText(snow);
99 | humidityView.setText(humidity);
100 | pressureView.setText(pressure);
101 | if (temperatureMorning > 0) {
102 | temperatureMorningStr = "+" + temperatureMorningStr;
103 | }
104 | if (temperatureDay > 0) {
105 | temperatureDayStr = "+" + temperatureDayStr;
106 | }
107 | if (temperatureEvening > 0) {
108 | temperatureEveningStr = "+" + temperatureEveningStr;
109 | }
110 | if (temperatureNight > 0) {
111 | temperatureNightStr = "+" + temperatureNightStr;
112 | }
113 | temperatureMorningView.setText(temperatureMorningStr);
114 | temperatureDayView.setText(temperatureDayStr);
115 | temperatureEveningView.setText(temperatureEveningStr);
116 | temperatureNightView.setText(temperatureNightStr);
117 |
118 | return v;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/model/CitySearch.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.model;
2 |
3 | public class CitySearch
4 | {
5 | private String mCityName;
6 | private String mCountry;
7 | private String mLatitude;
8 | private String mLongitude;
9 | private String mCountryCode;
10 |
11 | public CitySearch(){}
12 | public CitySearch(String cityName, String countryCode, String latitude, String longitude)
13 | {
14 | mCityName = cityName;
15 | mCountryCode = countryCode;
16 | mLatitude = latitude;
17 | mLongitude = longitude;
18 | }
19 |
20 | public String getCityName()
21 | {
22 | return mCityName;
23 | }
24 |
25 | public void setCityName(String cityName)
26 | {
27 | mCityName = cityName;
28 | }
29 |
30 | public String getCountry()
31 | {
32 | return mCountry;
33 | }
34 |
35 | public void setCountry(String country)
36 | {
37 | mCountry = country;
38 | }
39 |
40 | public String getLatitude()
41 | {
42 | return mLatitude;
43 | }
44 |
45 | public void setLatitude(String latitude)
46 | {
47 | mLatitude = latitude;
48 | }
49 |
50 | public String getLongitude()
51 | {
52 | return mLongitude;
53 | }
54 |
55 | public void setLongitude(String longitude)
56 | {
57 | mLongitude = longitude;
58 | }
59 |
60 | public String getCountryCode()
61 | {
62 | return mCountryCode;
63 | }
64 |
65 | public void setCountryCode(String countryCode)
66 | {
67 | mCountryCode = countryCode;
68 | }
69 |
70 | @Override
71 | public String toString()
72 | {
73 | return mCityName + ", " + mCountryCode;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/model/Weather.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.model;
2 |
3 | public class Weather {
4 |
5 | public CitySearch location;
6 | public Temperature temperature = new Temperature();
7 | public Wind wind = new Wind();
8 | public CurrentWeather currentWeather = new CurrentWeather();
9 | public CurrentCondition currentCondition = new CurrentCondition();
10 | public Cloud cloud = new Cloud();
11 | public Sys sys = new Sys();
12 |
13 | public class Temperature {
14 |
15 | private float mTemp;
16 |
17 | public float getTemp() {
18 | return mTemp;
19 | }
20 |
21 | public void setTemp(float temp) {
22 | mTemp = temp;
23 | }
24 | }
25 |
26 | public class Wind {
27 |
28 | private float mSpeed;
29 | private float mDirection;
30 |
31 | public float getSpeed() {
32 | return mSpeed;
33 | }
34 |
35 | public void setSpeed(float speed) {
36 | mSpeed = speed;
37 | }
38 |
39 | public float getDirection() {
40 | return mDirection;
41 | }
42 |
43 | public void setDirection(float direction) {
44 | mDirection = direction;
45 | }
46 | }
47 |
48 | public class CurrentWeather {
49 |
50 | private String mDescription;
51 | private String mIdIcon;
52 |
53 | public String getDescription() {
54 | return mDescription;
55 | }
56 |
57 | public void setDescription(String description) {
58 | mDescription = description.substring(0, 1).toUpperCase() + description.substring(1);
59 | }
60 |
61 | public String getIdIcon() {
62 | return mIdIcon;
63 | }
64 |
65 | public void setIdIcon(String idIcon) {
66 | mIdIcon = idIcon;
67 | }
68 | }
69 |
70 | public class CurrentCondition {
71 |
72 | private float mPressure;
73 | private int mHumidity;
74 |
75 | public float getPressure() {
76 | return mPressure;
77 | }
78 |
79 | public void setPressure(float pressure) {
80 | mPressure = pressure;
81 | }
82 |
83 | public int getHumidity() {
84 | return mHumidity;
85 | }
86 |
87 | public void setHumidity(int humidity) {
88 | mHumidity = humidity;
89 | }
90 | }
91 |
92 | public class Cloud {
93 |
94 | private int mClouds;
95 |
96 | public int getClouds() {
97 | return mClouds;
98 | }
99 |
100 | public void setClouds(int clouds) {
101 | mClouds = clouds;
102 | }
103 | }
104 |
105 | public class Sys {
106 |
107 | private long mSunrise;
108 | private long mSunset;
109 |
110 | public long getSunrise() {
111 | return mSunrise;
112 | }
113 |
114 | public void setSunrise(long sunrise) {
115 | mSunrise = sunrise;
116 | }
117 |
118 | public long getSunset() {
119 | return mSunset;
120 | }
121 |
122 | public void setSunset(long sunset) {
123 | mSunset = sunset;
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/model/WeatherForecast.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.model;
2 |
3 | import java.io.Serializable;
4 |
5 | public class WeatherForecast implements Serializable {
6 |
7 | private long dateTime;
8 | private float temperatureMin;
9 | private float temperatureMax;
10 | private float temperatureMorning;
11 | private float temperatureDay;
12 | private float temperatureEvening;
13 | private float temperatureNight;
14 | private String pressure;
15 | private String humidity;
16 | private String icon;
17 | private String description;
18 | private String windSpeed;
19 | private String windDegree;
20 | private String cloudiness;
21 | private String rain;
22 | private String snow;
23 |
24 | public String getDescription() {
25 | return description;
26 | }
27 |
28 | public void setDescription(String description) {
29 | this.description = description.substring(0, 1).toUpperCase() + description.substring(1);
30 | }
31 |
32 | public long getDateTime() {
33 | return dateTime;
34 | }
35 |
36 | public void setDateTime(long dateTime) {
37 | this.dateTime = dateTime;
38 | }
39 |
40 | public String getHumidity() {
41 | return humidity;
42 | }
43 |
44 | public void setHumidity(String humidity) {
45 | this.humidity = humidity;
46 | }
47 |
48 | public String getIcon() {
49 | return icon;
50 | }
51 |
52 | public void setIcon(String icon) {
53 | this.icon = icon;
54 | }
55 |
56 | public String getPressure() {
57 | return pressure;
58 | }
59 |
60 | public void setPressure(String pressure) {
61 | this.pressure = pressure;
62 | }
63 |
64 | public String getRain() {
65 | return rain;
66 | }
67 |
68 | public void setRain(String rain) {
69 | this.rain = rain;
70 | }
71 |
72 | public String getSnow() {
73 | return snow;
74 | }
75 |
76 | public void setSnow(String snow) {
77 | this.snow = snow;
78 | }
79 |
80 | public String getWindDegree() {
81 | return windDegree;
82 | }
83 |
84 | public void setWindDegree(String windDegree) {
85 | this.windDegree = windDegree;
86 | }
87 |
88 | public String getWindSpeed() {
89 | return windSpeed;
90 | }
91 |
92 | public void setWindSpeed(String windSpeed) {
93 | this.windSpeed = windSpeed;
94 | }
95 |
96 | public String getCloudiness() {
97 | return cloudiness;
98 | }
99 |
100 | public void setCloudiness(String cloudiness) {
101 | this.cloudiness = cloudiness;
102 | }
103 |
104 | public float getTemperatureDay() {
105 | return temperatureDay;
106 | }
107 |
108 | public void setTemperatureDay(float temperatureDay) {
109 | this.temperatureDay = temperatureDay;
110 | }
111 |
112 | public float getTemperatureEvening() {
113 | return temperatureEvening;
114 | }
115 |
116 | public void setTemperatureEvening(float temperatureEvening) {
117 | this.temperatureEvening = temperatureEvening;
118 | }
119 |
120 | public float getTemperatureMax() {
121 | return temperatureMax;
122 | }
123 |
124 | public void setTemperatureMax(float temperatureMax) {
125 | this.temperatureMax = temperatureMax;
126 | }
127 |
128 | public float getTemperatureMin() {
129 | return temperatureMin;
130 | }
131 |
132 | public void setTemperatureMin(float temperatureMin) {
133 | this.temperatureMin = temperatureMin;
134 | }
135 |
136 | public float getTemperatureMorning() {
137 | return temperatureMorning;
138 | }
139 |
140 | public void setTemperatureMorning(float temperatureMorning) {
141 | this.temperatureMorning = temperatureMorning;
142 | }
143 |
144 | public float getTemperatureNight() {
145 | return temperatureNight;
146 | }
147 |
148 | public void setTemperatureNight(float temperatureNight) {
149 | this.temperatureNight = temperatureNight;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/receiver/StartupReceiver.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.receiver;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | import org.asdtm.goodweather.service.NotificationService;
8 | import org.asdtm.goodweather.utils.AppPreference;
9 |
10 | public class StartupReceiver extends BroadcastReceiver {
11 |
12 | private static final String TAG = "StartupReceiver";
13 |
14 | @Override
15 | public void onReceive(Context context, Intent intent) {
16 | boolean isNotificationEnabled = AppPreference.isNotificationEnabled(context);
17 | NotificationService.setNotificationServiceAlarm(context, isNotificationEnabled);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/service/CurrentWeatherService.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.service;
2 |
3 | import android.app.IntentService;
4 | import android.content.Intent;
5 | import android.content.SharedPreferences;
6 | import android.support.v4.content.LocalBroadcastManager;
7 | import android.util.Log;
8 |
9 | import org.asdtm.goodweather.ConnectionDetector;
10 | import org.asdtm.goodweather.utils.AppPreference;
11 | import org.asdtm.goodweather.utils.Constants;
12 | import org.asdtm.goodweather.utils.LanguageUtil;
13 | import org.asdtm.goodweather.utils.PreferenceUtil;
14 | import org.asdtm.goodweather.utils.Utils;
15 | import org.json.JSONArray;
16 | import org.json.JSONException;
17 | import org.json.JSONObject;
18 |
19 | import java.io.ByteArrayOutputStream;
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.net.HttpURLConnection;
23 | import java.net.URL;
24 |
25 | import static org.asdtm.goodweather.MainActivity.mCitySearch;
26 | import static org.asdtm.goodweather.MainActivity.mWeather;
27 |
28 | public class CurrentWeatherService extends IntentService {
29 |
30 | private static final String TAG = "WeatherService";
31 |
32 | public static final String ACTION_WEATHER_UPDATE_OK = "org.asdtm.goodweather.action.WEATHER_UPDATE_OK";
33 | public static final String ACTION_WEATHER_UPDATE_FAIL = "org.asdtm.goodweather.action.WEATHER_UPDATE_FAIL";
34 | public static final String ACTION_WEATHER_UPDATE_RESULT = "org.asdtm.goodweather.action.WEATHER_UPDATE_RESULT";
35 |
36 | public CurrentWeatherService() {
37 | super(TAG);
38 | }
39 |
40 | @Override
41 | protected void onHandleIntent(Intent intent) {
42 | ConnectionDetector connectionDetector = new ConnectionDetector(this);
43 | if (!connectionDetector.isNetworkAvailableAndConnected()) {
44 | return;
45 | }
46 |
47 | SharedPreferences preferences = getSharedPreferences(Constants.APP_SETTINGS_NAME, 0);
48 | String latitude = preferences.getString(Constants.APP_SETTINGS_LATITUDE, "51.51");
49 | String longitude = preferences.getString(Constants.APP_SETTINGS_LONGITUDE, "-0.13");
50 | String locale = LanguageUtil.getLanguageName(PreferenceUtil.getLanguage(this));
51 | String units = AppPreference.getTemperatureUnit(this);
52 |
53 | String requestResult = "";
54 | HttpURLConnection connection = null;
55 | try {
56 | URL url = Utils.getWeatherForecastUrl(Constants.WEATHER_ENDPOINT, latitude, longitude, units, locale);
57 | connection = (HttpURLConnection) url.openConnection();
58 |
59 | if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
60 | ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
61 | InputStream inputStream = connection.getInputStream();
62 |
63 | int bytesRead;
64 | byte[] buffer = new byte[1024];
65 | while ((bytesRead = inputStream.read(buffer)) > 0) {
66 | byteArray.write(buffer, 0, bytesRead);
67 | }
68 | byteArray.close();
69 | requestResult = byteArray.toString();
70 | AppPreference.saveLastUpdateTimeMillis(this);
71 | }
72 |
73 | } catch (IOException e) {
74 | Log.e(TAG, "IOException: " + requestResult);
75 |
76 | } finally {
77 | if (connection != null) {
78 | connection.disconnect();
79 | }
80 | }
81 | parseWeather(requestResult);
82 | }
83 |
84 | public void parseWeather(String data) {
85 | try {
86 | JSONObject jsonObject = new JSONObject(data);
87 |
88 | JSONArray weatherArray = jsonObject.getJSONArray("weather");
89 | JSONObject weatherObject = weatherArray.getJSONObject(0);
90 | if (weatherObject.has("description")) {
91 | mWeather.currentWeather.setDescription(weatherObject.getString("description"));
92 | }
93 | if (weatherObject.has("icon")) {
94 | mWeather.currentWeather.setIdIcon(weatherObject.getString("icon"));
95 | }
96 |
97 | JSONObject mainObj = jsonObject.getJSONObject("main");
98 | if (mainObj.has("temp")) {
99 | mWeather.temperature.setTemp(Float.parseFloat(mainObj.getString("temp")));
100 | }
101 | if (mainObj.has("pressure")) {
102 | mWeather.currentCondition.setPressure(
103 | Float.parseFloat(mainObj.getString("pressure")));
104 | }
105 | if (mainObj.has("humidity")) {
106 | mWeather.currentCondition.setHumidity(mainObj.getInt("humidity"));
107 | }
108 |
109 | JSONObject windObj = jsonObject.getJSONObject("wind");
110 | if (windObj.has("speed")) {
111 | mWeather.wind.setSpeed(Float.parseFloat(windObj.getString("speed")));
112 | }
113 | if (windObj.has("deg")) {
114 | mWeather.wind.setDirection(Float.parseFloat(windObj.getString("deg")));
115 | }
116 |
117 | JSONObject cloudsObj = jsonObject.getJSONObject("clouds");
118 | if (cloudsObj.has("all")) {
119 | mWeather.cloud.setClouds(cloudsObj.getInt("all"));
120 | }
121 |
122 | if (jsonObject.has("name")) {
123 | mCitySearch.setCityName(jsonObject.getString("name"));
124 | }
125 |
126 | JSONObject sysObj = jsonObject.getJSONObject("sys");
127 | if (sysObj.has("country")) {
128 | mCitySearch.setCountryCode(sysObj.getString("country"));
129 | }
130 | mWeather.sys.setSunrise(sysObj.getLong("sunrise"));
131 | mWeather.sys.setSunset(sysObj.getLong("sunset"));
132 |
133 | mWeather.location = mCitySearch;
134 | sendResult(ACTION_WEATHER_UPDATE_OK);
135 | } catch (JSONException e) {
136 | Log.e(TAG, "Error parsing JSON");
137 | sendResult(ACTION_WEATHER_UPDATE_FAIL);
138 | }
139 | }
140 |
141 | public void sendResult(String result) {
142 | Intent intent = new Intent(ACTION_WEATHER_UPDATE_RESULT);
143 | if (result.equals(ACTION_WEATHER_UPDATE_OK)) {
144 | intent.putExtra(ACTION_WEATHER_UPDATE_RESULT, ACTION_WEATHER_UPDATE_OK);
145 | } else if (result.equals(ACTION_WEATHER_UPDATE_FAIL)) {
146 | intent.putExtra(ACTION_WEATHER_UPDATE_RESULT, ACTION_WEATHER_UPDATE_FAIL);
147 | }
148 | LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/ApiKeys.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | public class ApiKeys {
4 |
5 | /**
6 | * API key for http://openweathermap.org/api
7 | */
8 | public static final String OPEN_WEATHER_MAP_API_KEY = "1487dd8a93bfd85d278d9ac8dcfee94c";
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/AppWidgetProviderAlarm.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | import android.app.AlarmManager;
4 | import android.app.PendingIntent;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.SystemClock;
8 |
9 | public class AppWidgetProviderAlarm {
10 |
11 | private static final String TAG = "AppWidgetProviderAlarm";
12 |
13 | private Context mContext;
14 | private Class> mCls;
15 |
16 | public AppWidgetProviderAlarm(Context context, Class> cls) {
17 | this.mContext = context;
18 | this.mCls = cls;
19 | }
20 |
21 | public void setAlarm() {
22 | String updatePeriodStr = AppPreference.getWidgetUpdatePeriod(mContext);
23 | long updatePeriodMills = Utils.intervalMillisForAlarm(updatePeriodStr);
24 | AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
25 | alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
26 | SystemClock.elapsedRealtime() + updatePeriodMills,
27 | updatePeriodMills,
28 | getPendingIntent(mCls));
29 | }
30 |
31 | public void cancelAlarm() {
32 | AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
33 | alarmManager.cancel(getPendingIntent(mCls));
34 | getPendingIntent(mCls).cancel();
35 | }
36 |
37 | private PendingIntent getPendingIntent(Class> cls) {
38 | Intent intent = new Intent(mContext, cls);
39 | intent.setAction(Constants.ACTION_FORCED_APPWIDGET_UPDATE);
40 | return PendingIntent.getBroadcast(mContext,
41 | 0,
42 | intent,
43 | PendingIntent.FLAG_CANCEL_CURRENT);
44 | }
45 |
46 | public boolean isAlarmOff() {
47 | Intent intent = new Intent(mContext, mCls);
48 | intent.setAction(Constants.ACTION_FORCED_APPWIDGET_UPDATE);
49 | PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,
50 | 0,
51 | intent,
52 | PendingIntent.FLAG_NO_CREATE);
53 | return pendingIntent == null;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/CityParser.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | import android.net.Uri;
4 |
5 | import org.asdtm.goodweather.model.CitySearch;
6 | import org.json.JSONArray;
7 | import org.json.JSONException;
8 | import org.json.JSONObject;
9 |
10 | import java.io.ByteArrayOutputStream;
11 | import java.io.IOException;
12 | import java.io.InputStream;
13 | import java.net.HttpURLConnection;
14 | import java.net.MalformedURLException;
15 | import java.net.URL;
16 | import java.util.ArrayList;
17 | import java.util.List;
18 |
19 | public class CityParser {
20 |
21 | private static final String TAG = "CityParser";
22 | private static final String ENDPOINT = "http://api.openweathermap.org/data/2.5/find";
23 | private static final String APPID = ApiKeys.OPEN_WEATHER_MAP_API_KEY;
24 |
25 | public static List getCity(String query) {
26 | List citySearchList = new ArrayList<>();
27 | CitySearch city;
28 | HttpURLConnection connection = null;
29 |
30 | try {
31 | URL url = getUrl(query);
32 | connection = (HttpURLConnection) url.openConnection();
33 |
34 | if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
35 | return null;
36 | }
37 |
38 | ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
39 | InputStream inputStream = connection.getInputStream();
40 | int bytesRead;
41 | byte[] buffer = new byte[1024];
42 |
43 | while ((bytesRead = inputStream.read(buffer)) > 0) {
44 | byteArray.write(buffer, 0, bytesRead);
45 | }
46 | byteArray.close();
47 |
48 | JSONObject jsonObject = new JSONObject(byteArray.toString());
49 | JSONArray listArray = jsonObject.getJSONArray("list");
50 |
51 | int listArrayCount = listArray.length();
52 |
53 | for (int i = 0; i != listArrayCount; ++i) {
54 | city = new CitySearch();
55 | JSONObject resultObject = listArray.getJSONObject(i);
56 | city.setCityName(resultObject.getString("name"));
57 |
58 | JSONObject coordObject = resultObject.getJSONObject("coord");
59 | city.setLongitude(coordObject.getString("lon"));
60 | city.setLatitude(coordObject.getString("lat"));
61 |
62 | JSONObject sysObject = resultObject.getJSONObject("sys");
63 | city.setCountryCode(sysObject.getString("country"));
64 | citySearchList.add(city);
65 | }
66 |
67 | } catch (JSONException | IOException e) {
68 | e.printStackTrace();
69 | } finally {
70 | if (connection != null) {
71 | connection.disconnect();
72 | }
73 | }
74 |
75 | return citySearchList;
76 | }
77 |
78 | private static URL getUrl(String query) throws MalformedURLException {
79 | String url = Uri.parse(ENDPOINT).buildUpon()
80 | .appendQueryParameter("q", query)
81 | .appendQueryParameter("type", "like")
82 | .appendQueryParameter("cnt", "15")
83 | .appendQueryParameter("APPID", APPID)
84 | .build().toString();
85 | return new URL(url);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/Constants.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | public class Constants {
4 |
5 | /**
6 | * SharedPreference names
7 | */
8 | public static final String APP_SETTINGS_NAME = "config";
9 | public static final String PREF_WEATHER_NAME = "weather_pref";
10 | public static final String PREF_FORECAST_NAME = "weather_forecast";
11 |
12 | /**
13 | * Preferences constants
14 | */
15 | public static final String APP_SETTINGS_LATITUDE = "latitude";
16 | public static final String APP_SETTINGS_LONGITUDE = "longitude";
17 | public static final String APP_SETTINGS_CITY = "city";
18 | public static final String APP_SETTINGS_COUNTRY_CODE = "country_code";
19 | public static final String APP_SETTINGS_GEO_COUNTRY_NAME = "geo_country_name";
20 | public static final String APP_SETTINGS_GEO_DISTRICT_OF_CITY = "geo_district_name";
21 | public static final String APP_SETTINGS_GEO_CITY = "geo_city_name";
22 | public static final String LAST_UPDATE_TIME_IN_MS = "last_update";
23 |
24 | public static final String KEY_PREF_IS_NOTIFICATION_ENABLED = "notification_pref_key";
25 | public static final String KEY_PREF_TEMPERATURE = "temperature_pref_key";
26 | public static final String KEY_PREF_HIDE_DESCRIPTION = "hide_desc_pref_key";
27 | public static final String KEY_PREF_INTERVAL_NOTIFICATION = "notification_interval_pref_key";
28 | public static final String KEY_PREF_VIBRATE = "notification_vibrate_pref_key";
29 | public static final String KEY_PREF_WIDGET_UPDATE_LOCATION = "widget_update_location_pref_key";
30 | public static final String KEY_PREF_WIDGET_USE_GEOCODER = "widget_use_geocoder_pref_key";
31 | public static final String KEY_PREF_WIDGET_THEME = "widget_theme_pref_key";
32 | public static final String KEY_PREF_WIDGET_UPDATE_PERIOD = "widget_update_period_pref_key";
33 | public static final String PREF_LANGUAGE = "language_pref_key";
34 | public static final String PREF_THEME = "theme_pref_key";
35 |
36 | /**
37 | * About preference screen constants
38 | */
39 | public static final String KEY_PREF_ABOUT_VERSION = "about_version_pref_key";
40 | public static final String KEY_PREF_ABOUT_F_DROID = "about_f_droid_pref_key";
41 | public static final String KEY_PREF_ABOUT_GOOGLE_PLAY = "about_google_play_pref_key";
42 | public static final String KEY_PREF_ABOUT_OPEN_SOURCE_LICENSES =
43 | "about_open_source_licenses_pref_key";
44 |
45 | public static final String WEATHER_DATA_TEMPERATURE = "temperature";
46 | public static final String WEATHER_DATA_DESCRIPTION = "description";
47 | public static final String WEATHER_DATA_PRESSURE = "pressure";
48 | public static final String WEATHER_DATA_HUMIDITY = "humidity";
49 | public static final String WEATHER_DATA_WIND_SPEED = "wind_speed";
50 | public static final String WEATHER_DATA_CLOUDS = "clouds";
51 | public static final String WEATHER_DATA_ICON = "icon";
52 | public static final String WEATHER_DATA_SUNRISE = "sunrise";
53 | public static final String WEATHER_DATA_SUNSET = "sunset";
54 |
55 | /**
56 | * Widget action constants
57 | */
58 | public static final String ACTION_FORCED_APPWIDGET_UPDATE =
59 | "org.asdtm.goodweather.action.FORCED_APPWIDGET_UPDATE";
60 | public static final String ACTION_APPWIDGET_THEME_CHANGED =
61 | "org.asdtm.goodweather.action.APPWIDGET_THEME_CHANGED";
62 | public static final String ACTION_APPWIDGET_UPDATE_PERIOD_CHANGED =
63 | "org.asdtm.goodweather.action.APPWIDGET_UPDATE_PERIOD_CHANGED";
64 |
65 | /**
66 | * URIs constants
67 | */
68 | public static final String SOURCE_CODE_URI = "https://github.com/qqq3/good-weather";
69 | public static final String GOOGLE_PLAY_APP_URI = "market://details?id=%s";
70 | public static final String GOOGLE_PLAY_WEB_URI =
71 | "http://play.google.com/store/apps/details?id=%s";
72 | public static final String F_DROID_WEB_URI = "https://f-droid.org/repository/browse/?fdid=%s";
73 | public static final String WEATHER_ENDPOINT = "http://api.openweathermap.org/data/2.5/weather";
74 | public static final String WEATHER_FORECAST_ENDPOINT = "http://api.openweathermap.org/data/2.5/forecast/daily";
75 |
76 | public static final String BITCOIN_ADDRESS = "1FV8m1MKqZ9ZKB8YNwpsjsuubHTznJSiT8";
77 |
78 | public static final int PARSE_RESULT_SUCCESS = 0;
79 | public static final int TASK_RESULT_ERROR = -1;
80 | public static final int PARSE_RESULT_ERROR = -2;
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/CustomValueFormatter.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | import com.github.mikephil.charting.data.Entry;
4 | import com.github.mikephil.charting.formatter.ValueFormatter;
5 | import com.github.mikephil.charting.utils.ViewPortHandler;
6 |
7 | import java.text.DecimalFormat;
8 |
9 | public class CustomValueFormatter implements ValueFormatter {
10 |
11 | private DecimalFormat mFormat;
12 |
13 | public CustomValueFormatter() {
14 | mFormat = new DecimalFormat("#.##");
15 | }
16 |
17 | @Override
18 | public String getFormattedValue(float value, Entry entry, int dataSetIndex,
19 | ViewPortHandler viewPortHandler) {
20 | return mFormat.format(value);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/LanguageUtil.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.content.ContextWrapper;
6 | import android.content.Intent;
7 | import android.content.res.Configuration;
8 | import android.content.res.Resources;
9 | import android.os.Build;
10 | import android.text.TextUtils;
11 |
12 | import java.util.Locale;
13 |
14 | public class LanguageUtil {
15 |
16 | private static final String TAG = LanguageUtil.class.getSimpleName();
17 |
18 | @TargetApi(17)
19 | @SuppressWarnings("deprecation")
20 | public static void setLanguage(final ContextWrapper contextWrapper, String locale) {
21 | Locale sLocale;
22 | if (TextUtils.isEmpty(locale)) {
23 | sLocale = Locale.getDefault();
24 | } else {
25 | String[] localeParts = locale.split("_");
26 | if (localeParts.length > 1) {
27 | sLocale = new Locale(localeParts[0], localeParts[1]);
28 | } else {
29 | sLocale = new Locale(locale);
30 | }
31 | }
32 |
33 | Resources resources = contextWrapper.getBaseContext().getResources();
34 | Configuration configuration = resources.getConfiguration();
35 | Locale.setDefault(sLocale);
36 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
37 | configuration.setLocale(sLocale);
38 | } else {
39 | configuration.locale = sLocale;
40 | }
41 |
42 | resources.updateConfiguration(configuration, resources.getDisplayMetrics());
43 | }
44 |
45 | public static void forceChangeLanguage(Activity activity) {
46 | Intent intent = activity.getIntent();
47 | if (intent == null) {
48 | return;
49 | }
50 | intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
51 | activity.finish();
52 | activity.overridePendingTransition(0, 15);
53 | activity.startActivity(intent);
54 | activity.overridePendingTransition(0, 0);
55 | }
56 |
57 | public static String getLanguageName(String locale) {
58 | if (TextUtils.isEmpty(locale)) {
59 | locale = Locale.getDefault().toString();
60 | }
61 | if (locale.contains("_")) {
62 | return locale.split("_")[0];
63 | }
64 | return locale;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/PermissionUtil.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | import android.content.pm.PackageManager;
4 |
5 | public class PermissionUtil {
6 |
7 | public static boolean verifyPermissions(int[] grantResults) {
8 | if (grantResults.length < 1) {
9 | return false;
10 | }
11 |
12 | for (int result : grantResults) {
13 | if (result != PackageManager.PERMISSION_GRANTED) {
14 | return false;
15 | }
16 | }
17 | return true;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/PreferenceUtil.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.preference.PreferenceManager;
6 |
7 | public class PreferenceUtil {
8 |
9 | public enum Theme {
10 | light,
11 | dark,
12 | }
13 |
14 | public static SharedPreferences getDefaultSharedPrefs(Context context) {
15 | return PreferenceManager.getDefaultSharedPreferences(context);
16 | }
17 |
18 | public static String getLanguage(Context context) {
19 | return PreferenceManager.getDefaultSharedPreferences(context).getString(Constants.PREF_LANGUAGE, "en");
20 | }
21 |
22 | public static Theme getTheme(Context context) {
23 | return Theme.valueOf(PreferenceManager.getDefaultSharedPreferences(context).getString(Constants.PREF_THEME, "light"));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/XAxisValueFormatter.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | import com.github.mikephil.charting.components.AxisBase;
4 | import com.github.mikephil.charting.formatter.AxisValueFormatter;
5 |
6 | public class XAxisValueFormatter implements AxisValueFormatter {
7 |
8 | private String[] mValues;
9 |
10 | public XAxisValueFormatter(String[] dates) {
11 | mValues = dates;
12 | }
13 |
14 | @Override
15 | public String getFormattedValue(float value, AxisBase axis) {
16 | return mValues[(int) value];
17 | }
18 |
19 | @Override
20 | public int getDecimalDigits() {
21 | return 0;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/utils/YAxisValueFormatter.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.utils;
2 |
3 | import com.github.mikephil.charting.components.AxisBase;
4 | import com.github.mikephil.charting.formatter.AxisValueFormatter;
5 |
6 | import java.text.DecimalFormat;
7 |
8 | public class YAxisValueFormatter implements AxisValueFormatter {
9 |
10 | private DecimalFormat mFormat;
11 |
12 | public YAxisValueFormatter() {
13 | mFormat = new DecimalFormat("#.##");
14 | }
15 |
16 | @Override
17 | public String getFormattedValue(float value, AxisBase axis) {
18 | return mFormat.format(value);
19 | }
20 |
21 | @Override
22 | public int getDecimalDigits() {
23 | return 1;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/widget/LessWidgetService.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.widget;
2 |
3 | import android.app.IntentService;
4 | import android.appwidget.AppWidgetManager;
5 | import android.content.ComponentName;
6 | import android.content.Intent;
7 | import android.content.SharedPreferences;
8 | import android.util.Log;
9 | import android.widget.RemoteViews;
10 |
11 | import org.asdtm.goodweather.ConnectionDetector;
12 | import org.asdtm.goodweather.R;
13 | import org.asdtm.goodweather.WeatherJSONParser;
14 | import org.asdtm.goodweather.WeatherRequest;
15 | import org.asdtm.goodweather.model.Weather;
16 | import org.asdtm.goodweather.utils.AppPreference;
17 | import org.asdtm.goodweather.utils.Constants;
18 | import org.asdtm.goodweather.utils.LanguageUtil;
19 | import org.asdtm.goodweather.utils.PreferenceUtil;
20 | import org.asdtm.goodweather.utils.Utils;
21 | import org.json.JSONException;
22 |
23 | import java.io.IOException;
24 | import java.util.Locale;
25 |
26 | public class LessWidgetService extends IntentService {
27 |
28 | private static final String TAG = "UpdateLessWidgetService";
29 |
30 | public LessWidgetService() {
31 | super(TAG);
32 | }
33 |
34 | @Override
35 | protected void onHandleIntent(Intent intent) {
36 | ConnectionDetector checkNetwork = new ConnectionDetector(this);
37 | if (!checkNetwork.isNetworkAvailableAndConnected()) {
38 | return;
39 | }
40 | SharedPreferences preferences = getSharedPreferences(Constants.APP_SETTINGS_NAME, 0);
41 | String latitude = preferences.getString(Constants.APP_SETTINGS_LATITUDE, "51.51");
42 | String longitude = preferences.getString(Constants.APP_SETTINGS_LONGITUDE, "-0.13");
43 | String locale = LanguageUtil.getLanguageName(PreferenceUtil.getLanguage(this));
44 | String units = AppPreference.getTemperatureUnit(this);
45 | try {
46 | String weatherRaw = new WeatherRequest().getItems(latitude, longitude, units,
47 | locale);
48 | Weather weather;
49 | weather = WeatherJSONParser.getWeather(weatherRaw);
50 | AppPreference.saveWeather(this, weather);
51 | updateWidget(weather);
52 | } catch (IOException | JSONException e) {
53 | Log.e(TAG, "Error get weather", e);
54 | stopSelf();
55 | }
56 | }
57 |
58 | private void updateWidget(Weather weather) {
59 | AppWidgetManager widgetManager = AppWidgetManager.getInstance(this);
60 | ComponentName widgetComponent = new ComponentName(this,
61 | LessWidgetProvider.class);
62 |
63 | int[] widgetIds = widgetManager.getAppWidgetIds(widgetComponent);
64 | for (int appWidgetId : widgetIds) {
65 | RemoteViews remoteViews = new RemoteViews(this.getPackageName(),
66 | R.layout.widget_less_3x1);
67 |
68 | String iconId = weather.currentWeather.getIdIcon();
69 | String weatherIcon = Utils.getStrIcon(this, iconId);
70 | String lastUpdate = Utils.setLastUpdateTime(this, AppPreference
71 | .saveLastUpdateTimeMillis(this));
72 |
73 | String temperatureScale = Utils.getTemperatureScale(this);
74 | String temperature = String.format(Locale.getDefault(), "%.0f",
75 | weather.temperature.getTemp());
76 |
77 | remoteViews.setTextViewText(R.id.widget_temperature,
78 | temperature + temperatureScale);
79 | if(!AppPreference.hideDescription(this))
80 | remoteViews.setTextViewText(R.id.widget_description,
81 | weather.currentWeather.getDescription());
82 | else remoteViews.setTextViewText(R.id.widget_description, " ");
83 | remoteViews.setTextViewText(R.id.widget_city, Utils.getCityAndCountry(this));
84 | remoteViews.setTextViewText(R.id.widget_last_update, lastUpdate);
85 | remoteViews.setImageViewBitmap(R.id.widget_icon,
86 | Utils.createWeatherIcon(this, weatherIcon));
87 |
88 | widgetManager.updateAppWidget(appWidgetId, remoteViews);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/main/java/org/asdtm/goodweather/widget/MoreWidgetService.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather.widget;
2 |
3 | import android.app.IntentService;
4 | import android.appwidget.AppWidgetManager;
5 | import android.content.ComponentName;
6 | import android.content.Intent;
7 | import android.content.SharedPreferences;
8 | import android.util.Log;
9 | import android.widget.RemoteViews;
10 | import java.io.BufferedWriter;
11 | import java.io.File;
12 | import java.io.FileWriter;
13 |
14 | import org.asdtm.goodweather.ConnectionDetector;
15 | import org.asdtm.goodweather.R;
16 | import org.asdtm.goodweather.WeatherJSONParser;
17 | import org.asdtm.goodweather.WeatherRequest;
18 | import org.asdtm.goodweather.model.Weather;
19 | import org.asdtm.goodweather.utils.AppPreference;
20 | import org.asdtm.goodweather.utils.Constants;
21 | import org.asdtm.goodweather.utils.LanguageUtil;
22 | import org.asdtm.goodweather.utils.PreferenceUtil;
23 | import org.asdtm.goodweather.utils.Utils;
24 | import org.json.JSONException;
25 |
26 | import java.io.IOException;
27 | import java.util.Locale;
28 |
29 | public class MoreWidgetService extends IntentService {
30 |
31 | private static final String TAG = "UpdateMoreWidgetService";
32 |
33 | public MoreWidgetService() {
34 | super(TAG);
35 | }
36 |
37 | @Override
38 | protected void onHandleIntent(Intent intent) {
39 | ConnectionDetector checkNetwork = new ConnectionDetector(this);
40 | if (!checkNetwork.isNetworkAvailableAndConnected()) {
41 | return;
42 | }
43 |
44 | SharedPreferences preferences = getSharedPreferences(Constants.APP_SETTINGS_NAME, 0);
45 | String latitude = preferences.getString(Constants.APP_SETTINGS_LATITUDE, "51.51");
46 | String longitude = preferences.getString(Constants.APP_SETTINGS_LONGITUDE, "-0.13");
47 | String locale = LanguageUtil.getLanguageName(PreferenceUtil.getLanguage(this));
48 | String units = AppPreference.getTemperatureUnit(this);
49 |
50 | try {
51 | String weatherRaw = new WeatherRequest().getItems(latitude, longitude, units,
52 | locale);
53 | Weather weather;
54 | weather = WeatherJSONParser.getWeather(weatherRaw);
55 | AppPreference.saveWeather(this, weather);
56 | updateWidget(weather);
57 | } catch (IOException | JSONException e) {
58 | Log.e(TAG, "Error get weather", e);
59 | stopSelf();
60 | }
61 | }
62 |
63 | private void updateWidget(Weather weather) {
64 | AppWidgetManager widgetManager = AppWidgetManager.getInstance(this);
65 | ComponentName widgetComponent = new ComponentName(this, MoreWidgetProvider.class);
66 |
67 | int[] widgetIds = widgetManager.getAppWidgetIds(widgetComponent);
68 | for (int appWidgetId : widgetIds) {
69 | String temperatureScale = Utils.getTemperatureScale(this);
70 | String speedScale = Utils.getSpeedScale(this);
71 | String percentSign = getString(R.string.percent_sign);
72 | String pressureMeasurement = getString(R.string.pressure_measurement);
73 |
74 | String temperature = String.format(Locale.getDefault(), "%.0f",
75 | weather.temperature.getTemp());
76 | String wind = getString(R.string.wind_label, String.format(Locale.getDefault(),
77 | "%.1f",
78 | weather.wind.getSpeed()),
79 | speedScale);
80 | String humidity = getString(R.string.humidity_label,
81 | String.valueOf(weather.currentCondition.getHumidity()),
82 | percentSign);
83 | String pressure = getString(R.string.pressure_label,
84 | String.format(Locale.getDefault(), "%.1f",
85 | weather.currentCondition.getPressure()),
86 | pressureMeasurement);
87 | String cloudiness = getString(R.string.cloudiness_label,
88 | String.valueOf(weather.cloud.getClouds()),
89 | percentSign);
90 | String iconId = weather.currentWeather.getIdIcon();
91 | String weatherIcon = Utils.getStrIcon(this, iconId);
92 | String lastUpdate = Utils.setLastUpdateTime(this, AppPreference
93 | .saveLastUpdateTimeMillis(this));
94 |
95 | RemoteViews remoteViews = new RemoteViews(this.getPackageName(),
96 | R.layout.widget_more_3x3);
97 | remoteViews.setTextViewText(R.id.widget_city, Utils.getCityAndCountry(this));
98 | remoteViews.setTextViewText(R.id.widget_temperature, temperature + temperatureScale);
99 | if(!AppPreference.hideDescription(this))
100 | remoteViews.setTextViewText(R.id.widget_description,
101 | weather.currentWeather.getDescription());
102 | else remoteViews.setTextViewText(R.id.widget_description, " ");
103 | remoteViews.setTextViewText(R.id.widget_wind, wind);
104 | remoteViews.setTextViewText(R.id.widget_humidity, humidity);
105 | remoteViews.setTextViewText(R.id.widget_pressure, pressure);
106 | remoteViews.setTextViewText(R.id.widget_clouds, cloudiness);
107 | remoteViews.setImageViewBitmap(R.id.widget_icon,
108 | Utils.createWeatherIcon(this, weatherIcon));
109 | remoteViews.setTextViewText(R.id.widget_last_update, lastUpdate);
110 |
111 | widgetManager.updateAppWidget(appWidgetId, remoteViews);
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/background_nav_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/background_nav_header.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_barometer_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_barometer_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_current_weather_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_current_weather_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_daily_forecast_dark_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_daily_forecast_dark_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_feedback.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_graphs_black_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_graphs_black_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_humidity_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_humidity_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_menu_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_my_location_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_my_location_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_rain_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_rain_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_refresh_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_refresh_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_refresh_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_snow_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_snow_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_thumb_up_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_thumb_up_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_wind_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/ic_wind_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/small_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-hdpi/small_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/background_nav_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/background_nav_header.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_barometer_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_barometer_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_current_weather_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_current_weather_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_daily_forecast_dark_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_daily_forecast_dark_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_feedback.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_graphs_black_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_graphs_black_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_humidity_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_humidity_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_menu_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_my_location_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_my_location_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_rain_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_rain_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_refresh_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_refresh_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_refresh_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_snow_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_snow_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_thumb_up_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_thumb_up_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_wind_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/ic_wind_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/small_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-mdpi/small_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/background_appbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-nodpi/background_appbar.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/preview_less_widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-nodpi/preview_less_widget.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-nodpi/preview_more_widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-nodpi/preview_more_widget.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/background_nav_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/background_nav_header.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bitcoin_address_qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/bitcoin_address_qr.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_barometer_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_barometer_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_current_weather_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_current_weather_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_daily_forecast_dark_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_daily_forecast_dark_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_feedback.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_graphs_black_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_graphs_black_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_humidity_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_humidity_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_menu_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_my_location_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_my_location_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_rain_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_rain_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_refresh_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_refresh_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_refresh_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_refresh_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_snow_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_snow_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_thumb_up_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_thumb_up_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_wind_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/ic_wind_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/small_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xhdpi/small_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/background_nav_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/background_nav_header.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_barometer_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_barometer_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_current_weather_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_current_weather_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_daily_forecast_dark_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_daily_forecast_dark_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_feedback.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_graphs_black_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_graphs_black_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_humidity_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_humidity_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_menu_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_my_location_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_my_location_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_rain_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_rain_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_refresh_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_refresh_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_refresh_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_snow_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_snow_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_thumb_up_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_thumb_up_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_wind_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/ic_wind_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/small_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxhdpi/small_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/background_nav_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/background_nav_header.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_current_weather_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_current_weather_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_daily_forecast_dark_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_daily_forecast_dark_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_feedback.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_menu_settings.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_my_location_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_my_location_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_rain_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_rain_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_refresh_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_refresh_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_refresh_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_snow_light_32dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_snow_light_32dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_thumb_up_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/ic_thumb_up_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/small_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/drawable-xxxhdpi/small_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_android_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_share.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_license.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
20 |
21 |
22 |
23 |
30 |
31 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
15 |
16 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
26 |
27 |
33 |
34 |
35 |
36 |
37 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_weather_forecast.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
21 |
22 |
29 |
30 |
31 |
32 |
39 |
40 |
41 |
47 |
48 |
49 |
57 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/city_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_donation_bitcoin.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
27 |
28 |
33 |
34 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/forecast_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
24 |
25 |
30 |
31 |
41 |
42 |
50 |
51 |
66 |
67 |
68 |
77 |
78 |
79 |
89 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_less_3x1.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
29 |
30 |
39 |
40 |
51 |
52 |
53 |
59 |
60 |
70 |
71 |
79 |
80 |
88 |
89 |
90 |
97 |
98 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_more_3x3.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
29 |
30 |
38 |
39 |
50 |
51 |
52 |
62 |
63 |
68 |
69 |
76 |
77 |
84 |
85 |
92 |
93 |
100 |
101 |
108 |
109 |
116 |
117 |
118 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/draw_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_graphs.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/search.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/weather_forecast_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-ar/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | أدخل اسم المدينة
4 | المدينة الحالية
5 | اختر المدينة
6 | نظام التموضع العالمي غير مفعل. هل تريد أن تذهب إلى قائمة الإعدادات؟
7 | الإعدادات
8 | إلغاء
9 | البحث عن الموقع الحالي
10 | جار التحميل…
11 | بحث عن مكان
12 | الطقس الحالي
13 | توقعات يومية
14 | الرسوم البيانية للطقس
15 | ترخيص لـ %s
16 | تحديث
17 | ابحث عن مدينة
18 | تحديد الموقع
19 | تبديل القيم
20 | الطقس الحالي
21 | توقعات يومية
22 | الرسوم البيانية
23 | إعدادات
24 | ردود الفعل
25 | تبرع بيتكوين
26 | تحقق من اتصالك بالإنترنت
27 | حدث خطأ. حاول لاحقا!
28 | هكتوبسكال
29 | الإعدادات
30 | الحرارة
31 | إشعارات
32 | تفعيل الإشعارات
33 | 15 دقيقة
34 | 30 دقيقة
35 | كل ساعة
36 | 3 ساعات
37 | 6 ساعات
38 | 12 ساعة
39 | 24 ساعة
40 | الإعدادات العامة
41 | شفاف
42 | عرض
43 | اللغة
44 | القالب
45 | شفرة المصدر
46 | الترخيص
47 | تراخيص مفتوحة المصدر
48 | الحرارة
49 | الرياح
50 | أمطار
51 | ثلوج
52 | حول التطبيق
53 | الصباح
54 | يوم
55 | المساء
56 | الليل
57 | شمال
58 | شمال شرق
59 | الشرق
60 | جنوب شرق
61 | الجنوب
62 | جنوب غرب
63 | الغرب
64 | شمال غرب
65 | الرجاء إعادة تشغيل التطبيق قصد تطبيق الإعدادات الجديدة
66 | متر في الثانية
67 | ميل في الساعة
68 | ميليمتر
69 | ابحث عن مكان
70 | إخفاء وصف الطقس
71 | تحديث الفاصل الزمني
72 | اهتزاز
73 | فترة التحديث
74 | تحديث الموقع
75 | استخدام تحديد الموقع الجغرافي للعرض
76 | داكن
77 | فاتح
78 | النظام الافتراضي
79 | الإصدار
80 | الرياح: %1$s %2$s
81 | المطر: %1$s %2$s
82 | الثلج: %1$s %2$s
83 | الرطوبة: %1$s%2$s
84 | الضغط: %1$s %2$s
85 | السحاب: %1$s%2$s
86 | آخر تحديث: %s
87 | الشروق: %s
88 | الغروب: %s
89 | أيقونة الطقس الحالية
90 | تغيير محور الاحداتياث
91 | اعدادات الويدجيت
92 | ثيم الويدجيت
93 | زر تحديث الويدجيت
94 | التبرع بيتكوين رمز الاستجابة السريعة
95 | قم بنسخ عنوان Bitcoin
96 | افتح تطبيق Bitcoin
97 | تم نسخ عنوان Bitcoin إلى الحافظة
98 | مطلوب أذونات الموقع لتحديد المدينة الحالية
99 | لم يتم منح أذونات الموقع!
100 | تم منح أذونات الموقع
101 | يجب عليك منح أذونات الحصول على الموقع
102 |
--------------------------------------------------------------------------------
/app/src/main/res/values-hi/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | शहर चुनें
4 | शहर का नाम दर्ज करें
5 | २४ घंटे
6 | तापमान
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-pa/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | m/s
4 | ਰੱਦ ਕਰੋ
5 | ਮੌਜੂਦਾ ਟਿਕਾਣਾ ਲੱਭੋ
6 | ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…
7 | ਟਿਕਾਣਾ ਲੱਭੋ
8 | ਮੌਜੂਦਾ ਮੌਸਮ
9 | ਰੋਜ਼ਾਨਾ ਦੀ ਭਵਿੱਖਬਾਣੀ
10 | ਮੌਸਮੀ ਗਰਾਫ਼
11 | %s ਲਈ ਲਸੰਸ
12 | ਅੱਪਡੇਟ
13 | ਸ਼ਹਿਰ ਲੱਭੋ
14 | ਟਿਕਾਣਾ ਖੋਜੋ
15 | ਮੁੱਲ ਬਦਲੋ
16 | Y-ਧੁਰਾ ਬਦਲੋ
17 | ਮੌਜੂਦਾ ਮੌਸਮ
18 | ਰੋਜ਼ਾਨਾ ਦੀ ਭਵਿੱਖਬਾਣੀ
19 | ਬਿੱਟਕੁਆਇੰਨ ਦਾਨ ਕਰੋ
20 | ਗਲਤੀ ਆਈ ਹੈ। ਬਾਅਦ \'ਚ ਕੋਸ਼ਿਸ਼ ਕਰੋ!
21 | ਮੀ.ਪ੍ਰਤੀ ਘੰ.
22 | ਮਿ.ਮੀ.
23 | ਨੋਟੀਫਿਕੇਸ਼ਨ
24 | 15 ਮਿੰਟ
25 | 12 ਘੰਟੇ
26 | 24 ਘੰਟੇ
27 | ਕੰਪਨ
28 | ਟਿਕਾਣਾ ਅੱਪਡੇਟ ਕਰੋ
29 | ਗੂੜ੍ਹਾ
30 | ਹਲਕਾ
31 | ਪਾਰਦਰਸ਼ੀ
32 | ਡਿਸਪਲੇਅ
33 | ਭਾਸ਼ਾ
34 | ਸਿਸਟਮ ਦਾ ਮੂਲ
35 | ਥੀਮ
36 | ਇਸ ਬਾਰੇ
37 | ਵਰਜ਼ਨ
38 | ਸਰੋਤ ਕੋਡ
39 | ਲਸੰਸ
40 | ਆਜ਼ਾਦ ਸਰੋਤ ਲਸੰਸ
41 | ਹਵਾ: %1$s %2$s
42 | ਮੀਂਹ: %1$s %2$s
43 | ਬਰਫ਼ਬਾਰੀ: %1$s %2$s
44 | ਹੁੰਮਸ: %1$s%2$s
45 | ਦਬਾਓ: %1$s %2$s
46 | ਬੱਦਲਵਾਈ: %1$s%2$s
47 | ਆਖਰੀ ਅੱਪਡੇਟ: %s
48 | ਸੂਰਜ ਡੁੱਬਣਾ: %s
49 | ਦਿਨ
50 | ਆਥਣ
51 | ਰਾਤ
52 | ਤਾਪਮਾਨ
53 | ਤੇਜ਼ ਹਵਾ
54 | ਮੀਂਹ
55 | ਬਰਫ਼
56 | ਮੌਜੂਦਾ ਮੌਸਮੀ ਆਈਕਾਨ
57 | ਵਿਜੈਟ ਤਾਜ਼ਾ ਕਰਨ ਦਾ ਬਟਨ
58 | ਦਾਨ ਵਾਲਾ ਬਿੱਟਕੁਆਇਨ QR ਕੋਡ
59 | ਬਿੱਟਕੁਆਇਨ ਐਡਰੈਸ ਕਾਪੀ ਕਰੋ
60 | ਬਿੱਟਕੁਆਇੰਨ ਸਿਰਾਨਵਾਂ ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ ਕਾਪੀ ਕੀਤਾ ਗਿਆ ਸੀ
61 | ਦੱ-ਪੂ
62 | ਦੱ
63 | ਦੱ-ਪੱ
64 | ਗਰਾਫ਼
65 | ਸੈਟਿੰਗਾਂ
66 | ਪੱ
67 | ਸੈਟਿੰਗਾਂ
68 | ਅੱਪਡੇਟ ਦਾ ਅੰਤਰਾਲ
69 | ਉ
70 | ਉ-ਪੂ
71 | ਪੂ
72 | ਉ-ਪੱ
73 | ਮੌਜੂਦਾ ਸ਼ਹਿਰ ਦਾ ਪਤਾ ਲਗਾਉਣ ਲਈ ਟਿਕਾਣੇ ਲਈ ਇਜਾਜ਼ਤ ਚਾਹੀਦੀ ਹੈ
74 | ਇਜਾਜ਼ਤਾਂ ਨਹੀਂ ਦਿੱਤੀਆਂ ਗਈਆਂ ਹਨ!
75 | ਟਿਕਾਣਾ ਇਜਾਜ਼ਤਾਂ ਦਿੱਤੀਆਂ ਗਈਆਂ ਹਨ
76 | ਤੁਹਾਨੂੰ ਟਿਕਾਣਾ ਇਜਾਜ਼ਤਾਂ ਦੇਣੀਆਂ ਚਾਹੀਦੀਆਂ ਹਨ
77 | ਨਵੀਆਂ ਸੈਟਿੰਗਾਂ ਲਾਗੂ ਕਰਨ ਲਈ ਐਪਲੀਕੇਸ਼ਨ ਮੁੜ-ਚਾਲੂ ਕਰੋ
78 | GPS ਸਮਰੱਥ ਨਹੀਂ ਹੈ। ਕੀ ਤੁਸੀਂ ਸੈਟਿੰਗਾਂ ਮੇਨੂ ਉੱਤੇ ਜਾਣਾ ਚਾਹੁੰਦੇ ਹੋ\?
79 | ਸ਼ਹਿਰ ਦਿਓ
80 | ਸ਼ਹਿਰ ਚੁਣੋ
81 | ਸੈਟਿੰਗਾਂ
82 | ਸੁਝਾਅ
83 | ਟਿਕਾਣਾ ਲੱਭੋ
84 | ਟਿਕਾਣਾ ਵੇਰਵਾ ਲੁਕਾਓ
85 | ਨੋਟੀਫਿਕੇਸ਼ਨ ਸਮਰੱਥ ਕਰੋ
86 | ਤਾਜ਼ਾ ਕਰਨ ਦਾ ਅੰਤਰਾਲ
87 | 3 ਘੰਟੇ
88 | ਆਪਣੇ ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਦੀ ਜਾਂਚ ਕਰੋ
89 | hPa
90 | ਤਾਪਮਾਨ
91 | 30 ਮਿੰਟ
92 | ਹਰ ਘੰਟੇ
93 | ਵਿਜੈੱਟ ਸੈਟਿੰਗਾਂ
94 | ਦਿਖਾਉਣ ਲਈ ਭੂਗੋਲਿਕ-ਟਿਕਾਣਾ ਵਰਤੋ
95 | ਵਿਜੈਟ ਥੀਮ
96 | 6 ਘੰਟੇ
97 | ਆਮ ਸੈਟਿੰਗਾਂ
98 | ਸੂਰਜ ਚੜ੍ਹਨਾ: %s
99 | ਸਵੇਰ
100 | ਬਿੱਟਕੁਆਇੰਨ ਐਪ ਖੋਲ੍ਹੋ
101 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ps/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | د ښوولو لپاره جيولوکېشن کارول
4 | لړزه
5 | تاندونې لارغه
6 | د y څاښ ونجول
7 | ارزښتونه ونجول
8 | لېرې کول
9 | مهرباني وکړئ، د نويو امستنو د کارونګه کولو لپاره کاریال بیاپیل کړئ
10 | تاسې د ځای پرېښلې هرومرو باید ور کړئ
11 | د ځای پرېښلې ور کړل شوې
12 | پرېښلې ور نه کړل شوې!
13 | د اوسني ښار موندلو لپاره د ځای پرېښلو ته اړتیا ده
14 | سويل لوېديځ
15 | شمال لوېديځ
16 | لوېديځ
17 | سويل ختيځ
18 | شمال ختيځ
19 | سويل
20 | ختيځ
21 | شمال
22 | د بېټکوېن پته ټوټه دړې ته ولمېسل شوه
23 | بېټکوېن کاریال پرانېستل
24 | بېټکوېن پته لمېسل
25 | د بېټکوېن کيو.آر کوډ
26 | د کارووني تاندولو تڼۍ
27 | د اوبه هوا اوسنی انځورن
28 | واوره
29 | باران
30 | باد
31 | تودوخه
32 | شپه
33 | ماښام
34 | ورځ
35 | سهار
36 | لمرڅرک: %s
37 | لمرلوېدن: %s
38 | وروستي ځل اوسمهالول شوې وه په %s
39 | ورېځ: %1$s %2$s
40 | فشار: %1$s %2$s
41 | لندبل: %1$s%2$s
42 | واوره: %1$s %2$s
43 | باران: %1$s %2$s
44 | باد: %1$s %2$s
45 | د ازادې سرچينې منښتلیکونه
46 | هوکليک
47 | سرچينې کوډ
48 | بڼه
49 | په اړه
50 | ويینه
51 | د غونډال تلواله ژبه
52 | ژبه
53 | ښوونه
54 | روڼ
55 | رڼا
56 | تياره
57 | د کارووني ويينه
58 | ځای اوسمهالول
59 | د کارووني امستنې
60 | ټوليزې امستنې
61 | اوسمهالونې پېر
62 | ۲۴ ساته
63 | ۱۲ ساته
64 | ۶ ساته
65 | ٣ ساته
66 | هر سات
67 | ۳۰ پېله
68 | ۱۵ پېله
69 | یادښتونه چارنده کول
70 | یادښتونه
71 | د اوبه هوا سپړاوى پټول
72 | تودوخه
73 | امستنې
74 | ځای پلټل
75 | ميليميټره
76 | ميله په سات کښې
77 | ميټره په رپ کښې
78 | هېکټوپاسکله
79 | یوه تېروتنه پېښه شوه. وروسته هڅه وکړئ!
80 | خپل د انټرنېټ پیوستون مو وګورئ
81 | بېټکوېن بسپنه کړئ
82 | كتنې
83 | امستنې
84 | كښنې
85 | هرورځنۍ مخويني
86 | اوسنۍ اوبه هوا
87 | ځای موندل
88 | ښار پلټل
89 | اوسمهالول
90 | د %s لپاره هوکليک
91 | کښنيزه اوبه هوا
92 | هرورځنۍ مخويني
93 | اوسنۍ اوبه هوا
94 | ځای پلټل
95 | لېښل کېږي…
96 | اوسنی ځای موندل
97 | امستنې
98 | نړیوال ځايونګ غونډال (GPS) چارندول شوی نه دی. غواړئ چې د امستنو غورنۍ ته لاړ شئ؟
99 | ښار ټاکل
100 | ښار مو دننه کړئ
101 |
--------------------------------------------------------------------------------
/app/src/main/res/values-si/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | සැකසුම්
4 | නගරය තෝරන්න
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 | 42sp
7 |
8 |
9 | 20sp
10 | 16dp
11 |
12 | 32dp
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 输入城市
4 | 当前城市
5 | 请选择城市
6 | GPS未开启。是否转到菜单设置?
7 | 设置
8 | 取消
9 | 查找当前位置
10 | 正在加载…
11 | 搜索位置
12 | 当前天气
13 | 每日预报
14 | 天气图
15 | %s 的许可证
16 | 更新
17 | 搜索城市
18 | 检测位置
19 | 切换值
20 | 切换 Y 轴
21 | 当前天气
22 | 每日预报
23 | 图
24 | 设置
25 | 反馈
26 | 捐出比特币
27 | 请检查您的互联网连接
28 | 发生错误。请重试!
29 | 百帕
30 | m/s
31 | 英里/小时
32 | 毫米
33 | 搜索位置
34 | 设置
35 | 温度
36 | 隐藏的天气描述
37 | 通知
38 | 启用通知
39 | 刷新间隔
40 | 15 分钟
41 | 30 分钟
42 | 每小时
43 | 3 小时
44 | 6 小时
45 | 12小时
46 | 24 小时
47 | 震动
48 | 更新周期
49 | 常规设置
50 | 小部件设置
51 | 更新位置
52 | 使用地理位置显示
53 | 小部件主题
54 | 黑暗
55 | 明亮
56 | 透明
57 | 显示
58 | 语言
59 | 系统默认
60 | 主题
61 | 关于
62 | 版本
63 | 源代码
64 | 许可证
65 | 开源许可证
66 | 风: %1$s %2$s
67 | 雨: %1$s %2$s
68 | 雪: %1$s %2$s
69 | 湿度: %1$s%2$s
70 | 气压:%1$s %2$s
71 | 云量: %1$s %2$s
72 | 最后更新: %s
73 | 日出: %s
74 | 日落: %s
75 | 早上
76 | 天
77 | 傍晚
78 | 晚上
79 | 温度
80 | 风
81 | 雨
82 | 雪
83 | 当前天气图标
84 | 小部件刷新按钮
85 | 捐赠比特币的二维码
86 | 复制比特币地址
87 | 打开比特币应用程序
88 | 比特币地址已经复制到剪贴板
89 | 北
90 | 东北
91 | 东
92 | 东南
93 | 南
94 | 西南
95 | 西
96 | 西北
97 | 确定当前的城市需要位置权限
98 | 未授予权限 !
99 | 位置权限
100 | 你必须授予位置权限
101 | 请重新启动应用程序以应用新的设置
102 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh-rTW/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 輸入城市
4 | 選擇城市
5 | GPS 未啟用。你想前往設定選單嗎?
6 | 設定
7 | 取消
8 | 尋找目前位置
9 | 載入中…
10 | 搜尋地點
11 | 目前天氣
12 | 每日預報
13 | 天氣圖
14 | 更新
15 | 搜尋城市
16 | 切換 Y 軸
17 | 目前天氣
18 | 每日預報
19 | 設定
20 | 意見反映
21 | 捐贈比特幣
22 | 檢查你的網路連接
23 | 發生了錯誤。稍後再試!
24 | 米/秒
25 | 英里/小時
26 | 毫米
27 | 搜尋地點
28 | 設定
29 | 溫度
30 | 隱藏天氣描述
31 | 重新整理間隔
32 | 15 分鐘
33 | 30 分鐘
34 | 每小時
35 | 3 小時
36 | 6 小時
37 | 12 小時
38 | 24 小時
39 | 震動
40 | 常規設定
41 | 小工具設定
42 | 淺色
43 | 透明
44 | 顯示
45 | 語言
46 | 系統預設
47 | 主題
48 | 關於
49 | 版本
50 | 原始碼
51 | 許可證
52 | 開源許可證
53 | 風:%1$s %2$s
54 | 雨:%1$s %2$s
55 | 雪:%1$s %2$s
56 | 濕度:%1$s %2$s
57 | 氣壓:%1$s %2$s
58 | 雲量:%1$s %2$s
59 | 最後更新:%s
60 | 日落:%s
61 | 早上
62 | 晚上
63 | 百帕
64 | 偵測位置
65 | 通知
66 | 啟用通知
67 | 日出:%s
68 | 更新週期
69 | 更新位置
70 | 使用地理位置進行顯示
71 | 小工具主題
72 | 深色
73 | 風
74 | 溫度
75 | 雨
76 | %s 的許可證
77 | 切換值
78 | 圖表
79 | 天
80 | 傍晚
81 | 雪
82 | 目前天氣圖示
83 | 小工具重新整理按鈕
84 | 捐贈比特幣 QR 圖碼
85 | 複製比特幣地址
86 | 開啟比特幣應用程式
87 | 北
88 | 西
89 | 西北
90 | 需要位置權限來判斷目前城市
91 | 沒有授予權限!
92 | 已授予位置權限
93 | 你必須授予位置權限
94 | 請重新啟動應用程式以套用新設定
95 | 比特幣地址已複製至剪貼簿
96 | 東北
97 | 東南
98 | 東
99 | 南
100 | 西南
101 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - °C
5 | - °F
6 |
7 |
8 | - metric
9 | - imperial
10 |
11 |
12 |
13 | - @string/update_period_15min
14 | - @string/update_period_30min
15 | - @string/update_period_1hour
16 | - @string/update_period_3hours
17 | - @string/update_period_6hours
18 | - @string/update_period_12hours
19 | - @string/update_period_24hours
20 |
21 |
22 | - 15
23 | - 30
24 | - 60
25 | - 180
26 | - 360
27 | - 720
28 | - 1440
29 |
30 |
31 |
32 | - @string/update_period_15min
33 | - @string/update_period_30min
34 | - @string/update_period_1hour
35 | - @string/update_period_3hours
36 | - @string/update_period_6hours
37 | - @string/update_period_12hours
38 | - @string/update_period_24hours
39 |
40 |
41 | - 15
42 | - 30
43 | - 60
44 | - 180
45 | - 360
46 | - 720
47 | - 1440
48 |
49 |
50 |
51 | - @string/theme_dark
52 | - @string/theme_light
53 | - @string/theme_transparent
54 |
55 |
56 | - dark
57 | - light
58 | - transparent
59 |
60 |
61 |
62 |
63 | - @string/wind_direction_north
64 | - @string/wind_direction_north_east
65 | - @string/wind_direction_east
66 | - @string/wind_direction_south_east
67 | - @string/wind_direction_south
68 | - @string/wind_direction_south_west
69 | - @string/wind_direction_west
70 | - @string/wind_direction_north_west
71 |
72 |
73 | -
74 | -
75 | -
76 | -
77 | -
78 | -
79 | -
80 | -
81 |
82 |
83 |
84 |
85 | - @string/pref_language_default
86 | - English
87 | - Euskara (Basque)
88 | - Беларуская (Belarusian)
89 | - Català (Catalan)
90 | - Čeština (Czech)
91 | - Français (French)
92 | - Italiano (Italian)
93 | - Deutsch (German)
94 | - Español (Spanish)
95 | - 日本語 (Japanese)
96 | - Polski (Polish)
97 | - Русский (Russian)
98 | - Türkçe (Turkish)
99 |
100 |
101 |
102 | - en
103 | - eu
104 | - be
105 | - ca
106 | - cs
107 | - fr
108 | - it
109 | - de
110 | - es
111 | - ja
112 | - pl
113 | - ru
114 | - tr
115 |
116 |
117 |
118 |
119 | - @string/theme_light
120 | - @string/theme_dark
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #009688
4 | #007065
5 | #FFFFFF
6 | #d4d4d4
7 | #de454e
8 | #d84315
9 | #4db6ac
10 | #df5e65
11 | #42c25e
12 | #4447da
13 | #302c2c
14 | #000000
15 | #ccc
16 | #0000FF
17 |
18 | #fa202020
19 | #FFFFFF
20 | #009688
21 |
22 | #f5e7e7e7
23 | #000000
24 | #009688
25 |
26 | #00e7e7e7
27 | #FFFFFF
28 | #00e7e7e7
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 30dp
6 | 14sp
7 |
8 |
9 | 20sp
10 | 4dp
11 |
12 | 8dp
13 | 8dp
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/licenses.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Gson
5 | (license)\n
6 |
7 | JEEP TRAIL IN LAKE CITY
8 | (license)\n
9 |
10 | MPAndroidChart
11 | (license)\n
12 |
13 | OpenWeatherMap
14 | (license)\n
15 |
16 | Roboto
17 | (license)\n
18 |
19 | Weather Icons
20 | (license)
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/nontranslatable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - light
5 | - dark
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
20 |
21 |
23 |
24 |
26 |
27 |
30 |
31 |
34 |
35 |
40 |
41 |
51 |
52 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
10 |
13 |
14 |
18 |
21 |
22 |
26 |
30 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_general.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
14 |
17 |
23 |
29 |
30 |
33 |
37 |
45 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_headers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_widget.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
18 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/searchable.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/widget_provider_less.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/widget_provider_more.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/test/java/org/asdtm/goodweather/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package org.asdtm.goodweather;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest
11 | {
12 | @Test
13 | public void addition_isCorrect() throws Exception
14 | {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.1'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | maven { url "https://jitpack.io" }
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
25 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | org.gradle.parallel=true
19 | org.gradle.daemon=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqq3/good-weather/9356148c362aa9cc4a2a7d7c5acff64697a59f89/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Mar 03 15:30:50 MSK 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------