├── .gitignore
├── .idea
├── libraries
│ └── Gradle__com_squareup_okhttp3_okhttp_3_11_0_jar.xml
└── vcs.xml
├── CyxbsMobile_Android_Refactoring.iml
├── app
├── .gitignore
├── app.iml
├── build.gradle
├── proguard-rules.pro
├── release
│ ├── output.json
│ ├── widget-v1.0.apk
│ └── widget-v1.1.apk
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── zia
│ │ └── widget
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-web.png
│ ├── java
│ │ └── com
│ │ │ └── zia
│ │ │ └── widget
│ │ │ ├── bean
│ │ │ ├── Config.java
│ │ │ └── Course.kt
│ │ │ ├── net
│ │ │ ├── SSLSocketClient.java
│ │ │ └── Service.kt
│ │ │ ├── page
│ │ │ ├── ConfigActivity.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── little
│ │ │ │ └── LittleConfigActivity.kt
│ │ │ ├── normal
│ │ │ │ └── NormalConfigActivity.kt
│ │ │ └── trans
│ │ │ │ ├── TransConfig.kt
│ │ │ │ └── TransConfigActivity.kt
│ │ │ ├── util
│ │ │ ├── AutoUpdateCourse.kt
│ │ │ ├── FileUtil.kt
│ │ │ ├── ShortcutsUtil.java
│ │ │ ├── TimeUtil.kt
│ │ │ ├── Util.kt
│ │ │ ├── Version.kt
│ │ │ └── downlaodUtil
│ │ │ │ ├── DownLoaderHelper.java
│ │ │ │ ├── DownloadListener.java
│ │ │ │ ├── DownloadRunnable.java
│ │ │ │ └── ReLocateUtil.java
│ │ │ └── widget
│ │ │ ├── little
│ │ │ ├── BaseLittleWidget.kt
│ │ │ ├── LittleTransWidget.kt
│ │ │ └── LittleWidget.kt
│ │ │ └── normal
│ │ │ └── NormalWidget.kt
│ └── res
│ │ ├── drawable-v24
│ │ ├── widget_back.png
│ │ ├── widget_bg_title.xml
│ │ ├── widget_down.png
│ │ ├── widget_fresh.png
│ │ ├── widget_front.png
│ │ ├── widget_ic_launcher_foreground.xml
│ │ ├── widget_little_example.png
│ │ ├── widget_little_trans_example.png
│ │ ├── widget_normal_example.png
│ │ └── widget_up.png
│ │ ├── drawable
│ │ ├── widget_back.png
│ │ ├── widget_bg_button.xml
│ │ ├── widget_bg_savebt.xml
│ │ ├── widget_bg_title.xml
│ │ ├── widget_down.png
│ │ ├── widget_fresh.png
│ │ ├── widget_front.png
│ │ ├── widget_ic_launcher_background.xml
│ │ ├── widget_ic_launcher_foreground.xml
│ │ ├── widget_little_example.png
│ │ ├── widget_little_trans_example.png
│ │ ├── widget_normal_example.png
│ │ └── widget_up.png
│ │ ├── layout
│ │ ├── widget_activity_config.xml
│ │ ├── widget_activity_little_config.xml
│ │ ├── widget_activity_main.xml
│ │ ├── widget_activity_normal_config.xml
│ │ ├── widget_activity_trans_config.xml
│ │ ├── widget_little.xml
│ │ ├── widget_little_trans.xml
│ │ └── widget_normal.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ ├── file_path.xml
│ │ ├── network_security_config.xml
│ │ ├── widget_little.xml
│ │ ├── widget_little_trans.xml
│ │ └── widget_normal.xml
│ └── test
│ └── java
│ └── com
│ └── zia
│ └── widget
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── readme.md
├── screenshots
└── example1.png
├── settings.gradle
└── widget.iml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | .idea
5 | /.idea
6 | /.idea/caches/build_file_checksums.ser
7 | /.idea/libraries
8 | /.idea/modules.xml
9 | /.idea/workspace.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_squareup_okhttp3_okhttp_3_11_0_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CyxbsMobile_Android_Refactoring.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | build/*
3 | release/*
4 | /release/*
5 | *.iml
6 | .gradle
7 | /local.properties
8 | .idea
9 | /.idea
10 | /.idea/caches/build_file_checksums.ser
11 | /.idea/libraries
12 | /.idea/modules.xml
13 | /.idea/workspace.xml
14 | .DS_Store
15 | /captures
16 | .externalNativeBuild
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | android {
8 | compileSdkVersion 28
9 | defaultConfig {
10 | applicationId "com.zia.widget"
11 | minSdkVersion 19
12 | targetSdkVersion 28
13 | versionCode 5
14 | versionName "1.4"
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled true
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | packagingOptions {
27 | exclude 'META-INF/LICENSE.txt'
28 | exclude 'META-INF/NOTICE.txt'
29 | }
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | lintOptions {
37 | abortOnError false
38 | }
39 | }
40 |
41 | dependencies {
42 | implementation fileTree(include: ['*.jar'], dir: 'libs')
43 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
44 | implementation 'com.android.support:appcompat-v7:28.0.0'
45 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
46 | implementation 'com.android.support:support-v4:28.0.0'
47 | testImplementation 'junit:junit:4.12'
48 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
49 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
50 | implementation 'com.android.support:cardview-v7:28.0.0'
51 | implementation 'com.android.support:design:28.0.0'
52 | implementation 'com.jaredrummler:colorpicker:1.0.2'
53 | implementation 'com.google.code.gson:gson:2.8.5'
54 | implementation 'com.github.tbruyelle:rxpermissions:0.10.2'
55 | implementation 'com.tencent.bugly:crashreport_upgrade:1.3.5'
56 | implementation 'com.tencent.bugly:nativecrashreport:3.3.1'
57 | implementation 'com.squareup.okhttp3:okhttp:3.11.0'
58 | }
59 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/dayaa/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | #-------------------------------------------定制化区域----------------------------------------------
20 | #---------------------------------1.实体类---------------------------------
21 | -keep class com.zia.widget.bean.**{ *; }
22 | -keep class com.zia.widget.net.**{ *;}
23 |
24 |
25 | -keep public class * extends android.app.Fragment
26 | #-keepclasseswithmembernames class * { # 保持native方法不被混淆
27 | # native ;
28 | #}
29 | #-------------------------------------------------------------------------
30 |
31 | #---------------------------------2.第三方包-------------------------------
32 |
33 | -dontwarn org.simpleframework.xml.stream.**
34 | -keep class org.simpleframework.xml.** { *; }
35 |
36 |
37 | -dontwarn com.a.a.**
38 | -dontwarn com.autonavi.**
39 | -ignorewarnings
40 |
41 |
42 | -keep class com.autonavi.** {*;}
43 | -keep class com.a.a.** {*;}
44 | #-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
45 | #okhttp with retrofit
46 |
47 | -keepattributes Signature
48 | -keepattributes *Annotation*
49 | -keep class com.squareup.okhttp3.** { *; }
50 | -keep interface com.squareup.okhttp3.** { *; }
51 | -dontwarn com.squareup.okhttp3.**
52 |
53 |
54 | -keep class okhttp3.** { *; }
55 |
56 | -keep interface okhttp3.** { *; }
57 |
58 | -dontwarn okhttp3.**
59 |
60 | -dontwarn rx.**
61 | -dontwarn retrofit2.**
62 | -keep class retrofit2.** { *; }
63 | -keepclasseswithmembers class * {
64 | @retrofit.http.* ;
65 | }
66 |
67 | -keep class sun.misc.Unsafe { *; }
68 |
69 | -dontwarn okio.**
70 | -dontwarn com.squareup.retrofit2.**
71 | -dontwarn retrofit.appengine.UrlFetchClient
72 |
73 | -keep class com.tbruyelle.rxpermissions.**{*;}
74 | -keep class rxpermissions.**{*;}
75 | -keep interface rxpermissions.**{*;}
76 |
77 | #your package path where your gson models are stored
78 |
79 | #gson
80 | -keepattributes Signature
81 | -keepattributes *Annotation*
82 | -keep class sun.misc.Unsafe { *; }
83 | -keep class com.google.gson.stream.** { *; }
84 |
85 | #rxjava
86 | -dontwarn sun.misc.**
87 |
88 | -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
89 | long producerIndex;
90 | long consumerIndex;
91 | }
92 |
93 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
94 | rx.internal.util.atomic.LinkedQueueNode producerNode;
95 | }
96 |
97 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
98 | rx.internal.util.atomic.LinkedQueueNode consumerNode;
99 | }
100 | #rxandroid
101 | -keep class rx.schedulers.Schedulers {
102 | public static ;
103 | }
104 | -keep class rx.schedulers.ImmediateScheduler {
105 | public ;
106 | }
107 | -keep class rx.schedulers.TestScheduler {
108 | public ;
109 | }
110 | -keep class rx.schedulers.Schedulers {
111 | public static ** test();
112 | }
113 | -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
114 | long producerIndex;
115 | long consumerIndex;
116 | }
117 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
118 | long producerNode;
119 | long consumerNode;
120 | }
121 |
122 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
123 | rx.internal.util.atomic.LinkedQueueNode producerNode;
124 | }
125 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
126 | rx.internal.util.atomic.LinkedQueueNode consumerNode;
127 | }
128 | -keepclassmembers class rx.internal.util.unsafe.** {
129 | long producerIndex;
130 | long consumerIndex;
131 | }
132 | -dontwarn rx.internal.util.unsafe.**
133 |
134 | #nineoldandroids
135 | -keep class com.nineoldandroids.** { *; }
136 |
137 | ##---------------End: proguard configuration for Gson ----------
138 |
139 | #-------------------------------------------------------------------------
140 |
141 | #---------------------------------3.与js互相调用的类------------------------
142 |
143 |
144 |
145 | #-------------------------------------------------------------------------
146 |
147 | #---------------------------------4.反射相关的类和方法-----------------------
148 |
149 |
150 |
151 | #----------------------------------------------------------------------------
152 | #---------------------------------------------------------------------------------------------------
153 |
154 | #-------------------------------------------基本不用动区域--------------------------------------------
155 | #---------------------------------基本指令区----------------------------------
156 | -optimizationpasses 5
157 | -dontusemixedcaseclassnames
158 | -dontskipnonpubliclibraryclasses
159 | -dontskipnonpubliclibraryclassmembers
160 | -dontpreverify
161 | -verbose
162 | -printmapping proguardMapping.txt
163 | -optimizations !code/simplification/cast,!field/*,!class/merging/*
164 | -keepattributes *Annotation*,InnerClasses
165 | -keepattributes Signature
166 | -keepattributes SourceFile,LineNumberTable
167 | #----------------------------------------------------------------------------
168 |
169 | #---------------------------------默认保留区---------------------------------
170 | -keep public class * extends android.app.Activity
171 | -keep public class * extends android.app.AppCompatActivity
172 | -keep public class * extends android.app.Application
173 | -keep public class * extends android.app.Service
174 | -keep public class * extends android.content.BroadcastReceiver
175 | -keep public class * extends android.content.ContentProvider
176 | -keep public class * extends android.app.backup.BackupAgentHelper
177 | -keep public class * extends android.preference.Preference
178 | -keep public class * extends android.view.View
179 | -keep public class com.android.vending.licensing.ILicensingService
180 | -keep class android.support.** {*;}
181 |
182 | -keepclasseswithmembernames class * {
183 | native ;
184 | }
185 | -keepclassmembers class * extends android.app.Activity{
186 | public void *(android.view.View);
187 | }
188 | -keepclassmembers enum * {
189 | public static **[] values();
190 | public static ** valueOf(java.lang.String);
191 | }
192 |
193 | -keep public class * extends android.view.View{
194 | *** get*();
195 | void set*(***);
196 | public (android.content.Context);
197 | public (android.content.Context, android.util.AttributeSet);
198 | public (android.content.Context, android.util.AttributeSet, int);
199 | }
200 | -keepclasseswithmembers class * {
201 | public (android.content.Context, android.util.AttributeSet);
202 | public (android.content.Context, android.util.AttributeSet, int);
203 | }
204 | -keep class * implements android.os.Parcelable {
205 | public static final android.os.Parcelable$Creator *;
206 | }
207 | -keepclassmembers class * implements java.io.Serializable {
208 | static final long serialVersionUID;
209 | private static final java.io.ObjectStreamField[] serialPersistentFields;
210 | private void writeObject(java.io.ObjectOutputStream);
211 | private void readObject(java.io.ObjectInputStream);
212 | java.lang.Object writeReplace();
213 | java.lang.Object readResolve();
214 | }
215 | -keep class **.R$* {
216 | *;
217 | }
218 | -keepclassmembers class * {
219 | void *(**On*Event);
220 | }
221 | #----------------------------------------------------------------------------
222 |
223 | #---------------------------------webview------------------------------------
224 | -keepclassmembers class fqcn.of.javascript.interface.for.Webview {
225 | public *;
226 | }
227 | -keepclassmembers class * extends android.webkit.WebViewClient {
228 | public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
229 | public boolean *(android.webkit.WebView, java.lang.String);
230 | }
231 | -keepclassmembers class * extends android.webkit.WebViewClient {
232 | public void *(android.webkit.WebView, jav.lang.String);
233 | }
234 | #----------------------------------------------------------------------------
235 | #---------------------------------------------------------------------------------------------------
236 |
237 | -dontwarn com.taobao.**
238 | -dontwarn anet.channel.**
239 | -dontwarn anetwork.channel.**
240 | -dontwarn org.android.**
241 | -dontwarn org.apache.thrift.**
242 | -dontwarn com.xiaomi.**
243 | -dontwarn com.huawei.**
244 |
245 | -keepattributes *Annotation*
246 |
247 | -keep class com.taobao.** {*;}
248 | -keep class org.android.** {*;}
249 | -keep class anet.channel.** {*;}
250 | -keep class com.umeng.** {*;}
251 | -keep class com.xiaomi.** {*;}
252 | -keep class com.huawei.** {*;}
253 | -keep class org.apache.thrift.** {*;}
254 |
255 | -keep class com.alibaba.sdk.android.**{*;}
256 | -keep class com.ut.**{*;}
257 | -keep class com.ta.**{*;}
258 |
259 | -keep public class **.R$*{
260 | public static final int *;
261 | }
262 |
263 | -dontshrink
264 | -keep,allowshrinking class com.umeng.message.* {
265 | public ;
266 | public ;
267 | }
268 | -keep,allowshrinking class com.umeng.message.protobuffer.MessageResponse$PushResponse$Info {
269 | public ;
270 | public ;
271 | }
272 | -keep,allowshrinking class com.umeng.message.protobuffer.MessageResponse$PushResponse$Info$Builder {
273 | public ;
274 | public ;
275 | }
276 | -keep,allowshrinking class org.android.agoo.impl.*{
277 | public ;
278 | public ;
279 | }
280 | -keep,allowshrinking class org.android.agoo.service.* {*;}
281 | -keep,allowshrinking class org.android.spdy.**{*;}
282 | -keep public class com.mredrock.cyxbs.R$*{
283 | public static final int *;
284 | }
285 |
--------------------------------------------------------------------------------
/app/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":3,"versionName":"1.2","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
--------------------------------------------------------------------------------
/app/release/widget-v1.0.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/release/widget-v1.0.apk
--------------------------------------------------------------------------------
/app/release/widget-v1.1.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/release/widget-v1.1.apk
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/zia/widget/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget
2 |
3 | import android.support.test.InstrumentationRegistry
4 | import android.support.test.runner.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getTargetContext()
22 | assertEquals("com.mredrock.cyxbs.module_widget", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 |
24 |
25 |
28 |
29 |
32 |
33 |
36 |
37 |
40 |
41 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
57 |
58 |
61 |
62 |
68 |
72 |
73 |
74 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
88 |
89 |
90 |
91 |
92 |
95 |
96 |
99 |
100 |
101 |
102 |
103 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/bean/Config.java:
--------------------------------------------------------------------------------
1 | package com.zia.widget.bean;
2 |
3 | /**
4 | * Created By zia on 2018/10/13.
5 | */
6 | public class Config {
7 | public String key;
8 | public int version;
9 | public String url;
10 | public String able;
11 | public String message;
12 | public String other;
13 |
14 | public Config(String key, int version, String url, String able, String message, String other) {
15 | this.key = key;
16 | this.version = version;
17 | this.url = url;
18 | this.able = able;
19 | this.message = message;
20 | this.other = other;
21 | }
22 |
23 | @Override
24 | public String toString() {
25 | return "Config{" +
26 | "key=" + key +
27 | ", version=" + version +
28 | ", url='" + url + '\'' +
29 | ", able=" + able +
30 | ", message='" + message + '\'' +
31 | ", other='" + other + '\'' +
32 | '}';
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/bean/Course.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.bean
2 |
3 | /**
4 | * Created by zia on 2018/10/9.
5 | */
6 | class Course {
7 |
8 | /**
9 | * status : 200
10 | * success : true
11 | * version : 18.9.8
12 | * term : 2018-2019学年第1学期
13 | * stuNum : 2016211541
14 | * data : [{"hash_day":0,"hash_lesson":1,"begin_lesson":3,"day":"星期一","lesson":"三四节","course":"飞盘中级","course_num":"A1090030","teacher":"王燕妮","classroom":"待定","rawWeek":"1-15周单周","weekModel":"single","weekBegin":1,"weekEnd":15,"week":[1,3,5,7,9,11,13,15],"type":"必修","period":2},{"hash_day":0,"hash_lesson":2,"begin_lesson":5,"day":"星期一","lesson":"五六节","course":"嵌入式系统设计A","course_num":"A2040080","teacher":"龙林波","classroom":"3104","rawWeek":"2-13周,16周","weekModel":"all","weekBegin":2,"weekEnd":16,"week":[2,3,4,5,6,7,8,9,10,11,12,13,16],"type":"选修","period":2},{"hash_day":1,"hash_lesson":0,"begin_lesson":1,"day":"星期二","lesson":"一二节","course":"计算机图形学B","course_num":"A2040291","teacher":"魏秉铎","classroom":"3101","rawWeek":"3-13周,16-17周","weekModel":"all","weekBegin":3,"weekEnd":17,"week":[3,4,5,6,7,8,9,10,11,12,13,16,17],"type":"选修","period":2},{"hash_day":1,"hash_lesson":0,"begin_lesson":1,"day":"星期二","lesson":"一二节","course":"电装实习","course_num":"A2080010","teacher":"罗萍","classroom":"电力系统仿真实验室(综合实验楼A606/A607)","rawWeek":"1周","weekModel":"all","weekBegin":1,"weekEnd":1,"week":[1],"type":"必修","period":4},{"hash_day":1,"hash_lesson":2,"begin_lesson":5,"day":"星期二","lesson":"五六节","course":"计算机网络B","course_num":"A2040050","teacher":"黄俊(信息)","classroom":"3508","rawWeek":"2-13周,16-18周","weekModel":"all","weekBegin":2,"weekEnd":18,"week":[2,3,4,5,6,7,8,9,10,11,12,13,16,17,18],"type":"必修","period":2},{"hash_day":1,"hash_lesson":2,"begin_lesson":5,"day":"星期二","lesson":"五六节","course":"课程设计(计算机网络)","course_num":"A2040300","teacher":"杜欢","classroom":"数据科学与大数据技术实验室(综合实验楼B516/B517)","rawWeek":"18周","weekModel":"all","weekBegin":18,"weekEnd":18,"week":[18],"type":"必修","period":4},{"hash_day":1,"hash_lesson":2,"begin_lesson":5,"day":"星期二","lesson":"五六节","course":"课程设计(软件综合设计开发)","course_num":"A2040450","teacher":"刘伯红","classroom":"计算机系统实验室(综合实验楼B505/B506)","rawWeek":"19周","weekModel":"all","weekBegin":19,"weekEnd":19,"week":[19],"type":"必修","period":4},{"hash_day":1,"hash_lesson":2,"begin_lesson":5,"day":"星期二","lesson":"五六节","course":"金工实习B","course_num":"A2140010","teacher":"朱小均","classroom":"先进设计技术实训室207","rawWeek":"14周","weekModel":"all","weekBegin":14,"weekEnd":14,"week":[14],"type":"必修","period":4},{"hash_day":2,"hash_lesson":0,"begin_lesson":1,"day":"星期三","lesson":"一二节","course":"电装实习","course_num":"A2080010","teacher":"王大军","classroom":"PCB实训室(实训楼301)","rawWeek":"1周","weekModel":"all","weekBegin":1,"weekEnd":1,"week":[1],"type":"必修","period":4},{"hash_day":2,"hash_lesson":1,"begin_lesson":3,"day":"星期三","lesson":"三四节","course":"WEB动态网页设计","course_num":"A2040010","teacher":"刘立","classroom":"3101","rawWeek":"2-13周,16-18周","weekModel":"all","weekBegin":2,"weekEnd":18,"week":[2,3,4,5,6,7,8,9,10,11,12,13,16,17,18],"type":"选修","period":2},{"hash_day":2,"hash_lesson":2,"begin_lesson":5,"day":"星期三","lesson":"五六节","course":"课程设计(计算机网络)","course_num":"A2040300","teacher":"杜欢","classroom":"数据科学与大数据技术实验室(综合实验楼B516/B517)","rawWeek":"18周","weekModel":"all","weekBegin":18,"weekEnd":18,"week":[18],"type":"必修","period":4},{"hash_day":2,"hash_lesson":2,"begin_lesson":5,"day":"星期三","lesson":"五六节","course":"课程设计(软件综合设计开发)","course_num":"A2040450","teacher":"刘伯红","classroom":"计算机系统实验室(综合实验楼B505/B506)","rawWeek":"19周","weekModel":"all","weekBegin":19,"weekEnd":19,"week":[19],"type":"必修","period":4},{"hash_day":2,"hash_lesson":2,"begin_lesson":5,"day":"星期三","lesson":"五六节","course":"金工实习B","course_num":"A2140010","teacher":"朱小均","classroom":"先进设计技术实训室207","rawWeek":"14周","weekModel":"all","weekBegin":14,"weekEnd":14,"week":[14],"type":"必修","period":4},{"hash_day":2,"hash_lesson":3,"begin_lesson":7,"day":"星期三","lesson":"七八节","course":"数据挖掘基础B","course_num":"A2040501","teacher":"刘群","classroom":"3207","rawWeek":"2-13周,16-17周","weekModel":"all","weekBegin":2,"weekEnd":17,"week":[2,3,4,5,6,7,8,9,10,11,12,13,16,17],"type":"选修","period":2},{"hash_day":3,"hash_lesson":0,"begin_lesson":1,"day":"星期四","lesson":"一二节","course":"计算机网络B","course_num":"A2040050","teacher":"黄俊(信息)","classroom":"3508","rawWeek":"3-13周单周,17周","weekModel":"single","weekBegin":3,"weekEnd":17,"week":[3,5,7,9,11,13,17],"type":"必修","period":2},{"hash_day":3,"hash_lesson":0,"begin_lesson":1,"day":"星期四","lesson":"一二节","course":"电装实习","course_num":"A2080010","teacher":"陈绍明","classroom":"SMT实训室(实训楼302)","rawWeek":"1周","weekModel":"all","weekBegin":1,"weekEnd":1,"week":[1],"type":"必修","period":4},{"hash_day":3,"hash_lesson":1,"begin_lesson":3,"day":"星期四","lesson":"三四节","course":"嵌入式系统设计A","course_num":"A2040080","teacher":"曾素华","classroom":"智能终端实验室(综合实验楼B509/B510)","rawWeek":"9-16周","weekModel":"all","weekBegin":9,"weekEnd":16,"week":[9,10,11,12,13,14,15,16],"type":"选修","period":2},{"hash_day":3,"hash_lesson":2,"begin_lesson":5,"day":"星期四","lesson":"五六节","course":"课程设计(计算机网络)","course_num":"A2040300","teacher":"杜欢","classroom":"数据科学与大数据技术实验室(综合实验楼B516/B517)","rawWeek":"18周","weekModel":"all","weekBegin":18,"weekEnd":18,"week":[18],"type":"必修","period":4},{"hash_day":3,"hash_lesson":2,"begin_lesson":5,"day":"星期四","lesson":"五六节","course":"课程设计(软件综合设计开发)","course_num":"A2040450","teacher":"刘伯红","classroom":"计算机系统实验室(综合实验楼B505/B506)","rawWeek":"19周","weekModel":"all","weekBegin":19,"weekEnd":19,"week":[19],"type":"必修","period":4},{"hash_day":3,"hash_lesson":2,"begin_lesson":5,"day":"星期四","lesson":"五六节","course":"金工实习B","course_num":"A2140010","teacher":"朱小均","classroom":"先进设计技术实训室207","rawWeek":"14周","weekModel":"all","weekBegin":14,"weekEnd":14,"week":[14],"type":"必修","period":4},{"hash_day":3,"hash_lesson":4,"begin_lesson":9,"day":"星期四","lesson":"九十节","course":"嵌入式系统设计A","course_num":"A2040080","teacher":"龙林波","classroom":"3104","rawWeek":"2-12周双周,16周","weekModel":"double","weekBegin":2,"weekEnd":16,"week":[2,4,6,8,10,12,16],"type":"选修","period":2},{"hash_day":4,"hash_lesson":0,"begin_lesson":1,"day":"星期五","lesson":"一二节","course":"中国近现代史纲要","course_num":"A1100040","teacher":"邓庆伟","classroom":"3301","rawWeek":"2-11周","weekModel":"all","weekBegin":2,"weekEnd":11,"week":[2,3,4,5,6,7,8,9,10,11],"type":"必修","period":2},{"hash_day":4,"hash_lesson":0,"begin_lesson":1,"day":"星期五","lesson":"一二节","course":"课程设计(计算机网络)","course_num":"A2040300","teacher":"杜欢","classroom":"数据科学与大数据技术实验室(综合实验楼B516/B517)","rawWeek":"18周","weekModel":"all","weekBegin":18,"weekEnd":18,"week":[18],"type":"必修","period":4},{"hash_day":4,"hash_lesson":0,"begin_lesson":1,"day":"星期五","lesson":"一二节","course":"课程设计(软件综合设计开发)","course_num":"A2040450","teacher":"刘伯红","classroom":"计算机系统实验室(综合实验楼B505/B506)","rawWeek":"19周","weekModel":"all","weekBegin":19,"weekEnd":19,"week":[19],"type":"必修","period":4},{"hash_day":4,"hash_lesson":0,"begin_lesson":1,"day":"星期五","lesson":"一二节","course":"电装实习","course_num":"A2080010","teacher":"林海波","classroom":"电装实训室(先进制造实训楼A303)","rawWeek":"1周","weekModel":"all","weekBegin":1,"weekEnd":1,"week":[1],"type":"必修","period":4},{"hash_day":4,"hash_lesson":2,"begin_lesson":5,"day":"星期五","lesson":"五六节","course":"形势与政策","course_num":"A1100010","teacher":"郑兴刚","classroom":"2402","rawWeek":"5-8周","weekModel":"all","weekBegin":5,"weekEnd":8,"week":[5,6,7,8],"type":"必修","period":2},{"hash_day":4,"hash_lesson":2,"begin_lesson":5,"day":"星期五","lesson":"五六节","course":"金工实习B","course_num":"A2140010","teacher":"朱小均","classroom":"先进设计技术实训室207","rawWeek":"14周","weekModel":"all","weekBegin":14,"weekEnd":14,"week":[14],"type":"必修","period":4}]
15 | * cachedTimestamp : 1539089073698
16 | * outOfDateTimestamp : 1539693873698
17 | * nowWeek : 5
18 | */
19 |
20 | var status: Int = 0
21 | var isSuccess: Boolean = false
22 | var version: String? = null
23 | var term: String? = null
24 | var stuNum: String? = null
25 | var cachedTimestamp: Long = 0
26 | var outOfDateTimestamp: Long = 0
27 | var nowWeek: Int = 0
28 | var data: List? = null
29 |
30 | override fun toString(): String {
31 | return "Course{" +
32 | "status=" + status +
33 | ", success=" + isSuccess +
34 | ", version='" + version + '\''.toString() +
35 | ", term='" + term + '\''.toString() +
36 | ", stuNum='" + stuNum + '\''.toString() +
37 | ", cachedTimestamp=" + cachedTimestamp +
38 | ", outOfDateTimestamp=" + outOfDateTimestamp +
39 | ", nowWeek=" + nowWeek +
40 | ", data=" + data +
41 | '}'.toString()
42 | }
43 |
44 | class DataBean {
45 | /**
46 | * hash_day : 0
47 | * hash_lesson : 1
48 | * begin_lesson : 3
49 | * day : 星期一
50 | * lesson : 三四节
51 | * course : 飞盘中级
52 | * course_num : A1090030
53 | * teacher : 王燕妮
54 | * classroom : 待定
55 | * rawWeek : 1-15周单周
56 | * weekModel : single
57 | * weekBegin : 1
58 | * weekEnd : 15
59 | * week : [1,3,5,7,9,11,13,15]
60 | * type : 必修
61 | * period : 2
62 | */
63 |
64 | var hash_day: Int = 0
65 | var hash_lesson: Int = 0
66 | var begin_lesson: Int = 0
67 | var day: String? = null
68 | var lesson: String? = null
69 | var course: String? = null
70 | var course_num: String? = null
71 | var teacher: String? = null
72 | var classroom: String? = null
73 | var rawWeek: String? = null
74 | var weekModel: String? = null
75 | var weekBegin: Int = 0
76 | var weekEnd: Int = 0
77 | var type: String? = null
78 | var period: Int = 0
79 | var week: List? = null
80 |
81 | override fun toString(): String {
82 | return "DataBean{" +
83 | "hash_day=" + hash_day +
84 | ", hash_lesson=" + hash_lesson +
85 | ", begin_lesson=" + begin_lesson +
86 | ", day='" + day + '\''.toString() +
87 | ", lesson='" + lesson + '\''.toString() +
88 | ", course='" + course + '\''.toString() +
89 | ", course_num='" + course_num + '\''.toString() +
90 | ", classroom='" + classroom + '\''.toString() +
91 | ", rawWeek='" + rawWeek + '\''.toString() +
92 | ", weekModel='" + weekModel + '\''.toString() +
93 | ", weekBegin=" + weekBegin +
94 | ", weekEnd=" + weekEnd +
95 | ", type='" + type + '\''.toString() +
96 | ", period=" + period +
97 | ", week=" + week +
98 | '}'.toString()
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/net/SSLSocketClient.java:
--------------------------------------------------------------------------------
1 | package com.zia.widget.net;
2 |
3 | import java.security.SecureRandom;
4 | import java.security.cert.X509Certificate;
5 |
6 | import javax.net.ssl.HostnameVerifier;
7 | import javax.net.ssl.SSLContext;
8 | import javax.net.ssl.SSLSocketFactory;
9 | import javax.net.ssl.TrustManager;
10 | import javax.net.ssl.X509TrustManager;
11 |
12 | /**
13 | * 忽略https证书验证
14 | */
15 |
16 | public class SSLSocketClient {
17 | //获取这个SSLSocketFactory
18 | public static SSLSocketFactory getSSLSocketFactory() {
19 | try {
20 | SSLContext sslContext = SSLContext.getInstance("SSL");
21 | sslContext.init(null, getTrustManager(), new SecureRandom());
22 | return sslContext.getSocketFactory();
23 | } catch (Exception e) {
24 | throw new RuntimeException(e);
25 | }
26 | }
27 |
28 | //获取TrustManager
29 | private static TrustManager[] getTrustManager() {
30 | return new TrustManager[]{new X509TrustManager() {
31 | @Override
32 | public void checkClientTrusted(X509Certificate[] chain, String authType) {
33 | }
34 |
35 | @Override
36 | public void checkServerTrusted(X509Certificate[] chain, String authType) {
37 | }
38 |
39 | @Override
40 | public X509Certificate[] getAcceptedIssuers() {
41 | return new X509Certificate[]{};
42 | }
43 | }};
44 | }
45 |
46 | //获取HostnameVerifier
47 | public static HostnameVerifier getHostnameVerifier() {
48 | return (s, sslSession) -> true;
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/net/Service.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.net
2 |
3 | import okhttp3.OkHttpClient
4 | import java.util.concurrent.TimeUnit
5 |
6 | /**
7 | * Created by zia on 2018/10/16.
8 | */
9 | object Service {
10 | val okHttpClient = OkHttpClient.Builder()
11 | .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
12 | .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
13 | .connectTimeout(5, TimeUnit.SECONDS)
14 | .writeTimeout(10, TimeUnit.SECONDS)
15 | .readTimeout(20, TimeUnit.SECONDS)
16 | .build()
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/page/ConfigActivity.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.page
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.support.v7.app.AppCompatActivity
6 | import com.zia.widget.R
7 | import com.zia.widget.page.little.LittleConfigActivity
8 | import com.zia.widget.page.normal.NormalConfigActivity
9 | import com.zia.widget.page.trans.TransConfigActivity
10 | import kotlinx.android.synthetic.main.widget_activity_config.*
11 |
12 |
13 | /**
14 | * Created by zia on 2018/10/11.
15 | * 设置主页面
16 | */
17 | class ConfigActivity : AppCompatActivity() {
18 |
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 | setContentView(R.layout.widget_activity_config)
22 |
23 | widget_config_littleTransLayout.setOnClickListener {
24 | startActivity(Intent(this@ConfigActivity, TransConfigActivity::class.java))
25 | }
26 |
27 | widget_config_littleLayout.setOnClickListener {
28 | startActivity(Intent(this@ConfigActivity, LittleConfigActivity::class.java))
29 | }
30 |
31 | widget_config_normalLayout.setOnClickListener {
32 | startActivity(Intent(this@ConfigActivity, NormalConfigActivity::class.java))
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/page/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.page
2 |
3 | import android.Manifest
4 | import android.annotation.SuppressLint
5 | import android.app.ProgressDialog
6 | import android.content.ClipData
7 | import android.content.ClipboardManager
8 | import android.content.Intent
9 | import android.content.pm.ShortcutInfo
10 | import android.graphics.drawable.Icon
11 | import android.net.Uri
12 | import android.os.Build
13 | import android.os.Bundle
14 | import android.os.Environment
15 | import android.support.v7.app.AlertDialog
16 | import android.support.v7.app.AppCompatActivity
17 | import android.widget.Toast
18 | import com.google.gson.Gson
19 | import com.tbruyelle.rxpermissions2.RxPermissions
20 | import com.tencent.bugly.crashreport.CrashReport
21 | import com.zia.widget.R
22 | import com.zia.widget.bean.Config
23 | import com.zia.widget.bean.Course
24 | import com.zia.widget.net.Service
25 | import com.zia.widget.util.*
26 | import com.zia.widget.util.downlaodUtil.DownloadRunnable
27 | import com.zia.widget.widget.little.LittleTransWidget
28 | import com.zia.widget.widget.little.LittleWidget
29 | import com.zia.widget.widget.normal.NormalWidget
30 | import kotlinx.android.synthetic.main.widget_activity_main.*
31 | import okhttp3.*
32 | import java.io.File
33 | import java.io.IOException
34 |
35 |
36 | /**
37 | * Created by zia on 2018/10/10.
38 | * 小部件独立模块的界面,用于登录,验证
39 | */
40 | class MainActivity : AppCompatActivity() {
41 |
42 | private lateinit var rxPermissions: RxPermissions
43 |
44 | @SuppressLint("SetTextI18n")
45 | override fun onCreate(savedInstanceState: Bundle?) {
46 | super.onCreate(savedInstanceState)
47 | setContentView(R.layout.widget_activity_main)
48 |
49 | CrashReport.initCrashReport(applicationContext)
50 |
51 | addShortcut()
52 |
53 | rxPermissions = RxPermissions(this@MainActivity)
54 |
55 | widget_main_version.text = "v${Version.packageName(this)}"
56 |
57 | checkVersion()
58 |
59 | widget_main_configBt.setOnClickListener { startActivity(Intent(this@MainActivity, ConfigActivity::class.java)) }
60 |
61 | widget_main_joinGroup.setOnClickListener { joinQQ() }
62 |
63 | initViews()
64 |
65 | val needFresh = intent.getBooleanExtra("needFresh", false)
66 | if (needFresh) {
67 | Toast.makeText(this, "正在更新", Toast.LENGTH_SHORT).show()
68 | refresh(defaultSharedPreferences.getString(SP_STUNUM, ""))
69 | }
70 |
71 | //修复自动更新bug,设置为不自动更新
72 | defaultSharedPreferences.editor {
73 | putBoolean(SP_IS_AUTO_UPDATE, false)
74 | }
75 | }
76 |
77 | private fun checkVersion() {
78 | val versionRequest = Request.Builder()
79 | .url("http://zzzia.net:8080/version/get")
80 | .post(FormBody.Builder().add("key", "widget").build())
81 | .build()
82 |
83 | showWaitDialog()
84 | Service.okHttpClient.newCall(versionRequest).enqueue(object : Callback {
85 | override fun onFailure(call: Call, e: IOException) {
86 | runOnUiThread {
87 | hideWaitDialog()
88 | e.printStackTrace()
89 | showErrorDialog("连接服务器失败,请检查网络")
90 | }
91 | }
92 |
93 | override fun onResponse(call: Call, response: Response) {
94 | val json = response.body()?.string()
95 |
96 | runOnUiThread {
97 | hideWaitDialog()
98 | val config = Gson().fromJson(json, Config::class.java)
99 | if (config == null || config.able != "true") {
100 | //服务器认证失败,无法访问
101 | showErrorDialog("由于某些原因,软件不再提供使用")
102 | } else if (config.version > Version.packageCode(this@MainActivity)) {
103 | showUpdateDialog(config)
104 | }
105 | }
106 | }
107 |
108 | })
109 | }
110 |
111 | private fun initViews() {
112 | //填充学号记录
113 | val stuNumHistory = defaultSharedPreferences.getString(SP_STUNUM, "")
114 | widget_main_stuNumEt.setText(stuNumHistory)
115 | //填充自动更新记录
116 | // val isAutoUpdate = defaultSharedPreferences.getBoolean(SP_IS_AUTO_UPDATE, false)
117 | // widget_main_autoUpdate_check.isChecked = isAutoUpdate
118 | //
119 | // widget_main_autoUpdate_check.setOnTouchListener { _, _ ->
120 | // return@setOnTouchListener false
121 | // }
122 |
123 | //自动更新点击事件
124 | // widget_main_autoUpdate_layout.setOnClickListener {
125 | // val checked = !widget_main_autoUpdate_check.isChecked
126 | // widget_main_autoUpdate_check.isChecked = checked
127 | // Log.d(javaClass.simpleName, "checked:$checked")
128 | // defaultSharedPreferences.editor {
129 | // putBoolean(SP_IS_AUTO_UPDATE, checked)
130 | // }
131 | // if (checked) {
132 | // autoFreshCourse(this)
133 | // }
134 | // }
135 |
136 | //刷新课表点击事件
137 | widget_main_loginBt.setOnClickListener {
138 |
139 | val stuNum = widget_main_stuNumEt.text.toString()
140 |
141 | if (stuNum.isEmpty() || stuNum.length < 4) {
142 | Toast.makeText(this, "请输入学号", Toast.LENGTH_SHORT).show()
143 | return@setOnClickListener
144 | }
145 |
146 | refresh(stuNum)
147 | }
148 | }
149 |
150 | private fun refresh(stuNum: String?) {
151 | if (stuNum == null || stuNum.isEmpty()) {
152 | Toast.makeText(this, "还没有填写账号", Toast.LENGTH_SHORT).show()
153 | return
154 | }
155 | val courseRequest = Request.Builder()
156 | .url("https://wx.idsbllp.cn/api/kebiao")
157 | .post(FormBody.Builder().add("stuNum", stuNum).build())
158 | .build()
159 |
160 | showWaitDialog()
161 |
162 | Service.okHttpClient.newCall(courseRequest).enqueue(object : Callback {
163 | override fun onFailure(call: Call, e: IOException) {
164 | runOnUiThread {
165 | hideWaitDialog()
166 | e.printStackTrace()
167 | Toast.makeText(this@MainActivity, "网络出错", Toast.LENGTH_SHORT).show()
168 | }
169 | }
170 |
171 | override fun onResponse(call: Call, response: Response) {
172 | val json = response.body()?.string()
173 | val course: Course
174 | try {
175 | //服务器数据有问题时json解析会出错
176 | course = Gson().fromJson(json, Course::class.java)
177 | } catch (e: java.lang.Exception) {
178 | Toast.makeText(this@MainActivity, "服务器数据出了点问题..", Toast.LENGTH_SHORT).show()
179 | return
180 | }
181 |
182 | runOnUiThread {
183 | hideWaitDialog()
184 | if (course.data == null) {
185 | Toast.makeText(this@MainActivity, "服务器没有课表...", Toast.LENGTH_SHORT).show()
186 | return@runOnUiThread
187 | }
188 | defaultSharedPreferences.editor {
189 | putString(WIDGET_COURSE, json)
190 | putBoolean(SP_WIDGET_NEED_FRESH, true)
191 | putString(SP_STUNUM, stuNum)
192 | }
193 | LittleTransWidget().refresh(this@MainActivity)
194 | LittleWidget().refresh(this@MainActivity)
195 | NormalWidget().fresh(this@MainActivity, 0)
196 | Toast.makeText(this@MainActivity, "更新成功", Toast.LENGTH_SHORT).show()
197 | }
198 | }
199 |
200 | })
201 | }
202 |
203 | private fun showUpdateDialog(config: Config) {
204 | AlertDialog.Builder(this)
205 | .setTitle("是否更新版本")
206 | .setMessage(config.message)
207 | .setNegativeButton("取消", null)
208 | .setPositiveButton("更新") { _, _ ->
209 | rxPermissions
210 | .request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
211 | .subscribe {
212 | if (it) {
213 | downloadApk(config.url)
214 | } else {
215 | Toast.makeText(this@MainActivity, "请提供文件读写权限..", Toast.LENGTH_SHORT).show()
216 | }
217 | }
218 | }
219 | .setCancelable(true)
220 | .show()
221 | }
222 |
223 | private fun downloadApk(url: String) {
224 | val dialog = ProgressDialog(this@MainActivity)
225 | dialog.setCancelable(false)
226 | dialog.progress = 0
227 | dialog.setTitle("正在下载")
228 | dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
229 | dialog.show()
230 |
231 | val apkName = "widget.apk"
232 | val savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path
233 |
234 | val downloadRunnable = DownloadRunnable(url, savePath, apkName) { ratio, part, total ->
235 | runOnUiThread {
236 | if (ratio == 100F) {
237 | dialog.dismiss()
238 | val intent = Intent(Intent.ACTION_VIEW)
239 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
240 | intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
241 | } else {
242 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
243 | }
244 | intent.setDataAndType(FileUtil.getFileUri(this@MainActivity, File(savePath, apkName)),
245 | "application/vnd.android.package-archive")
246 | this@MainActivity.startActivity(intent)
247 | return@runOnUiThread
248 | }
249 | dialog.progress = ratio.toInt()
250 | dialog.setProgressNumberFormat(String.format("%.2fm / %.2fm", part / 1024f / 1024f, total / 1024f / 1024f))
251 | }
252 | }
253 |
254 | Thread(downloadRunnable).start()
255 | }
256 |
257 | private fun showErrorDialog(massage: String) {
258 | AlertDialog.Builder(this)
259 | .setTitle("提示")
260 | .setMessage(massage)
261 | .setPositiveButton("确定") { _, _ -> finish() }
262 | .setCancelable(false)
263 | .show()
264 | }
265 |
266 | private val waitDialog by lazy {
267 | AlertDialog.Builder(this@MainActivity)
268 | .setTitle("请稍等")
269 | .setMessage("正在连接服务器")
270 | .setCancelable(false)
271 | .create()
272 | }
273 |
274 | private fun showWaitDialog() {
275 | if (!waitDialog.isShowing) {
276 | waitDialog.show()
277 | }
278 | }
279 |
280 | private fun hideWaitDialog() {
281 | if (waitDialog.isShowing) {
282 | waitDialog.dismiss()
283 | }
284 | }
285 |
286 | private fun joinQQGroup(key: String): Boolean {
287 | val intent = Intent()
288 | intent.data = Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D$key")
289 | // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
290 | return try {
291 | startActivity(intent)
292 | true
293 | } catch (e: Exception) {
294 | // 未安装手Q或安装的版本不支持
295 | false
296 | }
297 | }
298 |
299 | private fun joinQQ() {
300 | if (!joinQQGroup("DXvamN9Ox1Kthaab1N_0w7s5N3aUYVIf")) {
301 | val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
302 | val data = ClipData.newPlainText("QQ Group", "570919844")
303 | clipboard.primaryClip = data
304 | Toast.makeText(this, "抱歉,由于您未安装手机QQ或版本不支持,无法跳转至掌邮bug反馈群。" + "已将群号复制至您的手机剪贴板,请您手动添加",
305 | Toast.LENGTH_LONG).show()
306 | }
307 | }
308 |
309 | private fun addShortcut() {
310 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
311 | val intent = Intent(this, MainActivity::class.java)
312 | intent.action = Intent.ACTION_VIEW
313 | intent.putExtra("needFresh", true)
314 | val shortcut = ShortcutInfo.Builder(this, "update")
315 | .setShortLabel("刷新课表")
316 | .setLongLabel("刷新课表")
317 | .setRank(1)
318 | .setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher_round))
319 | .setIntent(intent)
320 | .build()
321 | ShortcutsUtil.addShortcut(this, shortcut)
322 | }
323 | }
324 | }
325 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/page/little/LittleConfigActivity.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.page.little
2 |
3 | import android.support.v7.app.AppCompatActivity
4 | import android.os.Bundle
5 | import com.zia.widget.R
6 |
7 | class LittleConfigActivity : AppCompatActivity() {
8 |
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | setContentView(R.layout.widget_activity_little_config)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/page/normal/NormalConfigActivity.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.page.normal
2 |
3 | import android.support.v7.app.AppCompatActivity
4 | import android.os.Bundle
5 | import com.zia.widget.R
6 |
7 | class NormalConfigActivity : AppCompatActivity() {
8 |
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | setContentView(R.layout.widget_activity_normal_config)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/page/trans/TransConfig.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.page.trans
2 |
3 | import android.content.Context
4 | import android.support.annotation.ColorInt
5 | import com.zia.widget.util.editor
6 | import com.zia.widget.util.sharedPreferences
7 |
8 | /**
9 | * Created by zia on 2018/10/11.
10 | */
11 | class TransConfig {
12 |
13 | private val shareName = "cyxbs_widget_trans_config"
14 |
15 | var timeTextSize = 15
16 | var courseTextSize = 19
17 | var roomTextSize = 15
18 |
19 | @ColorInt
20 | var timeTextColor = "#FFFFFF"
21 |
22 | @ColorInt
23 | var courseTextColor = "#FFFFFF"
24 |
25 | @ColorInt
26 | var roomTextColor = "#FFFFFF"
27 |
28 | @ColorInt
29 | var holderColor = "#FFFFFF"
30 |
31 | fun save(context: Context) {
32 | context.sharedPreferences(shareName).editor {
33 | putInt("timeTextSize", timeTextSize)
34 | putInt("courseTextSize", courseTextSize)
35 | putInt("roomTextSize", roomTextSize)
36 | putString("timeTextColor", timeTextColor)
37 | putString("courseTextColor", courseTextColor)
38 | putString("roomTextColor", roomTextColor)
39 | putString("holderColor", holderColor)
40 | }
41 | }
42 |
43 | override fun toString(): String {
44 | return "TransConfig(timeTextSize=$timeTextSize, courseTextSize=$courseTextSize, roomTextSize=$roomTextSize, timeTextColor='$timeTextColor', courseTextColor='$courseTextColor', roomTextColor='$roomTextColor', holderColor='$holderColor')"
45 | }
46 |
47 |
48 | companion object {
49 |
50 | fun getUserConfig(context: Context): TransConfig {
51 | return TransConfig().apply {
52 | timeTextColor = context.sharedPreferences(shareName).getString("timeTextColor", timeTextColor)
53 | courseTextColor = context.sharedPreferences(shareName).getString("courseTextColor", courseTextColor)
54 | roomTextColor = context.sharedPreferences(shareName).getString("roomTextColor", roomTextColor)
55 | holderColor = context.sharedPreferences(shareName).getString("holderColor", holderColor)
56 | timeTextSize = context.sharedPreferences(shareName).getInt("timeTextSize", timeTextSize)
57 | courseTextSize = context.sharedPreferences(shareName).getInt("courseTextSize", courseTextSize)
58 | roomTextSize = context.sharedPreferences(shareName).getInt("roomTextSize", roomTextSize)
59 | }
60 | }
61 |
62 | fun getDefaultWhite(): TransConfig {
63 | return TransConfig()
64 | }
65 |
66 | fun getDefaultBlack(): TransConfig {
67 | return TransConfig().apply {
68 | timeTextColor = "#000000"
69 | courseTextColor = "#000000"
70 | roomTextColor = "#000000"
71 | holderColor = "#E7E7E7"
72 | }
73 | }
74 |
75 | fun getDefaultPink(): TransConfig {
76 | return TransConfig().apply {
77 | timeTextColor = "#F1AAA6"
78 | courseTextColor = "#FF6E97"
79 | roomTextColor = "#FF6E97"
80 | holderColor = "#E2E2E2"
81 | }
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/page/trans/TransConfigActivity.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.page.trans
2 |
3 | import android.graphics.Color
4 | import android.os.Bundle
5 | import android.support.v7.app.AppCompatActivity
6 | import android.text.Editable
7 | import android.text.TextWatcher
8 | import android.view.View
9 | import android.widget.EditText
10 | import android.widget.SeekBar
11 | import android.widget.TextView
12 | import android.widget.Toast
13 | import com.jaredrummler.android.colorpicker.ColorPickerDialog
14 | import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
15 | import com.zia.widget.R
16 | import com.zia.widget.widget.little.LittleTransWidget
17 | import kotlinx.android.synthetic.main.widget_activity_trans_config.*
18 |
19 |
20 | /**
21 | * Created by zzzia on 2018/10/11.
22 | * 透明版设置
23 | * 写了一天辣鸡代码,等你们优化了
24 | */
25 | class TransConfigActivity : AppCompatActivity() {
26 |
27 | private val userConfig by lazy {
28 | TransConfig.getUserConfig(this@TransConfigActivity)
29 | }
30 |
31 | override fun onCreate(savedInstanceState: Bundle?) {
32 | super.onCreate(savedInstanceState)
33 | setContentView(R.layout.widget_activity_trans_config)
34 |
35 | //从数据库读配置文件并复制给所有控件
36 | setAll(userConfig)
37 |
38 | setEditListener()
39 |
40 | //设置颜色选择的点击事件,联动
41 | setColorPicker(widget_config_trans_courseColorLayout, widget_config_trans_courseColor, widget_config_trans_courseTv, widget_config_trans_courseColorEt)
42 | setColorPicker(widget_config_trans_timeColorLayout, widget_config_trans_timeColor, widget_config_trans_timeTv, widget_config_trans_timeColorEt)
43 | setColorPicker(widget_config_trans_roomColorLayout, widget_config_trans_roomColor, widget_config_trans_roomTv, widget_config_trans_roomColorEt)
44 | setColorPicker(widget_config_trans_holderColorLayout, widget_config_trans_holderColor, null, widget_config_trans_holderColorEt)
45 |
46 | //预设方案的点击事件
47 | widget_config_trans_default_black.setOnClickListener { setAll(TransConfig.getDefaultBlack()) }
48 | widget_config_trans_default_white.setOnClickListener { setAll(TransConfig.getDefaultWhite()) }
49 | widget_config_trans_default_pink.setOnClickListener { setAll(TransConfig.getDefaultPink()) }
50 |
51 | //保存按钮监听
52 | widget_config_trans_saveBt.setOnClickListener {
53 | val timeSize = widget_config_trans_timeSb.progress
54 | val courseSize = widget_config_trans_courseSb.progress
55 | val roomSize = widget_config_trans_roomSb.progress
56 |
57 | val timeColor = widget_config_trans_timeColorEt.text.toString().replace(Regex("[^(#A-Fa-f0-9)]"), "")
58 | val courseColor = widget_config_trans_courseColorEt.text.toString().replace(Regex("[^(#A-Fa-f0-9)]"), "")
59 | val roomColor = widget_config_trans_roomColorEt.text.toString().replace(Regex("[^(#A-Fa-f0-9)]"), "")
60 | val holderColor = widget_config_trans_holderColorEt.text.toString().replace(Regex("[^(#A-Fa-f0-9)]"), "")
61 |
62 | if ((timeColor.length != 7 && timeColor.length != 9) ||
63 | (courseColor.length != 7 && courseColor.length != 9) ||
64 | (roomColor.length != 7 && roomColor.length != 9) ||
65 | holderColor.length != 7 && holderColor.length != 9) {
66 | Toast.makeText(this@TransConfigActivity, "颜色有误,请修改,如#ffffff", Toast.LENGTH_SHORT).show()
67 | return@setOnClickListener
68 | }
69 |
70 | TransConfig().apply {
71 | this@apply.timeTextSize = timeSize
72 | this@apply.courseTextSize = courseSize
73 | this@apply.roomTextSize = roomSize
74 | this@apply.timeTextColor = timeColor
75 | this@apply.courseTextColor = courseColor
76 | this@apply.roomTextColor = roomColor
77 | this@apply.holderColor = holderColor
78 | }.save(this)
79 |
80 | LittleTransWidget().refresh(this@TransConfigActivity)
81 |
82 | Toast.makeText(this@TransConfigActivity, "已刷新", Toast.LENGTH_SHORT).show()
83 | }
84 | }
85 |
86 | private fun setAll(config: TransConfig) {
87 | setTvColor(config)
88 | setTextSize(config)
89 | setColorEditText(config)
90 | setPreviewColor(config)
91 |
92 | //设置拖动条的监听
93 | setSeekBar(config)
94 | }
95 |
96 | private fun setEditListener() {
97 | widget_config_trans_holderColorEt.addTextChangedListener(getTextChangedListener(widget_config_trans_holderColor, null))
98 | widget_config_trans_timeColorEt.addTextChangedListener(getTextChangedListener(widget_config_trans_timeColor, widget_config_trans_timeTv))
99 | widget_config_trans_roomColorEt.addTextChangedListener(getTextChangedListener(widget_config_trans_roomColor, widget_config_trans_roomTv))
100 | widget_config_trans_courseColorEt.addTextChangedListener(getTextChangedListener(widget_config_trans_courseColor, widget_config_trans_courseTv))
101 | }
102 |
103 | private fun getTextChangedListener(colorView: View, textView: TextView?): TextWatcher {
104 | return object : TextWatcher {
105 | override fun afterTextChanged(s: Editable?) {
106 |
107 | }
108 |
109 | override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
110 |
111 | }
112 |
113 | override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
114 | if (s == null) return
115 | s.replace(Regex("[^(a-fA-F0-9#)]"), "")
116 | if (!s.isEmpty() && s.first() == '#' && (s.length == 7 || s.length == 9)) {
117 | try {
118 | val color = Color.parseColor(s.toString())
119 | colorView.setBackgroundColor(color)
120 | textView?.setTextColor(color)
121 | } catch (e: Exception) {
122 | e.printStackTrace()
123 | }
124 |
125 | }
126 | }
127 |
128 | }
129 | }
130 |
131 | private fun setPreviewColor(config: TransConfig) {
132 | try {
133 | widget_config_trans_timeColor.setBackgroundColor(Color.parseColor(config.timeTextColor))
134 | widget_config_trans_roomColor.setBackgroundColor(Color.parseColor(config.roomTextColor))
135 | widget_config_trans_courseColor.setBackgroundColor(Color.parseColor(config.courseTextColor))
136 | widget_config_trans_holderColor.setBackgroundColor(Color.parseColor(config.holderColor))
137 | } catch (e: Exception) {
138 | e.printStackTrace()
139 | }
140 | }
141 |
142 | private fun setColorEditText(config: TransConfig) {
143 | widget_config_trans_courseColorEt.setText(config.courseTextColor)
144 | widget_config_trans_roomColorEt.setText(config.roomTextColor)
145 | widget_config_trans_timeColorEt.setText(config.timeTextColor)
146 | widget_config_trans_holderColorEt.setText(config.holderColor)
147 | }
148 |
149 | private fun setTvColor(config: TransConfig) {
150 | try {
151 | widget_config_trans_courseTv.setTextColor(Color.parseColor(config.courseTextColor))
152 | widget_config_trans_roomTv.setTextColor(Color.parseColor(config.roomTextColor))
153 | widget_config_trans_timeTv.setTextColor(Color.parseColor(config.timeTextColor))
154 | } catch (e: Exception) {
155 | e.printStackTrace()
156 | }
157 | }
158 |
159 | private fun setTextSize(config: TransConfig) {
160 | widget_config_trans_courseTv.textSize = config.courseTextSize.toFloat()
161 | widget_config_trans_roomTv.textSize = config.roomTextSize.toFloat()
162 | widget_config_trans_timeTv.textSize = config.timeTextSize.toFloat()
163 | }
164 |
165 | private fun setSeekBar(config: TransConfig) {
166 |
167 | widget_config_trans_courseSb.max = 50
168 | widget_config_trans_courseSb.progress = config.courseTextSize
169 | widget_config_trans_roomSb.max = 50
170 | widget_config_trans_roomSb.progress = config.roomTextSize
171 | widget_config_trans_timeSb.max = 50
172 | widget_config_trans_timeSb.progress = config.timeTextSize
173 |
174 | widget_config_trans_courseSb.setOnSeekBarChangeListener(getSeekBarListener(widget_config_trans_courseTv))
175 | widget_config_trans_roomSb.setOnSeekBarChangeListener(getSeekBarListener(widget_config_trans_roomTv))
176 | widget_config_trans_timeSb.setOnSeekBarChangeListener(getSeekBarListener(widget_config_trans_timeTv))
177 | }
178 |
179 | private fun getSeekBarListener(tv: TextView): SeekBar.OnSeekBarChangeListener {
180 | return object : SeekBar.OnSeekBarChangeListener {
181 | override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
182 | runOnUiThread {
183 | tv.textSize = progress.toFloat()
184 | }
185 | }
186 |
187 | override fun onStartTrackingTouch(seekBar: SeekBar?) {
188 |
189 | }
190 |
191 | override fun onStopTrackingTouch(seekBar: SeekBar?) {
192 |
193 | }
194 |
195 | }
196 | }
197 |
198 | private fun setColorPicker(touchView: View, colorView: View, textView: TextView?, editText: EditText) {
199 | touchView.setOnClickListener {
200 | val dialog = ColorPickerDialog.newBuilder()
201 | .setShowAlphaSlider(true)
202 | .create()
203 |
204 | dialog.setColorPickerDialogListener(object : ColorPickerDialogListener {
205 | override fun onDialogDismissed(dialogId: Int) {
206 |
207 | }
208 |
209 | override fun onColorSelected(dialogId: Int, color: Int) {
210 | val stringColor = String.format("#%06X", (0xFFFFFFFF and color.toLong()))
211 | editText.setText(stringColor)
212 | textView?.setTextColor(color)
213 | colorView.setBackgroundColor(color)
214 | }
215 | })
216 | dialog.show(fragmentManager, "颜色选择")
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/AutoUpdateCourse.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util
2 |
3 | import android.app.IntentService
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.util.Log
7 | import com.google.gson.Gson
8 | import com.zia.widget.bean.Course
9 | import com.zia.widget.net.Service
10 | import com.zia.widget.widget.little.LittleTransWidget
11 | import com.zia.widget.widget.little.LittleWidget
12 | import com.zia.widget.widget.normal.NormalWidget
13 | import okhttp3.FormBody
14 | import okhttp3.Request
15 | import java.util.*
16 |
17 | /**
18 | * Created by zia on 2018/12/17.
19 | */
20 |
21 | /**
22 | * 自动更新课表
23 | */
24 | //同步方法,避免不必要的网络请求
25 | @Synchronized fun autoFreshCourse(context: Context) {
26 | //如果没开启该功能
27 | if (!context.defaultSharedPreferences.getBoolean(SP_IS_AUTO_UPDATE, false)){
28 | return
29 | }
30 | //获取应该更新的时间
31 | val updateTime = context.defaultSharedPreferences
32 | .getLong(SP_COURSE_UPDATE_TIME, Calendar.getInstance().timeInMillis - 1)
33 | //如果当前时间大于应该更新的时间,并且是晚上12点,那么更新
34 | val calendar = Calendar.getInstance()
35 | if (calendar.timeInMillis > updateTime && calendar.get(Calendar.HOUR_OF_DAY) == 0) {
36 | context.startService(Intent(context, UpdateCourseService::class.java))
37 | }
38 | }
39 |
40 | class UpdateCourseService : IntentService("UpdateCourseService") {
41 | override fun onHandleIntent(intent: Intent?) {
42 | val stuNum = defaultSharedPreferences.getString(SP_STUNUM, "")
43 | if (stuNum == null || stuNum.isEmpty()) return
44 |
45 | val courseRequest = Request.Builder()
46 | .url("https://wx.idsbllp.cn/api/kebiao")
47 | .post(FormBody.Builder().add("stuNum", stuNum).build())
48 | .build()
49 | try {
50 | val json = Service.okHttpClient.newCall(courseRequest).execute().body()?.string()
51 | val course: Course = Gson().fromJson(json, Course::class.java)
52 | if (course.data == null) {
53 | return
54 | }
55 | val calendar = Calendar.getInstance()
56 | calendar.add(Calendar.DATE, 7)
57 | defaultSharedPreferences.editor {
58 | putString(WIDGET_COURSE, json)
59 | putBoolean(SP_WIDGET_NEED_FRESH, true)
60 | putString(SP_STUNUM, stuNum)
61 | putLong(SP_COURSE_UPDATE_TIME, calendar.timeInMillis)
62 | }
63 | LittleTransWidget().refresh(this@UpdateCourseService)
64 | LittleWidget().refresh(this@UpdateCourseService)
65 | NormalWidget().fresh(this@UpdateCourseService, 0)
66 | Log.d(javaClass.simpleName, "autoUpdate:\n$json")
67 | } catch (e: Exception) {
68 | e.printStackTrace()
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/FileUtil.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util
2 |
3 | import android.content.Context
4 | import android.net.Uri
5 | import android.os.Build
6 | import android.support.v4.content.FileProvider
7 | import java.io.File
8 |
9 | /**
10 | * Created by zia on 2018/10/13.
11 | */
12 | object FileUtil {
13 | fun getFileUri(context: Context, file: File): Uri {
14 | return if (Build.VERSION.SDK_INT >= 24) {
15 | FileProvider.getUriForFile(context, "com.zia.widget.FileProvider", file)
16 | } else {
17 | Uri.fromFile(file)
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/ShortcutsUtil.java:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util;
2 |
3 | import android.content.Context;
4 | import android.content.pm.ShortcutInfo;
5 | import android.content.pm.ShortcutManager;
6 | import android.widget.Toast;
7 |
8 | import java.util.Collections;
9 | import java.util.List;
10 |
11 | /**
12 | * Created by zia on 2018/12/14.
13 | */
14 | public class ShortcutsUtil {
15 |
16 | /**
17 | * 删除shortcut
18 | *
19 | * @param context
20 | * @param id
21 | */
22 | public static void removeShortcut(Context context, String id) {
23 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
24 | try {
25 | ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
26 | shortcutManager.removeDynamicShortcuts(Collections.singletonList(id));
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | if (context != null) {
30 | Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
31 | }
32 | }
33 | }
34 | }
35 |
36 | public static void setShortcuts(Context context, List infos) {
37 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
38 | try {
39 | ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
40 | shortcutManager.setDynamicShortcuts(infos);
41 | } catch (Exception e) {
42 | e.printStackTrace();
43 | if (context != null) {
44 | Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
45 | }
46 | }
47 | }
48 | }
49 |
50 | /**
51 | * 添加shortcut
52 | *
53 | * @param context
54 | * @param shortcutInfo
55 | */
56 | public static void addShortcut(Context context, ShortcutInfo shortcutInfo) {
57 | try {
58 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
59 | ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
60 | shortcutManager.addDynamicShortcuts(Collections.singletonList(shortcutInfo));
61 | }
62 | } catch (Exception e) {
63 | e.printStackTrace();
64 | if (context != null) {
65 | Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
66 | }
67 | }
68 | }
69 |
70 | /**
71 | * 添加shortcut到指定position
72 | *
73 | * @param context
74 | * @param shortcutInfo
75 | * @param index
76 | */
77 | public static void addShortcut(Context context, ShortcutInfo shortcutInfo, int index) {
78 | try {
79 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
80 | ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
81 | List dynamicShortcuts = shortcutManager.getDynamicShortcuts();
82 | for (ShortcutInfo dynamicShortcut : dynamicShortcuts) {
83 | if (dynamicShortcut.getId().equals(shortcutInfo.getId())) {
84 | return;
85 | }
86 | }
87 | dynamicShortcuts.add(index, shortcutInfo);
88 | setShortcuts(context, dynamicShortcuts);
89 | }
90 | } catch (Exception e) {
91 | e.printStackTrace();
92 | if (context != null) {
93 | Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
94 | }
95 | }
96 |
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/TimeUtil.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util
2 |
3 | import java.util.Calendar
4 | import java.util.Date
5 |
6 | /**
7 | * Created by zia on 2018/10/12.
8 | */
9 | object TimeUtil {
10 |
11 | fun calcDayOffset(date1: Date, date2: Date): Int {
12 | val cal1 = Calendar.getInstance()
13 | cal1.time = date1
14 |
15 | val cal2 = Calendar.getInstance()
16 | cal2.time = date2
17 | val day1 = cal1.get(Calendar.DAY_OF_YEAR)
18 | val day2 = cal2.get(Calendar.DAY_OF_YEAR)
19 |
20 | val year1 = cal1.get(Calendar.YEAR)
21 | val year2 = cal2.get(Calendar.YEAR)
22 | if (year1 != year2) { //同一年
23 | var timeDistance = 0
24 | for (i in year1 until year2) {
25 | if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) { //闰年
26 | timeDistance += 366
27 | } else { //不是闰年
28 |
29 | timeDistance += 365
30 | }
31 | }
32 | return timeDistance + (day2 - day1)
33 | } else { //不同年
34 | return day2 - day1
35 | }
36 | }
37 |
38 | fun calcWeekOffset(startTime: Date, endTime: Date): Int {
39 | val cal = Calendar.getInstance()
40 | cal.time = startTime
41 | var dayOfWeek = cal.get(Calendar.DAY_OF_WEEK)
42 | dayOfWeek = dayOfWeek - 1
43 | if (dayOfWeek == 0) dayOfWeek = 7
44 |
45 | val dayOffset = calcDayOffset(startTime, endTime)
46 |
47 | var weekOffset = dayOffset / 7
48 | val a: Int
49 | if (dayOffset > 0) {
50 | a = if (dayOffset % 7 + dayOfWeek > 7) 1 else 0
51 | } else {
52 | a = if (dayOfWeek + dayOffset % 7 < 1) -1 else 0
53 | }
54 | weekOffset = weekOffset + a
55 | return weekOffset
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/Util.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util
2 |
3 | import android.app.PendingIntent
4 | import android.appwidget.AppWidgetProvider
5 | import android.content.Context
6 | import android.content.Intent
7 | import android.content.SharedPreferences
8 | import android.net.Uri
9 | import android.support.annotation.IdRes
10 | import android.util.Log
11 | import com.google.gson.Gson
12 | import com.zia.widget.bean.Course
13 | import java.text.SimpleDateFormat
14 | import java.util.*
15 | import kotlin.collections.ArrayList
16 |
17 | /**
18 | * Created by zia on 2018/10/10.
19 | * 精力憔悴,这些方法直接揉在一起了
20 | */
21 |
22 | fun getTodayCourse(context: Context): List? {
23 | return getCourseByCalendar(context, Calendar.getInstance())
24 | }
25 |
26 | fun getCourseByCalendar(context: Context, calendar: Calendar): ArrayList? {
27 | val json = context.defaultSharedPreferences.getString(WIDGET_COURSE, "")
28 | val course = Gson().fromJson(json, Course::class.java) ?: return null
29 | if (course.data == null) return null
30 |
31 | val needFresh = context.defaultSharedPreferences.getBoolean(SP_WIDGET_NEED_FRESH, true)
32 | //计算当前周数
33 | var beginTime = context.defaultSharedPreferences.getLong(beginTimeShareName, 0L)
34 | //需要刷新当前周
35 | if (needFresh) {
36 | beginTime = saveBeginTime(context, course.nowWeek)
37 | context.defaultSharedPreferences.editor {
38 | putBoolean(SP_WIDGET_NEED_FRESH, false)
39 | putString(WIDGET_COURSE, json)
40 | }
41 | }
42 | val week = TimeUtil.calcWeekOffset(Date(beginTime), calendar.time)
43 | Log.d("Widget", "week:$week")
44 | /*
45 | * 转换表,老外从周日开始计数,orz
46 | * 7 1 2 3 4 5 6 老外
47 | * 1 2 3 4 5 6 7 Calendar.DAY_OF_WEEK
48 | * 6 0 1 2 3 4 5 需要的结果(hash_day)
49 | * */
50 | val hash_day = (calendar.get(Calendar.DAY_OF_WEEK) + 5) % 7
51 |
52 | val list = ArrayList()
53 | course.data!!.forEach {
54 | if (it.hash_day == hash_day && it.week!!.contains(week)) {
55 | // LogUtils.d("Widget", it.toString())
56 | list.add(it)
57 | }
58 | }
59 | list.sortBy { it.hash_lesson }
60 | return list
61 | }
62 |
63 | private val beginTimeShareName = "zscy_widget_beginTime"
64 |
65 | private fun saveBeginTime(context: Context, nowWeek: Int): Long {
66 | val calendar = Calendar.getInstance()
67 | val targetWeek = calendar.get(Calendar.WEEK_OF_YEAR) - nowWeek
68 | calendar.set(Calendar.WEEK_OF_YEAR, targetWeek)
69 | val hash_day = (calendar.get(Calendar.DAY_OF_WEEK) + 5) % 7
70 | calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - hash_day)
71 | calendar.set(Calendar.HOUR_OF_DAY, 0)
72 | calendar.set(Calendar.MINUTE, 0)
73 | calendar.set(Calendar.MILLISECOND, 0)
74 | context.defaultSharedPreferences.editor {
75 | putLong(beginTimeShareName, calendar.time.time)
76 | }
77 | return calendar.time.time
78 | }
79 |
80 | fun getErrorCourseList(): ArrayList {
81 | val data = Course.DataBean()
82 | data.hash_lesson = 0
83 | data.course = "数据异常,请刷新"
84 | data.classroom = ""
85 | val list = ArrayList()
86 | list.add(data)
87 | return list
88 | }
89 |
90 | fun getNoCourse(): Course.DataBean {
91 | val data = Course.DataBean()
92 | data.hash_lesson = 0
93 | data.course = "无课"
94 | data.classroom = ""
95 | return data
96 | }
97 |
98 | fun saveHashLesson(context: Context, hash_lesson: Int, shareName: String) {
99 | context.defaultSharedPreferences.editor {
100 | putInt(shareName, hash_lesson)
101 | }
102 | }
103 |
104 | fun getHashLesson(context: Context, shareName: String): Int {
105 | return context.defaultSharedPreferences.getInt(shareName, 0)
106 | }
107 |
108 |
109 | private const val SP_DayOffset = "dayOffset"
110 | //天数偏移量,用于LittleWidget切换明天课程
111 | fun saveDayOffset(context: Context, offset: Int) {
112 | context.defaultSharedPreferences.editor {
113 | putInt(SP_DayOffset, offset)
114 | }
115 | }
116 | fun getDayOffset(context: Context): Int {
117 | return context.defaultSharedPreferences.getInt(SP_DayOffset, 0)
118 | }
119 |
120 |
121 | fun isNight(): Boolean {
122 | val calendar = Calendar.getInstance()
123 | return calendar.get(Calendar.HOUR_OF_DAY) > 19
124 | }
125 |
126 | /**
127 | * hash_lesson == 0 第1节 返回8:00
128 | */
129 | fun getStartCalendarByNum(hash_lesson: Int): Calendar {
130 | val calendar = Calendar.getInstance()
131 | when (hash_lesson) {
132 | 0 -> {
133 | calendar.set(Calendar.HOUR_OF_DAY, 8)
134 | calendar.set(Calendar.MINUTE, 0)
135 | }
136 | 1 -> {
137 | calendar.set(Calendar.HOUR_OF_DAY, 10)
138 | calendar.set(Calendar.MINUTE, 15)
139 | }
140 | 2 -> {
141 | calendar.set(Calendar.HOUR_OF_DAY, 14)
142 | calendar.set(Calendar.MINUTE, 0)
143 | }
144 | 3 -> {
145 | calendar.set(Calendar.HOUR_OF_DAY, 16)
146 | calendar.set(Calendar.MINUTE, 15)
147 | }
148 | 4 -> {
149 | calendar.set(Calendar.HOUR_OF_DAY, 19)
150 | calendar.set(Calendar.MINUTE, 0)
151 | }
152 | 5 -> {
153 | calendar.set(Calendar.HOUR_OF_DAY, 21)
154 | calendar.set(Calendar.MINUTE, 15)
155 | }
156 | 6 -> {
157 | calendar.set(Calendar.HOUR_OF_DAY, 19)
158 | calendar.set(Calendar.MINUTE, 0)
159 | }
160 | 7 -> {
161 | calendar.set(Calendar.HOUR_OF_DAY, 21)
162 | calendar.set(Calendar.MINUTE, 0)
163 | }
164 | }
165 | return calendar
166 | }
167 |
168 | fun getWeekDayChineseName(weekDay: Int): String {
169 | when (weekDay) {
170 | 1 -> return "星期天"
171 | 2 -> return "星期一"
172 | 3 -> return "星期二"
173 | 4 -> return "星期三"
174 | 5 -> return "星期四"
175 | 6 -> return "星期五"
176 | 7 -> return "星期六"
177 | else -> return "null"
178 | }
179 | }
180 |
181 | fun getClickPendingIntent(context: Context, @IdRes resId: Int, action: String, clazz: Class): PendingIntent {
182 | val intent = Intent()
183 | intent.setClass(context, clazz)
184 | intent.action = action
185 | intent.data = Uri.parse("id:$resId")
186 | return PendingIntent.getBroadcast(context, 0, intent, 0)
187 | }
188 |
189 | fun formatTime(calendar: Calendar): String {
190 | return SimpleDateFormat("HH:mm", Locale.SIMPLIFIED_CHINESE).format(calendar.time)
191 | }
192 |
193 | fun filterClassRoom(classRoom: String): String {
194 | if (classRoom.length > 8) {
195 | return classRoom.replace(Regex("[\\u4e00-\\u9fa5()()]"), "")
196 | } else {
197 | return classRoom
198 | }
199 | }
200 |
201 | //桌面小部件课表json数据
202 | const val WIDGET_COURSE = "widget_kb"
203 |
204 | const val SP_WIDGET_NEED_FRESH = "widget_need_fresh"
205 | const val SP_STUNUM = "student_number"
206 | const val SP_COURSE_UPDATE_TIME = "course_update_time"
207 | const val SP_IS_AUTO_UPDATE = "is_auto_update"
208 |
209 | val Context.defaultSharedPreferences get() = sharedPreferences("share_data")
210 |
211 | fun Context.sharedPreferences(name: String): SharedPreferences = getSharedPreferences(name, Context.MODE_PRIVATE)
212 | fun SharedPreferences.editor(editorBuilder: SharedPreferences.Editor.() -> Unit) = edit().apply(editorBuilder).apply()
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/Version.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util
2 |
3 | import android.content.Context
4 | import android.content.pm.PackageManager
5 |
6 | /**
7 | * Created by zia on 2018/10/13.
8 | */
9 | object Version {
10 | fun packageCode(context: Context): Int {
11 | val manager = context.packageManager
12 | var code = 0
13 | try {
14 | val info = manager.getPackageInfo(context.packageName, 0)
15 | code = info.versionCode
16 | } catch (e: PackageManager.NameNotFoundException) {
17 | e.printStackTrace()
18 | }
19 |
20 | return code
21 | }
22 |
23 | fun packageName(context: Context): String? {
24 | val manager = context.packageManager
25 | var name: String? = null
26 | try {
27 | val info = manager.getPackageInfo(context.packageName, 0)
28 | name = info.versionName
29 | } catch (e: PackageManager.NameNotFoundException) {
30 | e.printStackTrace()
31 | }
32 |
33 | return name
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/downlaodUtil/DownLoaderHelper.java:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util.downlaodUtil;
2 |
3 | import android.util.Log;
4 |
5 | import java.io.File;
6 |
7 | public class DownLoaderHelper {
8 | public static boolean mkDir(String root) {
9 | File file = new File(root);
10 | if (!file.exists() && !file.mkdirs()) {
11 | Log.d("DownLoaderHelper", "路径创建失败..");
12 | return false;
13 | }
14 | return true;
15 | }
16 |
17 | public static String convertSize(int fileSize) {
18 | float kb = fileSize / 1024;
19 | float mb = kb / 1024;
20 | float gb = mb / 1024;
21 | if (gb != 0) {
22 | return mb / 1024f + " Gb";
23 | } else if (mb != 0) {
24 | return kb / 1024f + " Mb";
25 | } else {
26 | return fileSize / 1024f + " Kb";
27 | }
28 | }
29 |
30 | /**
31 | * 检查路径并返回带有/结尾的路径
32 | *
33 | * @param source 路径
34 | * @return
35 | */
36 | static String optimizeRoot(String source) {
37 | source = source.trim();
38 | int length = source.length();
39 | if (source.charAt(length - 1) != File.separatorChar) {
40 | source = source + File.separatorChar;
41 | }
42 | return source;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/downlaodUtil/DownloadListener.java:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util.downlaodUtil;
2 |
3 | public interface DownloadListener {
4 | void getRatio(float ratio,float part,float total);
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/downlaodUtil/DownloadRunnable.java:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util.downlaodUtil;
2 |
3 | import android.util.Log;
4 |
5 | import java.io.BufferedInputStream;
6 | import java.io.BufferedOutputStream;
7 | import java.io.FileOutputStream;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.net.HttpURLConnection;
11 | import java.net.URL;
12 |
13 | public class DownloadRunnable implements Runnable {
14 |
15 | private String url, path, fileName;
16 | private int fileLength, currentFileLength = 0;
17 | private DownloadListener downloadListener;
18 | private int position;
19 |
20 | public DownloadRunnable(String url, String path, String fileName) {
21 | this(url, path, fileName, null);
22 | }
23 |
24 | public DownloadRunnable(String url, String path, String fileName, DownloadListener downloadListener) {
25 | this.url = url;
26 | this.path = DownLoaderHelper.optimizeRoot(path);
27 | this.fileName = fileName;
28 | this.downloadListener = downloadListener;
29 | }
30 |
31 | @Override
32 | public void run() {
33 | if (!DownLoaderHelper.mkDir(path)) {
34 | Log.e("DownloadRunnable", "创建文件路径失败..");
35 | return;
36 | }
37 |
38 | HttpURLConnection conn = null;
39 | InputStream inputStream = null;
40 |
41 | try {
42 |
43 | url = ReLocateUtil.getLocate(url);
44 | URL httpUrl = new URL(url);
45 |
46 | conn = (HttpURLConnection) httpUrl.openConnection();
47 | conn.setConnectTimeout(5000);
48 | conn.setDoInput(true);
49 | conn.connect();
50 |
51 | fileLength = conn.getContentLength();
52 | Log.d("DownloadRunnable", fileName + " Size: " + DownLoaderHelper.convertSize(fileLength));
53 |
54 | inputStream = conn.getInputStream();
55 | loadSteam(inputStream);
56 | } catch (IOException e) {
57 | e.printStackTrace();
58 | } finally {
59 | try {
60 | if (inputStream != null) {
61 | inputStream.close();
62 | }
63 | } catch (IOException e) {
64 | e.printStackTrace();
65 | }
66 | if (conn != null) {
67 | conn.disconnect();
68 | }
69 | // Thread.currentThread().interrupt();
70 | }
71 | }
72 |
73 | //写入本地
74 | private void loadSteam(InputStream inputStream) throws IOException {
75 | BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
76 | FileOutputStream fileOut = new FileOutputStream(path + fileName);
77 | BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOut);
78 | byte[] buf = new byte[4096];
79 | int lastRatio = 0;
80 | int length = bufferedInputStream.read(buf);
81 | while (length != -1) {
82 | bufferedOutputStream.write(buf, 0, length);
83 | length = bufferedInputStream.read(buf);
84 | currentFileLength = currentFileLength + length;
85 | float ratio = (float) currentFileLength / (float) fileLength * 100;
86 | if (downloadListener != null && lastRatio != (int) (ratio * 100)) {//变化超过0.01时回调
87 | downloadListener.getRatio(ratio, currentFileLength, fileLength);
88 | lastRatio = (int) (ratio * 100);
89 | }
90 | }
91 | bufferedOutputStream.close();
92 | bufferedInputStream.close();
93 | if (downloadListener != null) downloadListener.getRatio(100f, fileLength, fileLength);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/util/downlaodUtil/ReLocateUtil.java:
--------------------------------------------------------------------------------
1 | package com.zia.widget.util.downlaodUtil;
2 |
3 | import java.io.IOException;
4 | import java.net.HttpURLConnection;
5 | import java.net.URL;
6 |
7 | public class ReLocateUtil {
8 |
9 | public static String getLocate(String url) throws IOException {
10 | URL u = new URL(url);
11 | HttpURLConnection conn = (HttpURLConnection) u.openConnection();
12 | String location = conn.getHeaderField("Location");
13 | if (location == null) {
14 | return url;
15 | } else {
16 | System.out.println("reLocation:\n" + location);
17 | return location;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/widget/little/BaseLittleWidget.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.widget.little
2 |
3 | import android.appwidget.AppWidgetManager
4 | import android.appwidget.AppWidgetProvider
5 | import android.content.ComponentName
6 | import android.content.Context
7 | import android.content.Intent
8 | import android.support.annotation.IdRes
9 | import android.support.annotation.LayoutRes
10 | import android.widget.RemoteViews
11 | import android.widget.Toast
12 | import com.zia.widget.bean.Course
13 | import com.zia.widget.util.*
14 | import java.util.*
15 |
16 | /**
17 | * Created by zia on 2018/10/10.
18 | * 精简版桌面小控件
19 | */
20 | abstract class BaseLittleWidget : AppWidgetProvider() {
21 |
22 | private val shareName = "share_hash_lesson_trans"
23 |
24 | @LayoutRes
25 | protected abstract fun getLayoutResId(): Int
26 |
27 | protected abstract fun getShareName(): String
28 | @IdRes
29 | protected abstract fun getUpResId(): Int
30 |
31 | @IdRes
32 | protected abstract fun getDownResId(): Int
33 |
34 | @IdRes
35 | protected abstract fun getTitleResId(): Int
36 |
37 | @IdRes
38 | protected abstract fun getCourseNameResId(): Int
39 |
40 | @IdRes
41 | protected abstract fun getRoomResId(): Int
42 |
43 | @IdRes
44 | protected abstract fun getRefreshResId(): Int
45 |
46 | protected abstract fun getRemoteViews(context: Context, course: Course.DataBean?, timeTv: String = "课程安排"): RemoteViews
47 |
48 |
49 | override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
50 | super.onUpdate(context, appWidgetManager, appWidgetIds)
51 | autoFreshCourse(context)
52 | refresh(context)
53 | }
54 |
55 | override fun onReceive(context: Context, intent: Intent) {
56 | super.onReceive(context, intent)
57 |
58 | if (intent.action == "btn.text.com") {
59 | val data = intent.data
60 | var rId = -1
61 | if (data != null) {
62 | rId = data.schemeSpecificPart.toInt()
63 | }
64 | if (rId == getUpResId() && getUpResId() != 0) {
65 | goUp(context)
66 | } else if (rId == getDownResId() && getDownResId() != 0) {
67 | goDown(context)
68 | } else if (rId == getRefreshResId() && getRefreshResId() != 0) {
69 | refresh(context)
70 | Toast.makeText(context, "已刷新", Toast.LENGTH_SHORT).show()
71 | }
72 | }
73 | }
74 |
75 | private fun show(context: Context, course: Course.DataBean?, startTime: String = "课程安排") {
76 | val manager = AppWidgetManager.getInstance(context)
77 | val componentName = ComponentName(context, javaClass)
78 | manager.updateAppWidget(componentName, getRemoteViews(context, course, startTime))
79 | }
80 |
81 | //获取正常显示的下一节课
82 | fun refresh(context: Context) {
83 | saveDayOffset(context, 0)//重置天数偏移
84 | val list = getTodayCourse(context)
85 | ?: getErrorCourseList()
86 |
87 | var isFound = false
88 | list.forEach {
89 | val endCalendar = getStartCalendarByNum(it.hash_lesson)
90 | //如果今天还有下一节课,显示下一节
91 | if (Calendar.getInstance() < endCalendar) {
92 | show(context, it, formatTime(getStartCalendarByNum(it.hash_lesson)))
93 | return
94 | }
95 | isFound = true
96 | }
97 |
98 | if (isFound) {//今天有课,但是上完了
99 | //新策略:显示明天第一节
100 | showTomorrowCourse(context)
101 | } else {//今天没有课
102 | if (isNight()) {//如果在晚上,显示明天课程
103 | showTomorrowCourse(context)
104 | } else {
105 | //白天显示今天无课
106 | show(context, null)
107 | }
108 | }
109 | }
110 |
111 | private fun showTomorrowCourse(context: Context) {
112 | saveDayOffset(context, 1)//天数偏移加一,上下切换课程将会切换明天的
113 |
114 | val tomorrowCalendar = Calendar.getInstance()
115 | tomorrowCalendar.set(Calendar.DAY_OF_YEAR, tomorrowCalendar.get(Calendar.DAY_OF_YEAR) + 1)
116 | val tomorrowList = getCourseByCalendar(context, tomorrowCalendar)
117 | if (tomorrowList == null) {//数据出错
118 | show(context, getErrorCourseList().first(), "掌上重邮")
119 | } else {
120 | if (tomorrowList.isEmpty()) {//明日无课
121 | show(context, getNoCourse(), "明日课程")
122 | } else {//显示明天第一节课
123 | show(context, tomorrowList.first(), "明日:" + formatTime(getStartCalendarByNum(tomorrowList.first().hash_lesson)))
124 | }
125 | }
126 | }
127 |
128 | //获取当前课程的上一节课
129 | private fun goUp(context: Context) {
130 | val hash_lesson = getHashLesson(context, getShareName())
131 |
132 | val dayOffset = getDayOffset(context)
133 | val calendar = Calendar.getInstance()
134 | calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + dayOffset)
135 |
136 | //拿到当前课程的上一个课程
137 | val list = getCourseByCalendar(context, calendar)
138 | ?: getErrorCourseList()
139 |
140 | var course: Course.DataBean? = null
141 | list.forEach {
142 | if (hash_lesson > it.hash_lesson) {
143 | course = it
144 | }
145 | }
146 | if (course != null) {
147 | val beforeTitle = if (dayOffset == 1) "明日:" else ""
148 | show(context, course, beforeTitle + formatTime(getStartCalendarByNum(course!!.hash_lesson)))
149 | } else {
150 | Toast.makeText(context, "没有上一节课了~", Toast.LENGTH_SHORT).show()
151 | }
152 | }
153 |
154 | //获取当前课程的下一节课
155 | private fun goDown(context: Context) {
156 | val hash_lesson = getHashLesson(context, getShareName())
157 |
158 | val dayOffset = getDayOffset(context)
159 | val calendar = Calendar.getInstance()
160 | calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + dayOffset)
161 |
162 | //拿到最后一节
163 | val list = getCourseByCalendar(context, calendar)
164 | ?: getErrorCourseList()
165 | list.forEach {
166 | if (hash_lesson < it.hash_lesson) {
167 | val beforeTitle = if (dayOffset == 1) "明日:" else ""
168 | show(context, it, beforeTitle + formatTime(getStartCalendarByNum(it.hash_lesson)))
169 | return
170 | }
171 | }
172 | Toast.makeText(context, "没有下一节课了~", Toast.LENGTH_SHORT).show()
173 | }
174 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/widget/little/LittleTransWidget.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.widget.little
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import android.graphics.Color
6 | import android.util.TypedValue
7 | import android.view.View
8 | import android.widget.RemoteViews
9 | import com.zia.widget.R
10 | import com.zia.widget.bean.Course
11 | import com.zia.widget.page.trans.TransConfig
12 | import com.zia.widget.util.filterClassRoom
13 | import com.zia.widget.util.getWeekDayChineseName
14 | import java.util.*
15 |
16 | /**
17 | * Created by zia on 2018/10/10.
18 | * 小型部件,不透明
19 | */
20 | class LittleTransWidget : BaseLittleWidget() {
21 | override fun getLayoutResId(): Int {
22 | return R.layout.widget_little_trans
23 | }
24 |
25 | override fun getShareName(): String {
26 | return "widget_share_little_trans"
27 | }
28 |
29 | override fun getUpResId(): Int {
30 | return 0
31 | }
32 |
33 | override fun getDownResId(): Int {
34 | return 0
35 | }
36 |
37 | override fun getTitleResId(): Int {
38 | return R.id.widget_little_title_trans
39 | }
40 |
41 | override fun getCourseNameResId(): Int {
42 | return R.id.widget_little_trans_courseName
43 | }
44 |
45 | override fun getRoomResId(): Int {
46 | return R.id.widget_little_trans_room
47 | }
48 |
49 | override fun getRefreshResId(): Int {
50 | return 0
51 | }
52 |
53 | override fun getRemoteViews(context: Context, course: Course.DataBean?, timeTv: String): RemoteViews {
54 | val rv = RemoteViews(context.packageName, getLayoutResId())
55 | if (course == null) {
56 | rv.setTextViewText(getTitleResId(), getWeekDayChineseName(Calendar.getInstance().get(Calendar.DAY_OF_WEEK)))
57 | rv.setTextViewText(getCourseNameResId(), "今天没有课~")
58 | rv.setTextViewText(getRoomResId(), "")
59 | } else {
60 | rv.setTextViewText(getTitleResId(), timeTv)
61 | rv.setTextViewText(getCourseNameResId(), course.course)
62 | rv.setTextViewText(getRoomResId(), filterClassRoom(course.classroom!!))
63 | }
64 |
65 | //设置用户自定义定义配置
66 |
67 | try {//这个tryCatch防止用户输入的颜色有误,parseColor报错
68 | //标题(时间)
69 | val config = TransConfig.getUserConfig(context)
70 | rv.setTextColor(getTitleResId(), Color.parseColor(config.timeTextColor))
71 | rv.setTextViewTextSize(getTitleResId(), TypedValue.COMPLEX_UNIT_SP, config.timeTextSize.toFloat())
72 |
73 | //课程名
74 | rv.setTextColor(getCourseNameResId(), Color.parseColor(config.courseTextColor))
75 | rv.setTextViewTextSize(getCourseNameResId(), TypedValue.COMPLEX_UNIT_SP, config.courseTextSize.toFloat())
76 |
77 | //教室
78 | rv.setTextColor(getRoomResId(), Color.parseColor(config.roomTextColor))
79 | rv.setTextViewTextSize(getRoomResId(), TypedValue.COMPLEX_UNIT_SP, config.roomTextSize.toFloat())
80 |
81 | rv.setViewVisibility(R.id.widget_little_trans_holder, View.VISIBLE)
82 |
83 | //装饰,用ARGB_8888是为了设置透明度
84 | val holderBm = Bitmap.createBitmap(300, 1, Bitmap.Config.ARGB_8888)
85 | holderBm.eraseColor(Color.parseColor(config.holderColor))
86 | rv.setImageViewBitmap(R.id.widget_little_trans_holder, holderBm)
87 |
88 | //这个方法不能运行,上面的代码性能不行,来个人优化下?
89 | // rv.setInt(R.id.widget_little_trans_holder,"setBackgroundColor",Color.parseColor(config.holderColor))
90 |
91 | if (config.holderColor.length == 9) {
92 | if (config.holderColor.subSequence(1, 3) == "00") {
93 | rv.setViewVisibility(R.id.widget_little_trans_holder, View.GONE)
94 | }
95 | }
96 | } catch (e: Exception) {
97 | e.printStackTrace()
98 | }
99 |
100 | return rv
101 | }
102 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/widget/little/LittleWidget.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.widget.little
2 |
3 | import android.content.Context
4 | import android.widget.RemoteViews
5 | import com.zia.widget.R
6 | import com.zia.widget.bean.Course
7 | import com.zia.widget.util.filterClassRoom
8 | import com.zia.widget.util.getClickPendingIntent
9 | import com.zia.widget.util.getWeekDayChineseName
10 | import com.zia.widget.util.saveHashLesson
11 | import java.util.*
12 |
13 | /**
14 | * Created by zia on 2018/10/10.
15 | * 小型部件,不透明
16 | */
17 | class LittleWidget : BaseLittleWidget() {
18 | override fun getLayoutResId(): Int {
19 | return R.layout.widget_little
20 | }
21 |
22 | override fun getShareName(): String {
23 | return "widget_share_little"
24 | }
25 |
26 | override fun getUpResId(): Int {
27 | return R.id.widget_little_up
28 | }
29 |
30 | override fun getDownResId(): Int {
31 | return R.id.widget_little_down
32 | }
33 |
34 | override fun getTitleResId(): Int {
35 | return R.id.widget_little_title
36 | }
37 |
38 | override fun getCourseNameResId(): Int {
39 | return R.id.widget_little_courseName
40 | }
41 |
42 | override fun getRoomResId(): Int {
43 | return R.id.widget_little_room
44 | }
45 |
46 | override fun getRefreshResId(): Int {
47 | return R.id.widget_little_refresh
48 | }
49 |
50 | override fun getRemoteViews(context: Context, course: Course.DataBean?, timeTv: String): RemoteViews {
51 | val rv = RemoteViews(context.packageName, getLayoutResId())
52 | rv.setOnClickPendingIntent(getUpResId(), getClickPendingIntent(context, getUpResId(), "btn.text.com", javaClass))
53 | rv.setOnClickPendingIntent(getDownResId(), getClickPendingIntent(context, getDownResId(), "btn.text.com", javaClass))
54 | rv.setOnClickPendingIntent(getRefreshResId(), getClickPendingIntent(context, getRefreshResId(), "btn.text.com", javaClass))
55 | if (course == null) {
56 | rv.setTextViewText(getTitleResId(), getWeekDayChineseName(Calendar.getInstance().get(Calendar.DAY_OF_WEEK)))
57 | rv.setTextViewText(getCourseNameResId(), "今天没有课~")
58 | rv.setTextViewText(getRoomResId(), "")
59 | } else {
60 | //保存当前hash_lesson
61 | saveHashLesson(context, course.hash_lesson, getShareName())
62 | rv.setTextViewText(getTitleResId(), timeTv)
63 | rv.setTextViewText(getCourseNameResId(), course.course)
64 | rv.setTextViewText(getRoomResId(), filterClassRoom(course.classroom!!))
65 | }
66 | return rv
67 | }
68 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zia/widget/widget/normal/NormalWidget.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget.widget.normal
2 |
3 | import android.appwidget.AppWidgetManager
4 | import android.appwidget.AppWidgetProvider
5 | import android.content.ComponentName
6 | import android.content.Context
7 | import android.content.Intent
8 | import android.support.annotation.IdRes
9 | import android.view.View
10 | import android.widget.RemoteViews
11 | import android.widget.Toast
12 | import com.zia.widget.R
13 | import com.zia.widget.util.*
14 | import java.util.*
15 | import kotlin.math.abs
16 |
17 | /**
18 | * Created by zia on 2018/10/10.
19 | * 大课表
20 | * 简单原理:因为一天最多6节课,直接写了6个布局,隐藏后面没有用到的布局就完了
21 | */
22 | class NormalWidget : AppWidgetProvider() {
23 |
24 | private val shareName = "zscy_widget_normal"
25 |
26 | override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
27 | super.onUpdate(context, appWidgetManager, appWidgetIds)
28 | context.defaultSharedPreferences.editor {
29 | putInt(shareName, 0)
30 | }
31 | autoFreshCourse(context)
32 | fresh(context, 0)
33 | }
34 |
35 | override fun onReceive(context: Context, intent: Intent) {
36 | super.onReceive(context, intent)
37 | if (intent.action == "btn.text.com") {
38 | val data = intent.data
39 | var rId = -1
40 | if (data != null) {
41 | rId = data.schemeSpecificPart.toInt()
42 | }
43 |
44 | val offsetTime = context.defaultSharedPreferences.getInt(shareName, 0)
45 |
46 | if (abs(offsetTime) == 3) {
47 | Toast.makeText(context, "提示:点击星期返回今日", Toast.LENGTH_SHORT).show()
48 | }
49 |
50 | when (rId) {
51 | R.id.widget_normal_back -> {
52 | context.defaultSharedPreferences.editor {
53 | putInt(shareName, offsetTime - 1)
54 | }
55 | fresh(context, offsetTime - 1)
56 | }
57 | R.id.widget_normal_front -> {
58 | context.defaultSharedPreferences.editor {
59 | putInt(shareName, offsetTime + 1)
60 | }
61 | fresh(context, offsetTime + 1)
62 | }
63 | R.id.widget_normal_title -> {
64 | context.defaultSharedPreferences.editor {
65 | putInt(shareName, 0)
66 | }
67 | fresh(context, 0)
68 | // Toast.makeText(context, "已刷新", Toast.LENGTH_SHORT).show()
69 | }
70 | }
71 | }
72 | }
73 |
74 | /**
75 | * 刷新,传入offsetTime作为今天的偏移量
76 | */
77 | fun fresh(context: Context, offsetTime: Int) {
78 | //生成calendar
79 | val calendar = Calendar.getInstance()
80 | val nowHour = calendar.get(Calendar.HOUR_OF_DAY)
81 | calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + offsetTime)
82 |
83 | //获取数据
84 | val list = getCourseByCalendar(context, calendar)
85 | ?: getErrorCourseList()
86 | if (list.isEmpty()){
87 | list.add(getNoCourse())
88 | }
89 |
90 | //如果课已经上完了,而且过了晚上7点,显示明天的课程
91 | if (nowHour > 19) {
92 | var i = 0
93 | list.forEach {
94 | val hour = getStartCalendarByNum(it.hash_lesson).get(Calendar.HOUR_OF_DAY)
95 | if (nowHour > hour) {
96 | i++
97 | } else {
98 | return@forEach
99 | }
100 | }
101 | if (i == list.size) {
102 | calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 1)
103 | val tomorrowList = getCourseByCalendar(context, calendar)
104 | ?: getErrorCourseList()
105 | list.clear()
106 | list.addAll(tomorrowList)
107 | }
108 | }
109 |
110 | val rv = RemoteViews(context.packageName, R.layout.widget_normal)
111 |
112 | //显示星期几
113 | rv.setTextViewText(R.id.widget_normal_title, getWeekDayChineseName(calendar.get(Calendar.DAY_OF_WEEK)))
114 |
115 | //显示课程
116 | var index = 1
117 | list.forEach { course ->
118 | rv.setViewVisibility(getLayoutId(index), View.VISIBLE)
119 | rv.setTextViewText(getTimeId(index), formatTime(getStartCalendarByNum(course.hash_lesson)))
120 | rv.setTextViewText(getCourseId(index), course.course)
121 | rv.setTextViewText(getRoomId(index), filterClassRoom(course.classroom!!))
122 | index++
123 | }
124 | //隐藏后面的item
125 | for (i in index..6) {
126 | rv.setViewVisibility(getLayoutId(i), View.GONE)
127 | }
128 |
129 | //设置前后按钮操作
130 | addClickPendingIntent(rv, context)
131 |
132 | show(rv, context)
133 | }
134 |
135 | private fun addClickPendingIntent(rv: RemoteViews, context: Context) {
136 | rv.setOnClickPendingIntent(R.id.widget_normal_title,
137 | getClickPendingIntent(context, R.id.widget_normal_title, "btn.text.com", javaClass))
138 | rv.setOnClickPendingIntent(R.id.widget_normal_front,
139 | getClickPendingIntent(context, R.id.widget_normal_front, "btn.text.com", javaClass))
140 | rv.setOnClickPendingIntent(R.id.widget_normal_back,
141 | getClickPendingIntent(context, R.id.widget_normal_back, "btn.text.com", javaClass))
142 | }
143 |
144 | private fun show(remoteViews: RemoteViews, context: Context) {
145 | val manager = AppWidgetManager.getInstance(context)
146 | val componentName = ComponentName(context, javaClass)
147 | manager.updateAppWidget(componentName, remoteViews)
148 | }
149 |
150 | @IdRes
151 | private fun getLayoutId(num: Int): Int {
152 | when (num) {
153 | 1 -> {
154 | return R.id.widget_normal_layout1
155 | }
156 | 2 -> {
157 | return R.id.widget_normal_layout2
158 | }
159 | 3 -> {
160 | return R.id.widget_normal_layout3
161 | }
162 | 4 -> {
163 | return R.id.widget_normal_layout4
164 | }
165 | 5 -> {
166 | return R.id.widget_normal_layout5
167 | }
168 | 6 -> {
169 | return R.id.widget_normal_layout6
170 | }
171 | else -> {
172 | return R.id.widget_normal_layout1
173 | }
174 | }
175 | }
176 |
177 | @IdRes
178 | private fun getTimeId(num: Int): Int {
179 | when (num) {
180 | 1 -> {
181 | return R.id.widget_normal_time1
182 | }
183 | 2 -> {
184 | return R.id.widget_normal_time2
185 | }
186 | 3 -> {
187 | return R.id.widget_normal_time3
188 | }
189 | 4 -> {
190 | return R.id.widget_normal_time4
191 | }
192 | 5 -> {
193 | return R.id.widget_normal_time5
194 | }
195 | 6 -> {
196 | return R.id.widget_normal_time6
197 | }
198 | else -> {
199 | return R.id.widget_normal_time1
200 | }
201 | }
202 | }
203 |
204 | @IdRes
205 | private fun getCourseId(num: Int): Int {
206 | when (num) {
207 | 1 -> {
208 | return R.id.widget_normal_course1
209 | }
210 | 2 -> {
211 | return R.id.widget_normal_course2
212 | }
213 | 3 -> {
214 | return R.id.widget_normal_course3
215 | }
216 | 4 -> {
217 | return R.id.widget_normal_course4
218 | }
219 | 5 -> {
220 | return R.id.widget_normal_course5
221 | }
222 | 6 -> {
223 | return R.id.widget_normal_course6
224 | }
225 | else -> {
226 | return R.id.widget_normal_course1
227 | }
228 | }
229 | }
230 |
231 | @IdRes
232 | private fun getRoomId(num: Int): Int {
233 | when (num) {
234 | 1 -> {
235 | return R.id.widget_normal_room1
236 | }
237 | 2 -> {
238 | return R.id.widget_normal_room2
239 | }
240 | 3 -> {
241 | return R.id.widget_normal_room3
242 | }
243 | 4 -> {
244 | return R.id.widget_normal_room4
245 | }
246 | 5 -> {
247 | return R.id.widget_normal_room5
248 | }
249 | 6 -> {
250 | return R.id.widget_normal_room6
251 | }
252 | else -> {
253 | return R.id.widget_normal_room1
254 | }
255 | }
256 | }
257 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable-v24/widget_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_bg_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable-v24/widget_down.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_fresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable-v24/widget_fresh.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable-v24/widget_front.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_little_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable-v24/widget_little_example.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_little_trans_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable-v24/widget_little_trans_example.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_normal_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable-v24/widget_normal_example.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/widget_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable-v24/widget_up.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable/widget_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_bg_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | -
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_bg_savebt.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 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_bg_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable/widget_down.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_fresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable/widget_fresh.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable/widget_front.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_little_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable/widget_little_example.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_little_trans_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable/widget_little_trans_example.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_normal_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable/widget_normal_example.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/drawable/widget_up.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_activity_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
16 |
22 |
23 |
29 |
30 |
34 |
35 |
43 |
44 |
48 |
49 |
55 |
56 |
57 |
62 |
63 |
71 |
72 |
76 |
77 |
83 |
84 |
85 |
90 |
91 |
99 |
100 |
104 |
105 |
111 |
112 |
113 |
114 |
115 |
121 |
122 |
134 |
135 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_activity_little_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
18 |
22 |
23 |
29 |
30 |
31 |
40 |
41 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
85 |
86 |
94 |
95 |
102 |
103 |
104 |
112 |
113 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_activity_normal_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_activity_trans_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
16 |
22 |
23 |
28 |
29 |
34 |
35 |
39 |
40 |
44 |
45 |
54 |
55 |
60 |
61 |
62 |
71 |
72 |
82 |
83 |
84 |
89 |
90 |
94 |
95 |
104 |
105 |
110 |
111 |
112 |
121 |
122 |
132 |
133 |
134 |
139 |
140 |
144 |
145 |
154 |
155 |
160 |
161 |
162 |
171 |
172 |
182 |
183 |
184 |
188 |
189 |
198 |
199 |
204 |
205 |
206 |
215 |
216 |
226 |
227 |
228 |
229 |
230 |
237 |
238 |
243 |
244 |
249 |
250 |
255 |
256 |
262 |
263 |
273 |
274 |
278 |
279 |
280 |
284 |
285 |
290 |
291 |
297 |
298 |
308 |
309 |
313 |
314 |
315 |
319 |
320 |
325 |
326 |
332 |
333 |
343 |
344 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
363 |
364 |
370 |
371 |
375 |
376 |
381 |
382 |
390 |
391 |
398 |
399 |
400 |
401 |
409 |
410 |
411 |
416 |
417 |
422 |
423 |
431 |
432 |
440 |
441 |
442 |
447 |
448 |
453 |
454 |
462 |
463 |
471 |
472 |
473 |
474 |
475 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_little.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
13 |
20 |
21 |
31 |
32 |
33 |
37 |
38 |
43 |
44 |
57 |
58 |
65 |
66 |
67 |
68 |
74 |
75 |
87 |
88 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_little_trans.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
16 |
20 |
21 |
29 |
30 |
35 |
36 |
37 |
38 |
39 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
22 |
23 |
24 |
32 |
33 |
41 |
42 |
43 |
44 |
52 |
53 |
61 |
62 |
73 |
74 |
86 |
87 |
88 |
96 |
97 |
105 |
106 |
117 |
118 |
130 |
131 |
132 |
140 |
141 |
149 |
150 |
161 |
162 |
174 |
175 |
176 |
184 |
185 |
193 |
194 |
205 |
206 |
218 |
219 |
220 |
228 |
229 |
237 |
238 |
249 |
250 |
262 |
263 |
264 |
272 |
273 |
281 |
282 |
293 |
294 |
306 |
307 |
308 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #44a5f7
4 | #44a5f7
5 | #58B1FC
6 | #e3262626
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 重邮课表
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/file_path.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/widget_little.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/widget_little_trans.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/widget_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/test/java/com/zia/widget/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.zia.widget
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext.kotlin_version = '1.2.71'
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 |
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.2.1'
12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | google()
19 | jcenter()
20 | mavenCentral()
21 | maven { url 'https://jitpack.io' }
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/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 | org.gradle.daemon=true
11 | org.gradle.parallel=true
12 | # When configured, Gradle will run in incubating parallel mode.
13 | # This option should only be used with decoupled projects. More details, visit
14 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
15 | # org.gradle.parallel=true
16 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file must *NOT* be checked into Version Control Systems,
2 | # as it contains information specific to your local configuration.
3 | #
4 | # Location of the SDK. This is only used by Gradle.
5 | # For customization when using a Version Control System, please read the
6 | # header note.
7 | #Sat Oct 13 22:47:28 CST 2018
8 | ndk.dir=/Users/jiangzilai/Library/Android/sdk/ndk-bundle
9 | sdk.dir=/Users/jiangzilai/Library/Android/sdk
10 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # 重邮课表桌面小应用
2 |
3 | 该应用是掌上重邮应用的子部件,占用资源更少,拥有更快的更新维护速度。
4 |
5 | [apk下载](http://qiniu.zzzia.net/widget-v1.4.apk)
6 |
7 |
8 |
--------------------------------------------------------------------------------
/screenshots/example1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/widget/541037a26cc607ec4a3e30ebc123a9a7ceba2338/screenshots/example1.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/widget.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------