├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENSE
├── README.md
├── README_CN.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── tech
│ │ └── nicesky
│ │ └── dailyimage
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── tech
│ │ │ └── nicesky
│ │ │ └── dailyimage
│ │ │ ├── App.java
│ │ │ ├── Constants.java
│ │ │ ├── MainActivity.java
│ │ │ ├── bean
│ │ │ ├── Origin.java
│ │ │ └── PoetryData.java
│ │ │ ├── http
│ │ │ ├── HttpEntity.java
│ │ │ └── JsonConverter.java
│ │ │ ├── util
│ │ │ ├── ChinaDate.java
│ │ │ └── StringUtils.java
│ │ │ └── widget
│ │ │ ├── DailyImageProvider.java
│ │ │ ├── DailyImageProviderLarge.java
│ │ │ └── DailyImageService.java
│ └── res
│ │ ├── drawable-v21
│ │ ├── ic_menu_camera.xml
│ │ ├── ic_menu_gallery.xml
│ │ ├── ic_menu_manage.xml
│ │ ├── ic_menu_send.xml
│ │ ├── ic_menu_share.xml
│ │ └── ic_menu_slideshow.xml
│ │ ├── drawable
│ │ ├── bg_1.9.png
│ │ ├── bg_2.9.png
│ │ ├── preview.png
│ │ ├── progress.xml
│ │ └── side_nav_bar.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ ├── app_bar_main.xml
│ │ ├── content_main.xml
│ │ ├── layout_daily_image.xml
│ │ └── nav_header_main.xml
│ │ ├── menu
│ │ ├── activity_main_drawer.xml
│ │ └── main.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── bg_1.png
│ │ ├── bg_2.png
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── values-v21
│ │ └── styles.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── drawables.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ ├── app_widget_provider_info.xml
│ │ └── app_widget_provider_info_large.xml
│ └── test
│ └── java
│ └── tech
│ └── nicesky
│ └── dailyimage
│ └── ExampleUnitTest.java
├── build.gradle
├── config.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── release
├── DailyImageWidget_1.0.0.apk
├── DailyImageWidget_1.0.1.apk
└── release
│ └── output.json
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | # *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # IntelliJ
36 | *.iml
37 | .idea/workspace.xml
38 | .idea/tasks.xml
39 | .idea/gradle.xml
40 | .idea/assetWizardSettings.xml
41 | .idea/dictionaries
42 | .idea/libraries
43 | .idea/caches
44 |
45 | # Keystore files
46 | # Uncomment the following line if you do not want to check your keystore files in.
47 | #*.jks
48 |
49 | # External native build folder generated in Android Studio 2.2 and later
50 | .externalNativeBuild
51 |
52 | # Google Services (e.g. APIs or Firebase)
53 | google-services.json
54 |
55 | # Freeline
56 | freeline.py
57 | freeline/
58 | freeline_project_description.json
59 |
60 | # fastlane
61 | fastlane/report.xml
62 | fastlane/Preview.html
63 | fastlane/screenshots
64 | fastlane/test_output
65 | fastlane/readme.md
66 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # DailyImageWidget
3 | > Android 桌面小部件(widget)日签 Or 日历,可作为桌面日历。Just For Fun! :video_game:
4 |
5 | > Android desktop widget, daily check Or calendar,it can be used as a desktop calendar :two_hearts:
6 |
7 | [](https://android-arsenal.com/api?level=19)
8 | [](https://www.apache.org/licenses/LICENSE-2.0)
9 | [ ](https://github.com/fairytale110/DailyImageWidget/raw/master/release/DailyImageWidget_1.0.1.apk)
10 |
11 | [中文 README](https://github.com/fairytale110/DailyImageWidget/blob/master/README_CN.md)
12 |
13 | ### Preview
14 |
15 | 
16 |
17 |
18 | ### Features
19 |
20 | - [x] Display date, week
21 | - [x] Show the current year and month of the lunar calendar and the zodiac
22 | - [x] Update a random verse every five minutes (requires App's network permissions)
23 |
24 | ### How to use this widget
25 |
26 | - step1: [ ](https://github.com/fairytale110/DailyImageWidget/raw/master/release/DailyImageWidget_1.0.1.apk)
27 | or you can scan this QRcode to download
28 |
29 | 
30 |
31 | install it on your Android phone,
32 |
33 | - step2: find "DailyImage" from the list of desktop widgets and add it to your desktop.
34 |
35 |
36 | ### Participate in the contribution
37 | fairytale110@foxmail.com
38 |
39 | :pray: [Idea comes from @renyijiu](https://github.com/renyijiu/daily_image)
40 |
41 | :pray: [一言·古诗词 API](https://www.jinrishici.com/)
42 |
43 | ### Author
44 | ```
45 | fairytale110@foxmail.com
46 | > 简书: http://jianshu.com/u/d95b27ffdd3c
47 | > 掘金: https://juejin.im/user/596d91ee6fb9a06bb874a800
48 | ```
49 |
50 | ### LICENSE
51 |
52 | ```
53 | Copyright 2018 fairytale110
54 |
55 | Licensed under the Apache License, Version 2.0 (the "License");
56 | you may not use this file except in compliance with the License.
57 | You may obtain a copy of the License at
58 |
59 | http://www.apache.org/licenses/LICENSE-2.0
60 |
61 | Unless required by applicable law or agreed to in writing, software
62 | distributed under the License is distributed on an "AS IS" BASIS,
63 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64 | See the License for the specific language governing permissions and
65 | limitations under the License.
66 | ```
67 |
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 |
2 | # DailyImageWidget
3 | > Android 桌面小部件(widget)日签 Or 日历,可作为桌面日历。Just For Fun! :video_game:
4 |
5 | [](https://android-arsenal.com/api?level=19)
6 | [](https://www.apache.org/licenses/LICENSE-2.0)
7 | [ ](https://github.com/fairytale110/DailyImageWidget/raw/master/release/DailyImageWidget_1.0.1.apk)
8 |
9 | ### 真机效果
10 |
11 | 
12 |
13 |
14 | ### 功能
15 |
16 | - [x] 展示当前阳历日期和星期
17 | - [x] 展示当前农历的年月日和生肖
18 | - [x] 每五分钟更新一句随机古诗(需要你的设备允许本软件的网络权限)
19 |
20 | ### 怎么用?
21 |
22 | - 第一步: [ ](https://github.com/fairytale110/DailyImageWidget/raw/master/release/DailyImageWidget_1.0.1.apk)
23 | 或者你也可以直接手机扫描下面的二维码下载安装
24 |
25 | 
26 |
27 | - 第二步: 在你的手机Launcher中进入添加桌面部件的位置,找到 "DailyImage" 拖入桌面即可.
28 |
29 |
30 | ### 参与贡献
31 | fairytale110@foxmail.com
32 |
33 | :pray: [项目idea来源 @renyijiu](https://github.com/renyijiu/daily_image)
34 |
35 | :pray: [一言·古诗词 API](https://www.jinrishici.com/)
36 |
37 | ### 作者
38 | ```
39 | fairytale110@foxmail.com
40 | > 简书: http://jianshu.com/u/d95b27ffdd3c
41 | > 掘金: https://juejin.im/user/596d91ee6fb9a06bb874a800
42 | ```
43 |
44 |
45 | ### 协议
46 |
47 | ```
48 | Copyright 2018 fairytale110
49 |
50 | Licensed under the Apache License, Version 2.0 (the "License");
51 | you may not use this file except in compliance with the License.
52 | You may obtain a copy of the License at
53 |
54 | http://www.apache.org/licenses/LICENSE-2.0
55 |
56 | Unless required by applicable law or agreed to in writing, software
57 | distributed under the License is distributed on an "AS IS" BASIS,
58 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
59 | See the License for the specific language governing permissions and
60 | limitations under the License.
61 | ```
62 |
63 | > 项目地址:https://github.com/fairytale110/DailyImageWidget
64 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: rootProject.ext.plugins.android
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.android.compileSdkVersion
5 | defaultConfig {
6 | applicationId rootProject.ext.android.applicationId
7 | minSdkVersion rootProject.ext.android.sampleMinSdkVersion
8 | targetSdkVersion rootProject.ext.android.targetSdkVersion
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 |
24 | testImplementation rootProject.ext.dependencies.junit
25 | implementation rootProject.ext.dependencies.appCompat
26 | implementation rootProject.ext.dependencies.design
27 | implementation rootProject.ext.dependencies.constraint_layout
28 | implementation rootProject.ext.dependencies.okalle
29 | implementation rootProject.ext.dependencies.fastjson
30 | implementation rootProject.ext.dependencies.autosize
31 | debugImplementation rootProject.ext.dependencies.leakcanary
32 |
33 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
34 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
35 |
36 | // implementation project(':libdailyimage')
37 | }
38 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/tech/nicesky/dailyimage/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("tech.nicesky.dailyimage", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
39 |
40 |
41 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/App.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage;
2 |
3 | import android.app.Application;
4 |
5 | import com.yanzhenjie.kalle.Kalle;
6 | import com.yanzhenjie.kalle.KalleConfig;
7 | import com.yanzhenjie.kalle.OkHttpConnectFactory;
8 | import com.yanzhenjie.kalle.connect.http.LoggerInterceptor;
9 | import com.yanzhenjie.kalle.cookie.DBCookieStore;
10 |
11 | import java.util.concurrent.TimeUnit;
12 |
13 | import tech.nicesky.dailyimage.http.JsonConverter;
14 |
15 | public class App extends Application {
16 |
17 |
18 | @Override
19 | public void onCreate() {
20 | super.onCreate();
21 |
22 | initKalle();
23 | }
24 |
25 | /**
26 | * init http lib
27 | */
28 | private void initKalle() {
29 | KalleConfig config = KalleConfig.newBuilder()
30 | .addParam("withCredentials","1")
31 | .cookieStore(DBCookieStore.newBuilder(this).build())
32 | .connectionTimeout(30000, TimeUnit.MILLISECONDS)
33 | .readTimeout(30000, TimeUnit.MILLISECONDS)
34 | .connectFactory(OkHttpConnectFactory.newBuilder().build())
35 | .converter(new JsonConverter(this))
36 | .addInterceptor(new LoggerInterceptor("HTTP-->", BuildConfig.DEBUG))
37 | .build();
38 |
39 | Kalle.setConfig(config);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/Constants.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage;
2 |
3 | public class Constants {
4 | public static String STATUS_SUCCESS = "success";
5 | public static String API_GET_JSON = "https://v2.jinrishici.com/one.json";
6 | //public static String API_GET_DATE = "https://cgi.im.qq.com/cgi-bin/cgi_svrtime";
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/MainActivity.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.design.widget.Snackbar;
7 | import android.view.View;
8 | import android.support.design.widget.NavigationView;
9 | import android.support.v4.view.GravityCompat;
10 | import android.support.v4.widget.DrawerLayout;
11 | import android.support.v7.app.ActionBarDrawerToggle;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.support.v7.widget.Toolbar;
14 | import android.view.Menu;
15 | import android.view.MenuItem;
16 |
17 | import tech.nicesky.dailyimage.widget.DailyImageService;
18 |
19 |
20 | public class MainActivity extends AppCompatActivity
21 | implements NavigationView.OnNavigationItemSelectedListener {
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_main);
27 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
28 | setSupportActionBar(toolbar);
29 |
30 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
31 | fab.setOnClickListener(new View.OnClickListener() {
32 | @Override
33 | public void onClick(View view) {
34 | // Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
35 | // .setAction("Action", null).show();
36 | }
37 | });
38 |
39 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
40 | ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
41 | this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
42 | drawer.addDrawerListener(toggle);
43 | toggle.syncState();
44 |
45 | NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
46 | navigationView.setNavigationItemSelectedListener(this);
47 |
48 | }
49 |
50 | @Override
51 | public void onBackPressed() {
52 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
53 | if (drawer.isDrawerOpen(GravityCompat.START)) {
54 | drawer.closeDrawer(GravityCompat.START);
55 | } else {
56 | super.onBackPressed();
57 | }
58 | }
59 |
60 | @Override
61 | public boolean onCreateOptionsMenu(Menu menu) {
62 | // Inflate the menu; this adds items to the action bar if it is present.
63 | getMenuInflater().inflate(R.menu.main, menu);
64 | return true;
65 | }
66 |
67 | @Override
68 | public boolean onOptionsItemSelected(MenuItem item) {
69 | // Handle action bar item clicks here. The action bar will
70 | // automatically handle clicks on the Home/Up button, so long
71 | // as you specify a parent activity in AndroidManifest.xml.
72 | int id = item.getItemId();
73 |
74 | //noinspection SimplifiableIfStatement
75 | if (id == R.id.action_settings) {
76 | return true;
77 | }
78 | return super.onOptionsItemSelected(item);
79 | }
80 |
81 | @SuppressWarnings("StatementWithEmptyBody")
82 | @Override
83 | public boolean onNavigationItemSelected(MenuItem item) {
84 | // Handle navigation view item clicks here.
85 | int id = item.getItemId();
86 |
87 | if (id == R.id.nav_camera) {
88 | // Handle the camera action
89 | } else if (id == R.id.nav_gallery) {
90 |
91 | } else if (id == R.id.nav_slideshow) {
92 |
93 | } else if (id == R.id.nav_manage) {
94 |
95 | } else if (id == R.id.nav_share) {
96 |
97 | } else if (id == R.id.nav_send) {
98 |
99 | }
100 |
101 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
102 | drawer.closeDrawer(GravityCompat.START);
103 | return true;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/bean/Origin.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 bejson.com
3 | */
4 | package tech.nicesky.dailyimage.bean;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Auto-generated: 2018-10-08 16:13:58
10 | *
11 | * @author bejson.com (i@bejson.com)
12 | * @website http://www.bejson.com/java2pojo/
13 | */
14 | public class Origin {
15 |
16 | private String title;
17 | private String dynasty;
18 | private String author;
19 | private List content;
20 |
21 | public void setTitle(String title) {
22 | this.title = title;
23 | }
24 |
25 | public String getTitle() {
26 | return title;
27 | }
28 |
29 | public void setDynasty(String dynasty) {
30 | this.dynasty = dynasty;
31 | }
32 |
33 | public String getDynasty() {
34 | return dynasty;
35 | }
36 |
37 | public void setAuthor(String author) {
38 | this.author = author;
39 | }
40 |
41 | public String getAuthor() {
42 | return "---- " + author;
43 | }
44 |
45 | public void setContent(List content) {
46 | this.content = content;
47 | }
48 |
49 | public List getContent() {
50 | return content;
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/bean/PoetryData.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 bejson.com
3 | */
4 | package tech.nicesky.dailyimage.bean;
5 |
6 | import java.util.List;
7 | import java.util.Date;
8 |
9 | /**
10 | * Auto-generated: 2018-10-08 16:13:58
11 | *
12 | * @author bejson.com (i@bejson.com)
13 | * @website http://www.bejson.com/java2pojo/
14 | */
15 | public class PoetryData {
16 |
17 | private String id;
18 | private String content;
19 | private Long popularity;
20 | private Origin origin;
21 | private List matchTags;
22 | private String recommendedReason;
23 | private String cacheAt;
24 |
25 | public void setId(String id) {
26 | this.id = id;
27 | }
28 |
29 | public String getId() {
30 | return id;
31 | }
32 |
33 | public void setContent(String content) {
34 | this.content = content;
35 | }
36 |
37 | public String getContent() {
38 | return content;
39 | }
40 |
41 | public void setPopularity(long popularity) {
42 | this.popularity = popularity;
43 | }
44 |
45 | public long getPopularity() {
46 | return popularity;
47 | }
48 |
49 | public void setOrigin(Origin origin) {
50 | this.origin = origin;
51 | }
52 |
53 | public Origin getOrigin() {
54 | return origin;
55 | }
56 |
57 | public void setMatchTags(List matchTags) {
58 | this.matchTags = matchTags;
59 | }
60 |
61 | public List getMatchTags() {
62 | return matchTags;
63 | }
64 |
65 | public void setRecommendedReason(String recommendedReason) {
66 | this.recommendedReason = recommendedReason;
67 | }
68 |
69 | public String getRecommendedReason() {
70 | return recommendedReason;
71 | }
72 |
73 | public void setCacheAt(String cacheAt) {
74 | this.cacheAt = cacheAt;
75 | }
76 |
77 | public String getCacheAt() {
78 | return cacheAt;
79 | }
80 |
81 |
82 | @Override
83 | public String toString() {
84 | return "PoetryData{" +
85 | "content='" + content + '\'' +
86 | '}';
87 | }
88 | }
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/http/HttpEntity.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage.http;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 | import android.text.TextUtils;
6 |
7 | import com.alibaba.fastjson.annotation.JSONField;
8 |
9 | import tech.nicesky.dailyimage.Constants;
10 | import tech.nicesky.dailyimage.util.StringUtils;
11 |
12 |
13 | /**
14 | * @class tech.nicesky.dailyimage.http.HttpEntity
15 | * @date on 2018/10/10-上午8:51
16 | * @author fairytale110
17 | * @email fairytale110@foxmail.com
18 | * @description: 网络返回
19 | *
20 | */
21 | public class HttpEntity implements Parcelable {
22 |
23 | @JSONField(name = "status")
24 | private String mSucceed;
25 |
26 | @JSONField(name = "errMessage")
27 | private String mMessage;
28 |
29 | @JSONField(name = "data")
30 | private String mData;
31 |
32 | @JSONField(name = "errCode")
33 | private int mErrCode;
34 |
35 | public HttpEntity() {
36 | }
37 |
38 | protected HttpEntity(Parcel in) {
39 | mSucceed = in.readString();
40 | mMessage = in.readString();
41 | mData = in.readString();
42 | mErrCode = in.readInt();
43 |
44 | }
45 |
46 | @Override
47 | public void writeToParcel(Parcel dest, int flags) {
48 | dest.writeString(mSucceed);
49 | dest.writeString(mMessage);
50 | dest.writeString(mData);
51 | dest.writeInt(mErrCode);
52 | }
53 |
54 | @Override
55 | public int describeContents() {
56 | return 0;
57 | }
58 |
59 | public static final Creator CREATOR = new Creator() {
60 | @Override
61 | public HttpEntity createFromParcel(Parcel in) {
62 | return new HttpEntity(in);
63 | }
64 |
65 | @Override
66 | public HttpEntity[] newArray(int size) {
67 | return new HttpEntity[size];
68 | }
69 | };
70 |
71 | public String getStatus() {
72 | return mSucceed;
73 | }
74 |
75 | public void setStatus(String mSucceed) {
76 | this.mSucceed = mSucceed;
77 | }
78 |
79 | public String getErrMessage() {
80 | return mMessage;
81 | }
82 |
83 | public void setErrMessage(String mMessage) {
84 | this.mMessage = mMessage;
85 | }
86 |
87 | public String getData() {
88 | return mData;
89 | }
90 |
91 | public void setData(String mData) {
92 | this.mData = mData;
93 | }
94 |
95 | public int getErrCode() {
96 | return mErrCode;
97 | }
98 |
99 | public void setErrCode(int mErrCode) {
100 | this.mErrCode = mErrCode;
101 | }
102 |
103 | public boolean isSucceed() {
104 | if (StringUtils.isEmpty(getStatus())) return false;
105 |
106 | return TextUtils.equals(getStatus(), Constants.STATUS_SUCCESS);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/http/JsonConverter.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage.http;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import com.alibaba.fastjson.JSON;
7 | import com.yanzhenjie.kalle.Response;
8 | import com.yanzhenjie.kalle.simple.Converter;
9 | import com.yanzhenjie.kalle.simple.SimpleResponse;
10 |
11 | import java.lang.reflect.Type;
12 |
13 | import tech.nicesky.dailyimage.R;
14 |
15 | /**
16 | * @class tech.nicesky.dailyimage.http.JsonConverter
17 | * @date on 2018/10/10-上午8:52
18 | * @author fairytale110
19 | * @email fairytale110@foxmail.com
20 | * @description: 解析器
21 | *
22 | */
23 | public class JsonConverter implements Converter {
24 |
25 | private Context mContext;
26 |
27 | public JsonConverter(Context context) {
28 | this.mContext = context;
29 | }
30 |
31 | @Override
32 | public SimpleResponse convert(Type succeed, Type failed, Response response, boolean fromCache) throws Exception {
33 | S succeedData = null; // The data when the business successful.
34 | F failedData = null; // The data when the business failed.
35 |
36 | int code = response.code();
37 | String serverJson = response.body().string();
38 | Log.w("Server Data: ","data===> " + serverJson);
39 | if (code >= 200 && code < 300) { // Http is successful.
40 | HttpEntity httpEntity;
41 | try {
42 | httpEntity = JSON.parseObject(serverJson, HttpEntity.class);
43 | } catch (Exception e) {
44 | httpEntity = new HttpEntity();
45 | httpEntity.setStatus("error");
46 | httpEntity.setErrMessage(mContext.getString(R.string.http_server_data_format_error));
47 | }
48 |
49 | if (httpEntity.isSucceed()) { // The server successfully processed the business.
50 | try {
51 | Log.w(" 解析数据 ==== ", "data--> "+ httpEntity.getData());
52 | succeedData = JSON.parseObject(httpEntity.getData(), succeed);
53 | } catch (Exception e) {
54 | failedData = (F) mContext.getString(R.string.http_server_data_format_error);
55 | }
56 | } else {
57 | // The server failed to read the wrong information.
58 | failedData = (F) httpEntity.getErrMessage();
59 | }
60 |
61 | } else if (code >= 400 && code < 500) {
62 | failedData = (F) mContext.getString(R.string.http_unknow_error);
63 | } else if (code >= 500) {
64 | failedData = (F) mContext.getString(R.string.http_server_error);
65 | }
66 |
67 | return SimpleResponse.newBuilder()
68 | .code(response.code())
69 | .headers(response.headers())
70 | .fromCache(fromCache)
71 | .succeed(succeedData)
72 | .failed(failedData)
73 | .build();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/util/ChinaDate.java:
--------------------------------------------------------------------------------
1 | /**
2 | * 来源 https://www.cnblogs.com/hongten/archive/2012/10/07/java_calendar.html
3 | */
4 | package tech.nicesky.dailyimage.util;
5 |
6 | import java.text.SimpleDateFormat;
7 | import java.util.Calendar;
8 | import java.util.Date;
9 | import java.util.GregorianCalendar;
10 | import java.util.Locale;
11 |
12 | @SuppressWarnings("all")
13 | public class ChinaDate {
14 | final private static long[] lunarInfo = new long[]{0x04bd8, 0x04ae0,
15 | 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0,
16 | 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540,
17 | 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5,
18 | 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
19 | 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3,
20 | 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0,
21 | 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0,
22 | 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8,
23 | 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570,
24 | 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5,
25 | 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0,
26 | 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50,
27 | 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0,
28 | 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
29 | 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7,
30 | 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50,
31 | 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954,
32 | 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260,
33 | 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0,
34 | 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0,
35 | 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20,
36 | 0x0ada0};
37 | final private static int[] year20 = new int[]{1, 4, 1, 2, 1, 2, 1, 1, 2,
38 | 1, 2, 1};
39 | final private static int[] year19 = new int[]{0, 3, 0, 1, 0, 1, 0, 0, 1,
40 | 0, 1, 0};
41 | final private static int[] year2000 = new int[]{0, 3, 1, 2, 1, 2, 1, 1,
42 | 2, 1, 2, 1};
43 | public final static String[] nStr1 = new String[]{"", "正", "二", "三", "四",
44 | "五", "六", "七", "八", "九", "十", "冬月", "腊月"};
45 | private final static String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊",
46 | "己", "庚", "辛", "壬", "癸"};
47 | private final static String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰",
48 | "巳", "午", "未", "申", "酉", "戌", "亥"};
49 | private final static String[] Animals = new String[]{"鼠", "牛", "虎", "兔",
50 | "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
51 |
52 | private final static String[] solarTerm = new String[]{"小寒", "大寒", "立春",
53 | "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑",
54 | "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"};
55 | private final static String[] sFtv = new String[]{"0101*元旦", "0214 情人节",
56 | "0308 妇女节", "0312 植树节", "0315 消费者权益日", "0401 愚人节", "0501 劳动节",
57 | "0504 青年节", "0512 护士节", "0601 儿童节", "0701 建党节", "0801 建军节",
58 | "0808 父亲节", "0909 mzd逝世纪念", "0910 教师节", "0928 孔子诞辰", "1001*国庆节",
59 | "1006 老人节", "1024 联合国日", "1112 孙中山诞辰", "1220 澳门回归", "1225 圣诞节",
60 | "1226 毛主席诞辰"};
61 | private final static String[] lFtv = new String[]{"0101*农历春节",
62 | "0115 元宵节", "0505 端午节", "0707 七夕情人节", "0815 中秋节", "0909 重阳节",
63 | "1208 腊八节", "1224 小年", "0100*除夕"};
64 |
65 | /**
66 | * 传回农历 y年的总天数
67 | *
68 | * @param y
69 | * @return
70 | */
71 | final private static int lYearDays(int y) {
72 | int i, sum = 348;
73 | for (i = 0x8000; i > 0x8; i >>= 1) {
74 | if ((lunarInfo[y - 1900] & i) != 0)
75 | sum += 1;
76 | }
77 | return (sum + leapDays(y));
78 | }
79 |
80 | /**
81 | * 传回农历 y年闰月的天数
82 | *
83 | * @param y
84 | * @return
85 | */
86 | final private static int leapDays(int y) {
87 | if (leapMonth(y) != 0) {
88 | if ((lunarInfo[y - 1900] & 0x10000) != 0)
89 | return 30;
90 | else
91 | return 29;
92 | } else
93 | return 0;
94 | }
95 |
96 | /**
97 | * 传回农历 y年闰哪个月 1-12 , 没闰传回 0
98 | *
99 | * @param y
100 | * @return
101 | */
102 | final private static int leapMonth(int y) {
103 | return (int) (lunarInfo[y - 1900] & 0xf);
104 | }
105 |
106 | /**
107 | * 传回农历 y年m月的总天数
108 | *
109 | * @param y
110 | * @param m
111 | * @return
112 | */
113 | final private static int monthDays(int y, int m) {
114 | if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
115 | return 29;
116 | else
117 | return 30;
118 | }
119 |
120 | /**
121 | * 传回农历 y年的生肖
122 | *
123 | * @param y
124 | * @return
125 | */
126 | final public static String AnimalsYear(int y) {
127 | return Animals[(y - 4) % 12];
128 | }
129 |
130 | /**
131 | * 传入 月日的offset 传回干支,0=甲子
132 | *
133 | * @param num
134 | * @return
135 | */
136 | final private static String cyclicalm(int num) {
137 | return (Gan[num % 10] + Zhi[num % 12]);
138 | }
139 |
140 | /**
141 | * 传入 offset 传回干支, 0=甲子
142 | *
143 | * @param y
144 | * @return
145 | */
146 | final public static String cyclical(int y) {
147 | int num = y - 1900 + 36;
148 | return (cyclicalm(num));
149 | }
150 |
151 | /**
152 | * 传出农历.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6
153 | *
154 | * @param y
155 | * @param m
156 | * @return
157 | */
158 | final private long[] Lunar(int y, int m) {
159 | long[] nongDate = new long[7];
160 | int i = 0, temp = 0, leap = 0;
161 | Date baseDate = new GregorianCalendar(1900 + 1900, 1, 31).getTime();
162 | Date objDate = new GregorianCalendar(y + 1900, m, 1).getTime();
163 | long offset = (objDate.getTime() - baseDate.getTime()) / 86400000L;
164 | if (y < 2000)
165 | offset += year19[m - 1];
166 | if (y > 2000)
167 | offset += year20[m - 1];
168 | if (y == 2000)
169 | offset += year2000[m - 1];
170 | nongDate[5] = offset + 40;
171 | nongDate[4] = 14;
172 | for (i = 1900; i < 2050 && offset > 0; i++) {
173 | temp = lYearDays(i);
174 | offset -= temp;
175 | nongDate[4] += 12;
176 | }
177 | if (offset < 0) {
178 | offset += temp;
179 | i--;
180 | nongDate[4] -= 12;
181 | }
182 | nongDate[0] = i;
183 | nongDate[3] = i - 1864;
184 | leap = leapMonth(i); // 闰哪个月
185 | nongDate[6] = 0;
186 | for (i = 1; i < 13 && offset > 0; i++) {
187 | // 闰月
188 | if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) {
189 | --i;
190 | nongDate[6] = 1;
191 | temp = leapDays((int) nongDate[0]);
192 | } else {
193 | temp = monthDays((int) nongDate[0], i);
194 | }
195 | // 解除闰月
196 | if (nongDate[6] == 1 && i == (leap + 1))
197 | nongDate[6] = 0;
198 | offset -= temp;
199 | if (nongDate[6] == 0)
200 | nongDate[4]++;
201 | }
202 | if (offset == 0 && leap > 0 && i == leap + 1) {
203 | if (nongDate[6] == 1) {
204 | nongDate[6] = 0;
205 | } else {
206 | nongDate[6] = 1;
207 | --i;
208 | --nongDate[4];
209 | }
210 | }
211 | if (offset < 0) {
212 | offset += temp;
213 | --i;
214 | --nongDate[4];
215 | }
216 | nongDate[1] = i;
217 | nongDate[2] = offset + 1;
218 | return nongDate;
219 | }
220 |
221 | /**
222 | * 传出y年m月d日对应的农历.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6
223 | *
224 | * @param y
225 | * @param m
226 | * @param d
227 | * @return
228 | */
229 | final public static long[] calElement(int y, int m, int d) {
230 | long[] nongDate = new long[7];
231 | int i = 0, temp = 0, leap = 0;
232 | Date baseDate = new GregorianCalendar(0 + 1900, 0, 31).getTime();
233 | Date objDate = new GregorianCalendar(y, m - 1, d).getTime();
234 | long offset = (objDate.getTime() - baseDate.getTime()) / 86400000L;
235 | nongDate[5] = offset + 40;
236 | nongDate[4] = 14;
237 | for (i = 1900; i < 2050 && offset > 0; i++) {
238 | temp = lYearDays(i);
239 | offset -= temp;
240 | nongDate[4] += 12;
241 | }
242 | if (offset < 0) {
243 | offset += temp;
244 | i--;
245 | nongDate[4] -= 12;
246 | }
247 | nongDate[0] = i;
248 | nongDate[3] = i - 1864;
249 | leap = leapMonth(i); // 闰哪个月
250 | nongDate[6] = 0;
251 | for (i = 1; i < 13 && offset > 0; i++) {
252 | // 闰月
253 | if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) {
254 | --i;
255 | nongDate[6] = 1;
256 | temp = leapDays((int) nongDate[0]);
257 | } else {
258 | temp = monthDays((int) nongDate[0], i);
259 | }
260 | // 解除闰月
261 | if (nongDate[6] == 1 && i == (leap + 1))
262 | nongDate[6] = 0;
263 | offset -= temp;
264 | if (nongDate[6] == 0)
265 | nongDate[4]++;
266 | }
267 | if (offset == 0 && leap > 0 && i == leap + 1) {
268 | if (nongDate[6] == 1) {
269 | nongDate[6] = 0;
270 | } else {
271 | nongDate[6] = 1;
272 | --i;
273 | --nongDate[4];
274 | }
275 | }
276 | if (offset < 0) {
277 | offset += temp;
278 | --i;
279 | --nongDate[4];
280 | }
281 | nongDate[1] = i;
282 | nongDate[2] = offset + 1;
283 | return nongDate;
284 | }
285 |
286 | public final static String getChinaDate(int day) {
287 | String a = "";
288 | if (day == 10)
289 | return "初十";
290 | if (day == 20)
291 | return "二十";
292 | if (day == 30)
293 | return "三十";
294 | int two = (int) ((day) / 10);
295 | if (two == 0)
296 | a = "初";
297 | if (two == 1)
298 | a = "十";
299 | if (two == 2)
300 | a = "廿";
301 | if (two == 3)
302 | a = "三";
303 | int one = (int) (day % 10);
304 | switch (one) {
305 | case 1:
306 | a += "一";
307 | break;
308 | case 2:
309 | a += "二";
310 | break;
311 | case 3:
312 | a += "三";
313 | break;
314 | case 4:
315 | a += "四";
316 | break;
317 | case 5:
318 | a += "五";
319 | break;
320 | case 6:
321 | a += "六";
322 | break;
323 | case 7:
324 | a += "七";
325 | break;
326 | case 8:
327 | a += "八";
328 | break;
329 | case 9:
330 | a += "九";
331 | break;
332 | }
333 | return a;
334 | }
335 |
336 | public static String getWeek() {
337 | Calendar cal = Calendar.getInstance();
338 | int i = cal.get(Calendar.DAY_OF_WEEK);
339 | switch (i) {
340 | case 1:
341 | return "星期日";
342 | case 2:
343 | return "星期一";
344 | case 3:
345 | return "星期二";
346 | case 4:
347 | return "星期三";
348 | case 5:
349 | return "星期四";
350 | case 6:
351 | return "星期五";
352 | case 7:
353 | return "星期六";
354 | default:
355 | return "";
356 | }
357 | }
358 |
359 | public static String today() {
360 | Calendar today = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE);
361 | int year = today.get(Calendar.YEAR);
362 | int month = today.get(Calendar.MONTH) + 1;
363 | int date = today.get(Calendar.DATE);
364 | long[] l = calElement(year, month, date);
365 | StringBuffer sToday = new StringBuffer();
366 | try {
367 | // sToday.append(sdf.format(today.getTime()));
368 | // sToday.append(" 农历");
369 | sToday.append(cyclical(year));
370 | sToday.append('(');
371 | sToday.append(AnimalsYear(year));
372 | sToday.append(")年,");
373 | sToday.append(nStr1[(int) l[1]]);
374 | sToday.append("月");
375 | sToday.append(getChinaDate((int) (l[2])));
376 | return sToday.toString();
377 | } finally {
378 | sToday = null;
379 | }
380 | }
381 |
382 | public static String oneDay(int year, int month, int day) {
383 | Calendar today = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE);
384 | long[] l = calElement(year, month, day);
385 | StringBuffer sToday = new StringBuffer();
386 | try {
387 | sToday.append(sdf.format(today.getTime()));
388 | sToday.append(" 农历");
389 | sToday.append(cyclical(year));
390 | sToday.append('(');
391 | sToday.append(AnimalsYear(year));
392 | sToday.append(")年");
393 | sToday.append(nStr1[(int) l[1]]);
394 | sToday.append("月");
395 | sToday.append(getChinaDate((int) (l[2])));
396 | return sToday.toString();
397 | } finally {
398 | sToday = null;
399 | }
400 | }
401 |
402 | private static SimpleDateFormat sdf = new SimpleDateFormat(
403 | "yyyy年M月d日 EEEEE");
404 |
405 |
406 | public static boolean isLeapYear(int year) {
407 | return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
408 | }
409 |
410 | public static double getDaysOfYear(int year){
411 | return isLeapYear(year) ? 366.0 : 365.0;
412 | }
413 |
414 | /**
415 | * 农历日历工具使用演示
416 | *
417 | * @param args
418 | */
419 | public static void main(String[] args) {
420 | System.out.println(today());
421 | System.out.println(oneDay(1989, 9, 10));
422 | int year = 2000;
423 | System.out.print(year + "年是 "+ (isLeapYear(year) ? "闰年" : "平年") + " 有 "+ getDaysOfYear(year) + "天");
424 | }
425 | }
426 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/util/StringUtils.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage.util;
2 |
3 | import android.text.TextUtils;
4 |
5 | /**
6 | * @class tech.nicesky.dailyimage.util.StringUtils
7 | * @date on 2018/10/10-上午8:53
8 | * @author fairytale110
9 | * @email fairytale110@foxmail.com
10 | * @description: N/A
11 | *
12 | */
13 | public class StringUtils {
14 |
15 |
16 | /**
17 | * 字符串空判断
18 | *
19 | * @param str
20 | * @return
21 | */
22 | public static boolean isEmpty(CharSequence str) {
23 | return TextUtils.isEmpty(str) || isNull(str);
24 | }
25 |
26 | public static boolean isEmptyNoSpace(CharSequence... strs) {
27 | if (strs == null) {
28 | return true;
29 | }
30 | if (strs.length < 1) {
31 | return true;
32 | }
33 | boolean hasEmp = false;
34 | for (CharSequence c :
35 | strs) {
36 | if (isEmptyNoSpace(c)) {
37 | hasEmp = true;
38 | break;
39 | }
40 | }
41 | return hasEmp;
42 | }
43 |
44 |
45 | /**
46 | * 字符串空判断 清除了空格字符
47 | *
48 | * @param str
49 | * @return
50 | */
51 | public static boolean isEmptyNoSpace(CharSequence str) {
52 | if (isEmpty(str)) {
53 | return true;
54 | }
55 | str = str.toString().trim();//去除首尾半角
56 | if (isEmpty(str)) {
57 | return true;
58 | }
59 | str = str.toString().replaceAll(" ", "");//去除中间半角空格
60 | str = str.toString().replaceAll(" ", "");//去除全角空格 :)
61 | return TextUtils.isEmpty(str) || isNull(str);
62 | }
63 |
64 | /**
65 | * 字符串空判断
66 | *
67 | * @param str
68 | * @return
69 | */
70 | public static boolean isNull(CharSequence str) {
71 | if (TextUtils.isEmpty(str)) {
72 |
73 | return true;
74 | }
75 | if (!TextUtils.isEmpty(str) && "null".equals(str.toString().toLowerCase())) {
76 | return true;
77 | } else
78 | return false;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/widget/DailyImageProvider.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage.widget;
2 |
3 | import android.appwidget.AppWidgetManager;
4 | import android.appwidget.AppWidgetProvider;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 | import android.widget.RemoteViews;
11 |
12 | import tech.nicesky.dailyimage.R;
13 |
14 | /**
15 | * @class tech.nicesky.dailyimage.widget.DailyImageProvider
16 | * @date on 2018/10/10-上午8:53
17 | * @author fairytale110
18 | * @email fairytale110@foxmail.com
19 | * @description: AppWidgetProvider
20 | *
21 | */
22 | public class DailyImageProvider extends AppWidgetProvider {
23 |
24 | public DailyImageProvider() {
25 | }
26 |
27 | public static final String CLICK_ACTION = "com.seewo.appwidgettest.action.CLICK"; // 点击事件的广播ACTION
28 |
29 | /**
30 | * 每次窗口小部件被更新都调用一次该方法
31 | */
32 | @Override
33 | public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
34 | super.onUpdate(context, appWidgetManager, appWidgetIds);
35 |
36 | RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_daily_image);
37 | // Intent intent = new Intent(CLICK_ACTION);
38 | // PendingIntent pendingIntent = PendingIntent.getBroadcast(context, R.id.doge_imageView, intent, PendingIntent.FLAG_UPDATE_CURRENT);
39 | // remoteViews.setOnClickPendingIntent(R.id.doge_imageView, pendingIntent);
40 |
41 | for (int appWidgetId : appWidgetIds) {
42 | appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
43 | }
44 |
45 | //Log.w("xxxxx","onUpdate");
46 |
47 | }
48 |
49 | /**
50 | * 接收窗口小部件点击时发送的广播
51 | */
52 | @Override
53 | public void onReceive(Context context, Intent intent) {
54 | super.onReceive(context, intent);
55 |
56 | // if (CLICK_ACTION.equals(intent.getAction())) {
57 | // Toast.makeText(context, "hello dog!", Toast.LENGTH_SHORT).show();
58 | // }
59 | // Log.w("xxxxx","onReceive");
60 | }
61 |
62 | /**
63 | * 每删除一次窗口小部件就调用一次
64 | */
65 | @Override
66 | public void onDeleted(Context context, int[] appWidgetIds) {
67 | super.onDeleted(context, appWidgetIds);
68 |
69 | // Log.w("xxxxx","onDeleted");
70 | }
71 |
72 | /**
73 | * 当最后一个该窗口小部件删除时调用该方法
74 | */
75 | @Override
76 | public void onDisabled(Context context) {
77 | super.onDisabled(context);
78 | context.stopService(new Intent(context,DailyImageService.class));
79 | // Log.w("xxxxx","onDisabled");
80 | }
81 |
82 | /**
83 | * 当该窗口小部件第一次添加到桌面时调用该方法
84 | */
85 | @Override
86 | public void onEnabled(Context context) {
87 | super.onEnabled(context);
88 | //Log.w("xxxxx","onEnabled");
89 |
90 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
91 | context.startForegroundService(new Intent(context,DailyImageService.class));
92 | } else {
93 | context.startService(new Intent(context,DailyImageService.class));
94 | }
95 | }
96 |
97 | /**
98 | * 当小部件大小改变时
99 | */
100 | @Override
101 | public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
102 | super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
103 | //Log.w("xxxxx","onAppWidgetOptionsChanged");
104 | }
105 |
106 | /**
107 | * 当小部件从备份恢复时调用该方法
108 | */
109 | @Override
110 | public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
111 | super.onRestored(context, oldWidgetIds, newWidgetIds);
112 | // Log.w("xxxxx","onRestored");
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/widget/DailyImageProviderLarge.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage.widget;
2 |
3 | import android.appwidget.AppWidgetManager;
4 | import android.appwidget.AppWidgetProvider;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 | import android.widget.RemoteViews;
10 |
11 | import tech.nicesky.dailyimage.R;
12 |
13 |
14 | /**
15 | * @class tech.nicesky.dailyimage.widget.DailyImageProviderLarge
16 | * @date on 2018/10/10-上午8:53
17 | * @author fairytale110
18 | * @email fairytale110@foxmail.com
19 | * @description: Large size AppWidgetProvider
20 | *
21 | */
22 | public class DailyImageProviderLarge extends AppWidgetProvider {
23 |
24 | public DailyImageProviderLarge() {
25 | }
26 |
27 | public static final String CLICK_ACTION = "com.seewo.appwidgettest.action.CLICK"; // 点击事件的广播ACTION
28 |
29 | /**
30 | * 每次窗口小部件被更新都调用一次该方法
31 | */
32 | @Override
33 | public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
34 | super.onUpdate(context, appWidgetManager, appWidgetIds);
35 |
36 | RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.layout_daily_image);
37 | // Intent intent = new Intent(CLICK_ACTION);
38 | // PendingIntent pendingIntent = PendingIntent.getBroadcast(context, R.id.doge_imageView, intent, PendingIntent.FLAG_UPDATE_CURRENT);
39 | // remoteViews.setOnClickPendingIntent(R.id.doge_imageView, pendingIntent);
40 |
41 | for (int appWidgetId : appWidgetIds) {
42 | appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
43 | }
44 |
45 | try {
46 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
47 | context.startForegroundService(new Intent(context,DailyImageService.class));
48 | } else {
49 | context.startService(new Intent(context,DailyImageService.class));
50 | }
51 | } catch (Exception e) {
52 | e.printStackTrace();
53 | }
54 | }
55 |
56 | /**
57 | * 接收窗口小部件点击时发送的广播
58 | */
59 | @Override
60 | public void onReceive(Context context, Intent intent) {
61 | super.onReceive(context, intent);
62 |
63 | // if (CLICK_ACTION.equals(intent.getAction())) {
64 | // Toast.makeText(context, "hello dog!", Toast.LENGTH_SHORT).show();
65 | // }
66 | }
67 |
68 | /**
69 | * 每删除一次窗口小部件就调用一次
70 | */
71 | @Override
72 | public void onDeleted(Context context, int[] appWidgetIds) {
73 | super.onDeleted(context, appWidgetIds);
74 | }
75 |
76 | /**
77 | * 当最后一个该窗口小部件删除时调用该方法
78 | */
79 | @Override
80 | public void onDisabled(Context context) {
81 | super.onDisabled(context);
82 | context.stopService(new Intent(context,DailyImageService.class));
83 | }
84 |
85 | /**
86 | * 当该窗口小部件第一次添加到桌面时调用该方法
87 | */
88 | @Override
89 | public void onEnabled(Context context) {
90 | super.onEnabled(context);
91 |
92 | }
93 |
94 | /**
95 | * 当小部件大小改变时
96 | */
97 | @Override
98 | public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
99 | super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
100 | }
101 |
102 | /**
103 | * 当小部件从备份恢复时调用该方法
104 | */
105 | @Override
106 | public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
107 | super.onRestored(context, oldWidgetIds, newWidgetIds);
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/app/src/main/java/tech/nicesky/dailyimage/widget/DailyImageService.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage.widget;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationChannel;
5 | import android.app.NotificationManager;
6 | import android.app.Service;
7 | import android.appwidget.AppWidgetManager;
8 | import android.content.ComponentName;
9 | import android.content.Intent;
10 | import android.graphics.Color;
11 | import android.os.Build;
12 | import android.os.IBinder;
13 | import android.util.Log;
14 | import android.widget.RemoteViews;
15 | import android.widget.Toast;
16 |
17 | import com.yanzhenjie.kalle.Kalle;
18 | import com.yanzhenjie.kalle.simple.SimpleCallback;
19 | import com.yanzhenjie.kalle.simple.SimpleResponse;
20 |
21 | import java.text.DecimalFormat;
22 | import java.util.Calendar;
23 | import java.util.Timer;
24 | import java.util.TimerTask;
25 |
26 | import tech.nicesky.dailyimage.Constants;
27 | import tech.nicesky.dailyimage.R;
28 | import tech.nicesky.dailyimage.bean.PoetryData;
29 | import tech.nicesky.dailyimage.util.ChinaDate;
30 |
31 | /**
32 | * @class tech.nicesky.dailyimage.widget.DailyImageService
33 | * @date on 2018/10/10-上午8:54
34 | * @author fairytale110
35 | * @email fairytale110@foxmail.com
36 | * @description: Service for timer
37 | *
38 | */
39 | public class DailyImageService extends Service {
40 |
41 | private Timer mTimer;
42 |
43 | @Override
44 | public void onCreate() {
45 | super.onCreate();
46 |
47 | String CHANNEL_ONE_ID = "tech.nicesky.dailyimage";
48 | String CHANNEL_ONE_NAME = "Channel One";
49 | NotificationChannel notificationChannel = null;
50 |
51 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
52 | notificationChannel = new NotificationChannel(CHANNEL_ONE_ID,
53 | CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_HIGH);
54 | notificationChannel.enableLights(true);
55 | notificationChannel.setLightColor(Color.RED);
56 | notificationChannel.setShowBadge(true);
57 | notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
58 | NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
59 | manager.createNotificationChannel(notificationChannel);
60 | }
61 |
62 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
63 | Notification notification = new Notification.Builder(this).setChannelId(CHANNEL_ONE_ID).build();
64 |
65 | startForeground(83674, notification);
66 | //这个id不要和应用内的其他同志id一样,不行就写 int.maxValue()
67 | // context.startForeground(SERVICE_ID, builder.getNotification());
68 | }
69 | }
70 |
71 | @Override
72 | public int onStartCommand(Intent intent, int flags, int startId) {
73 | if (null == mTimer) {
74 | mTimer = new Timer();
75 | }
76 | mTimer.schedule(new MyTimerTask(), 0, 300000);
77 | return START_STICKY;
78 | }
79 |
80 | @Override
81 | public void onDestroy() {
82 |
83 | super.onDestroy();
84 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
85 | stopForeground(Service.STOP_FOREGROUND_REMOVE);
86 | }
87 | }
88 |
89 | @Override
90 | public IBinder onBind(Intent intent) {
91 | return null;
92 | }
93 |
94 | private final class MyTimerTask extends TimerTask {
95 | DecimalFormat df = new DecimalFormat("#.00");
96 |
97 | @Override
98 | public void run() {
99 |
100 | Kalle.get(Constants.API_GET_JSON)
101 | //.addHeader("withCredentials","true")
102 | .perform(new SimpleCallback() {
103 | @Override
104 | public void onResponse(SimpleResponse response) {
105 | AppWidgetManager widgetManager = AppWidgetManager.getInstance(getApplicationContext());
106 | // widgetManager所操作的Widget对应的远程视图即当前Widget的layout文件
107 | RemoteViews remoteView = new RemoteViews(getPackageName(), R.layout.layout_daily_image);
108 | // remoteView.setImageViewResource(R.id.time_s, ResourceManager.getDrawableResId(getApplicationContext().getPackageName(), String.format("time_sec_%s", s)));
109 | // remoteView.setImageViewResource(R.id.time_m, ResourceManager.getDrawableResId(getApplicationContext().getPackageName(), String.format("time_min_%s", m)));
110 | // remoteView.setImageViewResource(R.id.time_h, ResourceManager.getDrawableResId(getApplicationContext().getPackageName(), String.format("time_hour_%s", h)));
111 |
112 | // schema 1 使用bitmap旋转
113 | Calendar calendar = Calendar.getInstance();
114 | int localYear = calendar.get(Calendar.YEAR);
115 | int localMonth = calendar.get(Calendar.MONTH);
116 | int localDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
117 | int localDayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
118 |
119 | int rawS = calendar.get(Calendar.SECOND);
120 | int rawM = calendar.get(Calendar.MINUTE);
121 | int rawH = calendar.get(Calendar.HOUR);
122 |
123 | float realS = rawS;
124 | float realM = rawM + realS / 60.0f;
125 | float realH = rawH + realM / 60.0f;
126 |
127 | remoteView.setTextViewText(R.id.txt_date,
128 | localYear + "-" + localMonth + "-" + localDayOfMonth
129 | // + " "+ realH + ":"+ realM + ":" + realS
130 | // + "\t\t" + rawH + ":" + rawM
131 | );
132 |
133 | remoteView.setTextViewText(R.id.txt_day_of_month, "" + localDayOfMonth);
134 | remoteView.setTextViewText(R.id.txt_week, ChinaDate.getWeek());
135 | remoteView.setTextViewText(R.id.txt_date_of_china, ChinaDate.today());
136 |
137 |
138 | double progressData = (localDayOfYear / ChinaDate.getDaysOfYear(localYear)) * 100;
139 |
140 | remoteView.setTextViewText(R.id.txt_progress_content,
141 | "第" + localDayOfYear + "天,进度已经消耗 " + df.format(progressData) + "%"
142 | );
143 | remoteView.setProgressBar(R.id.progress_for_day_of_year, 100, (int) progressData, false);
144 | if (response.isSucceed()) { // Http成功,业务也成功。
145 | PoetryData poetryData = response.succeed();
146 | //Log.w("SUCCESS---> ", " " + poetryData.toString());
147 |
148 | remoteView.setTextViewText(R.id.txt_ancient_poetry_content, poetryData.getContent());
149 | remoteView.setTextViewText(R.id.txt_ancient_poetry_title, poetryData.getOrigin().getTitle());
150 | remoteView.setTextViewText(R.id.txt_ancient_poetry_author, poetryData.getOrigin().getAuthor());
151 |
152 | } else {
153 | //Toast.show(response.failed());
154 | //Log.w("ERROR---> ", " " + response.failed());
155 | }
156 |
157 | ComponentName componentName = new ComponentName(getApplicationContext(), DailyImageProvider.class);
158 | ComponentName componentNameLarge = new ComponentName(getApplicationContext(), DailyImageProviderLarge.class);
159 | widgetManager.updateAppWidget(componentName, remoteView);
160 | widgetManager.updateAppWidget(componentNameLarge, remoteView);
161 | }
162 | });
163 |
164 | // 当点击Widgets时触发的世界
165 | // remoteView.setOnClickPendingIntent(viewId, pendingIntent)
166 |
167 | }
168 | }
169 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_camera.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_gallery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_manage.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_send.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_share.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_menu_slideshow.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_1.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/drawable/bg_1.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_2.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/drawable/bg_2.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/drawable/preview.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
9 |
10 |
11 |
12 |
13 | -
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/side_nav_bar.xml:
--------------------------------------------------------------------------------
1 |
3 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
25 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_daily_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
15 |
24 |
25 |
34 |
35 |
36 |
46 |
47 |
56 |
57 |
66 |
67 |
77 |
78 |
87 |
88 |
89 |
100 |
101 |
112 |
113 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
22 |
23 |
29 |
30 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/bg_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-xxhdpi/bg_1.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/bg_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-xxhdpi/bg_2.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6391a9
4 | #588095
5 | #c9cdd8
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 8dp
6 | 176dp
7 | 16dp
8 | 12sp
9 | 66sp
10 | 9sp
11 | 15dp
12 | 32dp
13 | 12dp
14 | 14dp
15 | 31dp
16 | 20dp
17 | 75sp
18 | 30dp
19 | 10dp
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 | - @android:drawable/ic_menu_camera
3 | - @android:drawable/ic_menu_gallery
4 | - @android:drawable/ic_menu_slideshow
5 | - @android:drawable/ic_menu_manage
6 | - @android:drawable/ic_menu_share
7 | - @android:drawable/ic_menu_send
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DailyImage
3 | Open navigation drawer
4 | Close navigation drawer
5 | Android Studio
6 | android.studio@android.com
7 | Navigation header
8 | Settings
9 | 数据转换出错
10 | 未知错误
11 | 服务器错误
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/app_widget_provider_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/app_widget_provider_info_large.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/test/java/tech/nicesky/dailyimage/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package tech.nicesky.dailyimage;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
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 | apply from: "config.gradle"
3 |
4 | buildscript {
5 |
6 | repositories {
7 | google()
8 | jcenter()
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.1.4'
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/config.gradle:
--------------------------------------------------------------------------------
1 | ext {
2 | plugins = [
3 | library: 'com.android.library',
4 | android: 'com.android.application',
5 | ]
6 |
7 | android = [
8 | applicationId : "tech.nicesky.dailyimage",
9 | compileSdkVersion : 28,
10 | buildToolsVersion : "28.0.2",
11 |
12 | librayMinSdkVersion: 19,
13 | sampleMinSdkVersion: 19,
14 | targetSdkVersion : 28,
15 |
16 | versionCode : 2,
17 | versionName : "1.0.1",
18 | default_dependcy_version : "28.0.0-rc02",
19 | testRunner : "android.support.test.runner.AndroidJUnitRunner"
20 | ]
21 |
22 | dependencies = [
23 | junit : "junit:junit:4.12",
24 | expressoCore : "com.android.support.test.espresso:espresso-core:3.0.2",
25 |
26 | constraint_layout : "com.android.support.constraint:constraint-layout:1.1.3",
27 | appCompat : "com.android.support:appcompat-v7:${android["default_dependcy_version"]}",
28 | design : "com.android.support:design:${android["default_dependcy_version"]}",
29 | design : "com.android.support:design:${android["default_dependcy_version"]}",
30 |
31 | leakcanary : "com.squareup.leakcanary:leakcanary-android-no-op:1.6.1",
32 | // Optional, if you use support library fragments:
33 | leakcanaryFragment : "com.squareup.leakcanary:leakcanary-support-fragment:1.6.1",
34 |
35 | okalle : "com.yanzhenjie:okalle:0.1.4",
36 | fastjson : "com.alibaba:fastjson:1.1.70.android",
37 |
38 | autosize : "me.jessyan:autosize:0.9.5"
39 | ]
40 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Oct 08 10:39:51 CST 2018
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-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/release/DailyImageWidget_1.0.0.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/release/DailyImageWidget_1.0.0.apk
--------------------------------------------------------------------------------
/release/DailyImageWidget_1.0.1.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fairytale110/DailyImageWidget/a221408aa6eaee22c7a4d26cf8411bb0d0396bea/release/DailyImageWidget_1.0.1.apk
--------------------------------------------------------------------------------
/release/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------